| 
									
										
										
										
											2018-01-07 18:38:11 +00:00
										 |  |  | // Copyright 2018 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | package scwallet | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"bytes" | 
					
						
							|  |  |  | 	"encoding/binary" | 
					
						
							| 
									
										
										
										
											2019-04-04 23:41:52 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2018-01-07 18:38:11 +00:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-20 10:37:45 +03:00
										 |  |  | // commandAPDU represents an application data unit sent to a smartcard. | 
					
						
							|  |  |  | type commandAPDU struct { | 
					
						
							| 
									
										
										
										
											2018-01-07 18:38:11 +00:00
										 |  |  | 	Cla, Ins, P1, P2 uint8  // Class, Instruction, Parameter 1, Parameter 2 | 
					
						
							|  |  |  | 	Data             []byte // Command data | 
					
						
							|  |  |  | 	Le               uint8  // Command data length | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // serialize serializes a command APDU. | 
					
						
							| 
									
										
										
										
											2018-04-20 10:37:45 +03:00
										 |  |  | func (ca commandAPDU) serialize() ([]byte, error) { | 
					
						
							| 
									
										
										
										
											2018-01-07 18:38:11 +00:00
										 |  |  | 	buf := new(bytes.Buffer) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if err := binary.Write(buf, binary.BigEndian, ca.Cla); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := binary.Write(buf, binary.BigEndian, ca.Ins); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := binary.Write(buf, binary.BigEndian, ca.P1); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := binary.Write(buf, binary.BigEndian, ca.P2); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if len(ca.Data) > 0 { | 
					
						
							|  |  |  | 		if err := binary.Write(buf, binary.BigEndian, uint8(len(ca.Data))); err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if err := binary.Write(buf, binary.BigEndian, ca.Data); err != nil { | 
					
						
							|  |  |  | 			return nil, err | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := binary.Write(buf, binary.BigEndian, ca.Le); err != nil { | 
					
						
							|  |  |  | 		return nil, err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return buf.Bytes(), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-20 10:37:45 +03:00
										 |  |  | // responseAPDU represents an application data unit received from a smart card. | 
					
						
							|  |  |  | type responseAPDU struct { | 
					
						
							| 
									
										
										
										
											2018-01-07 18:38:11 +00:00
										 |  |  | 	Data     []byte // response data | 
					
						
							|  |  |  | 	Sw1, Sw2 uint8  // status words 1 and 2 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-02-22 13:27:41 +00:00
										 |  |  | // deserialize deserializes a response APDU. | 
					
						
							| 
									
										
										
										
											2018-04-20 10:37:45 +03:00
										 |  |  | func (ra *responseAPDU) deserialize(data []byte) error { | 
					
						
							| 
									
										
										
										
											2019-04-04 23:41:52 +02:00
										 |  |  | 	if len(data) < 2 { | 
					
						
							|  |  |  | 		return fmt.Errorf("can not deserialize data: payload too short (%d < 2)", len(data)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-01-07 18:38:11 +00:00
										 |  |  | 	ra.Data = make([]byte, len(data)-2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	buf := bytes.NewReader(data) | 
					
						
							|  |  |  | 	if err := binary.Read(buf, binary.BigEndian, &ra.Data); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := binary.Read(buf, binary.BigEndian, &ra.Sw1); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if err := binary.Read(buf, binary.BigEndian, &ra.Sw2); err != nil { | 
					
						
							|  |  |  | 		return err | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	return nil | 
					
						
							|  |  |  | } |