Add commands
This commit is contained in:
parent
f66dd01301
commit
76fb3dd4fd
|
@ -9,14 +9,17 @@ Currently the following commands are implemented:
|
||||||
* Reset
|
* Reset
|
||||||
* GenerateAsymmetricKey
|
* GenerateAsymmetricKey
|
||||||
* SignDataEddsa
|
* SignDataEddsa
|
||||||
* SignDataPkcs1
|
|
||||||
* PutAsymmetricKey
|
* PutAsymmetricKey
|
||||||
* GetPubKey
|
* GetPubKey
|
||||||
* DeriveEcdh
|
* DeriveEcdh
|
||||||
* Echo
|
* Echo
|
||||||
* ChangeAuthenticationKey
|
* ChangeAuthenticationKey
|
||||||
|
* PutAuthenticationKey
|
||||||
|
* GetOpaque
|
||||||
|
* PutOpaque
|
||||||
|
* SignDataPkcs1
|
||||||
|
* SignAttestationCertificate
|
||||||
* Authentication & Session related commands
|
* Authentication & Session related commands
|
||||||
* GetPseudoRandom
|
|
||||||
|
|
||||||
Implementing new commands is really easy. Please consult `commands/constructors.go` and `commands/response.go` for reference.
|
Implementing new commands is really easy. Please consult `commands/constructors.go` and `commands/response.go` for reference.
|
||||||
|
|
||||||
|
|
|
@ -94,20 +94,6 @@ func CreateSignDataEcdsaCommand(keyID uint16, data []byte) (*CommandMessage, err
|
||||||
return command, nil
|
return command, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateSignDataPkcs1Command(keyID uint16, data []byte) (*CommandMessage, error) {
|
|
||||||
command := &CommandMessage{
|
|
||||||
CommandType: CommandTypeSignDataPkcs1,
|
|
||||||
}
|
|
||||||
|
|
||||||
payload := bytes.NewBuffer([]byte{})
|
|
||||||
binary.Write(payload, binary.BigEndian, keyID)
|
|
||||||
payload.Write(data)
|
|
||||||
|
|
||||||
command.Data = payload.Bytes()
|
|
||||||
|
|
||||||
return command, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreatePutAsymmetricKeyCommand(keyID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, keyPart1 []byte, keyPart2 []byte) (*CommandMessage, error) {
|
func CreatePutAsymmetricKeyCommand(keyID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, keyPart1 []byte, keyPart2 []byte) (*CommandMessage, error) {
|
||||||
if len(label) > LabelLength {
|
if len(label) > LabelLength {
|
||||||
return nil, errors.New("label is too long")
|
return nil, errors.New("label is too long")
|
||||||
|
@ -151,6 +137,26 @@ func NewIDOption(id uint16) ListCommandOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewDomainOption(domain uint16) ListCommandOption {
|
||||||
|
return func(w io.Writer) {
|
||||||
|
binary.Write(w, binary.BigEndian, ListObjectParamDomains)
|
||||||
|
binary.Write(w, binary.BigEndian, domain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLabelOption(label []byte) (ListCommandOption, error) {
|
||||||
|
if len(label) > LabelLength {
|
||||||
|
return nil, errors.New("label is too long")
|
||||||
|
}
|
||||||
|
if len(label) < LabelLength {
|
||||||
|
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
|
||||||
|
}
|
||||||
|
return func(w io.Writer) {
|
||||||
|
binary.Write(w, binary.BigEndian, ListObjectParamLabel)
|
||||||
|
binary.Write(w, binary.BigEndian, label)
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func CreateListObjectsCommand(options ...ListCommandOption) (*CommandMessage, error) {
|
func CreateListObjectsCommand(options ...ListCommandOption) (*CommandMessage, error) {
|
||||||
command := &CommandMessage{
|
command := &CommandMessage{
|
||||||
CommandType: CommandTypeListObjects,
|
CommandType: CommandTypeListObjects,
|
||||||
|
@ -235,6 +241,33 @@ func CreateDeriveEcdhCommand(objID uint16, pubkey []byte) (*CommandMessage, erro
|
||||||
return command, nil
|
return command, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreatePutAuthenticationKeyCommand(objID uint16, label []byte, domains uint16, capabilities uint64, delegated uint64, password string) (*CommandMessage, error) {
|
||||||
|
if len(label) > LabelLength {
|
||||||
|
return nil, errors.New("label is too long")
|
||||||
|
}
|
||||||
|
if len(label) < LabelLength {
|
||||||
|
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
|
||||||
|
}
|
||||||
|
|
||||||
|
command := &CommandMessage{
|
||||||
|
CommandType: CommandTypePutAuthKey,
|
||||||
|
}
|
||||||
|
|
||||||
|
authKey := authkey.NewFromPassword(password)
|
||||||
|
payload := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(payload, binary.BigEndian, objID)
|
||||||
|
payload.Write(label)
|
||||||
|
binary.Write(payload, binary.BigEndian, domains)
|
||||||
|
binary.Write(payload, binary.BigEndian, capabilities)
|
||||||
|
binary.Write(payload, binary.BigEndian, AlgorithmYubicoAESAuthentication)
|
||||||
|
binary.Write(payload, binary.BigEndian, delegated)
|
||||||
|
payload.Write(authKey.GetEncKey())
|
||||||
|
payload.Write(authKey.GetMacKey())
|
||||||
|
command.Data = payload.Bytes()
|
||||||
|
|
||||||
|
return command, nil
|
||||||
|
}
|
||||||
|
|
||||||
func CreateChangeAuthenticationKeyCommand(objID uint16, newPassword string) (*CommandMessage, error) {
|
func CreateChangeAuthenticationKeyCommand(objID uint16, newPassword string) (*CommandMessage, error) {
|
||||||
command := &CommandMessage{
|
command := &CommandMessage{
|
||||||
CommandType: CommandTypeChangeAuthenticationKey,
|
CommandType: CommandTypeChangeAuthenticationKey,
|
||||||
|
@ -251,90 +284,65 @@ func CreateChangeAuthenticationKeyCommand(objID uint16, newPassword string) (*Co
|
||||||
return command, nil
|
return command, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateGetPseudoRandomCommand(numBytes uint16) *CommandMessage {
|
func CreatePutOpaqueCommand(objID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, data []byte) (*CommandMessage, error) {
|
||||||
command := &CommandMessage{
|
|
||||||
CommandType: CommandTypeGetPseudoRandom,
|
|
||||||
}
|
|
||||||
|
|
||||||
payload := bytes.NewBuffer([]byte{})
|
|
||||||
binary.Write(payload, binary.BigEndian, numBytes)
|
|
||||||
command.Data = payload.Bytes()
|
|
||||||
|
|
||||||
return command
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreatePutWrapkeyCommand(objID uint16, label []byte, domains uint16, capabilities uint64, algorithm Algorithm, delegated uint64, wrapkey []byte) (*CommandMessage, error) {
|
|
||||||
if len(label) > LabelLength {
|
if len(label) > LabelLength {
|
||||||
return nil, errors.New("label is too long")
|
return nil, errors.New("label is too long")
|
||||||
}
|
}
|
||||||
if len(label) < LabelLength {
|
if len(label) < LabelLength {
|
||||||
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
|
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
|
||||||
}
|
}
|
||||||
switch algorithm {
|
|
||||||
case AlgorithmAES128CCMWrap:
|
|
||||||
if keyLen := len(wrapkey); keyLen != 16 {
|
|
||||||
return nil, errors.New("wrapkey is wrong length")
|
|
||||||
}
|
|
||||||
case AlgorithmAES192CCMWrap:
|
|
||||||
if keyLen := len(wrapkey); keyLen != 24 {
|
|
||||||
return nil, errors.New("wrapkey is wrong length")
|
|
||||||
}
|
|
||||||
case AlgorithmAES256CCMWrap:
|
|
||||||
if keyLen := len(wrapkey); keyLen != 32 {
|
|
||||||
return nil, errors.New("wrapkey is wrong length")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, errors.New("invalid algorithm")
|
|
||||||
}
|
|
||||||
|
|
||||||
command := &CommandMessage{
|
command := &CommandMessage{
|
||||||
CommandType: CommandTypePutWrapKey,
|
CommandType: CommandTypePutOpaque,
|
||||||
}
|
}
|
||||||
|
|
||||||
payload := bytes.NewBuffer([]byte{})
|
payload := bytes.NewBuffer(nil)
|
||||||
binary.Write(payload, binary.BigEndian, objID)
|
binary.Write(payload, binary.BigEndian, objID)
|
||||||
payload.Write(label)
|
payload.Write(label)
|
||||||
binary.Write(payload, binary.BigEndian, domains)
|
binary.Write(payload, binary.BigEndian, domains)
|
||||||
binary.Write(payload, binary.BigEndian, capabilities)
|
binary.Write(payload, binary.BigEndian, capabilities)
|
||||||
binary.Write(payload, binary.BigEndian, algorithm)
|
binary.Write(payload, binary.BigEndian, algorithm)
|
||||||
binary.Write(payload, binary.BigEndian, delegated)
|
payload.Write(data)
|
||||||
payload.Write(wrapkey)
|
|
||||||
|
|
||||||
command.Data = payload.Bytes()
|
command.Data = payload.Bytes()
|
||||||
|
|
||||||
return command, nil
|
return command, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreatePutAuthkeyCommand(objID uint16, label []byte, domains uint16, capabilities, delegated uint64, encKey, macKey []byte) (*CommandMessage, error) {
|
func CreateGetOpaqueCommand(objID uint16) (*CommandMessage, error) {
|
||||||
if len(label) > LabelLength {
|
command := &CommandMessage{
|
||||||
return nil, errors.New("label is too long")
|
CommandType: CommandTypeGetOpaque,
|
||||||
}
|
|
||||||
if len(label) < LabelLength {
|
|
||||||
label = append(label, bytes.Repeat([]byte{0x00}, LabelLength-len(label))...)
|
|
||||||
}
|
|
||||||
algorithm := AlgorithmYubicoAESAuthentication
|
|
||||||
// TODO: support P256 Authentication when it is released
|
|
||||||
// https://github.com/Yubico/yubihsm-shell/blob/1c8e254603e72f3f39cf1c3910996dbfcdba2b12/lib/yubihsm.c#L3110
|
|
||||||
if len(encKey) != 16 {
|
|
||||||
return nil, errors.New("invalid encryption key length")
|
|
||||||
}
|
|
||||||
if len(macKey) != 16 {
|
|
||||||
return nil, errors.New("invalid mac key length")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
payload := bytes.NewBuffer(nil)
|
||||||
|
binary.Write(payload, binary.BigEndian, objID)
|
||||||
|
command.Data = payload.Bytes()
|
||||||
|
|
||||||
|
return command, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSignDataPkcs1Command(objID uint16, data []byte) (*CommandMessage, error) {
|
||||||
command := &CommandMessage{
|
command := &CommandMessage{
|
||||||
CommandType: CommandTypePutAuthKey,
|
CommandType: CommandTypeSignDataPkcs1,
|
||||||
}
|
}
|
||||||
|
|
||||||
payload := bytes.NewBuffer([]byte{})
|
payload := bytes.NewBuffer([]byte{})
|
||||||
binary.Write(payload, binary.BigEndian, objID)
|
binary.Write(payload, binary.BigEndian, objID)
|
||||||
payload.Write(label)
|
payload.Write(data)
|
||||||
binary.Write(payload, binary.BigEndian, domains)
|
|
||||||
binary.Write(payload, binary.BigEndian, capabilities)
|
command.Data = payload.Bytes()
|
||||||
binary.Write(payload, binary.BigEndian, algorithm)
|
|
||||||
binary.Write(payload, binary.BigEndian, delegated)
|
return command, nil
|
||||||
payload.Write(encKey)
|
}
|
||||||
payload.Write(macKey)
|
|
||||||
|
func CreateSignAttestationCertCommand(keyObjID, attestationObjID uint16) (*CommandMessage, error) {
|
||||||
|
command := &CommandMessage{
|
||||||
|
CommandType: CommandTypeAttestAsymmetric,
|
||||||
|
}
|
||||||
|
|
||||||
|
payload := bytes.NewBuffer([]byte{})
|
||||||
|
binary.Write(payload, binary.BigEndian, keyObjID)
|
||||||
|
binary.Write(payload, binary.BigEndian, attestationObjID)
|
||||||
|
|
||||||
command.Data = payload.Bytes()
|
command.Data = payload.Bytes()
|
||||||
|
|
||||||
|
|
|
@ -62,10 +62,6 @@ type (
|
||||||
Signature []byte
|
Signature []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
SignDataPkcs1Response struct {
|
|
||||||
Signature []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
SignDataEcdsaResponse struct {
|
SignDataEcdsaResponse struct {
|
||||||
Signature []byte
|
Signature []byte
|
||||||
}
|
}
|
||||||
|
@ -84,16 +80,28 @@ type (
|
||||||
XCoordinate []byte
|
XCoordinate []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PutAuthenticationKeyResponse struct {
|
||||||
|
ObjectID uint16
|
||||||
|
}
|
||||||
|
|
||||||
ChangeAuthenticationKeyResponse struct {
|
ChangeAuthenticationKeyResponse struct {
|
||||||
ObjectID uint16
|
ObjectID uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
PutWrapkeyResponse struct {
|
PutOpaqueResponse struct {
|
||||||
ObjectID uint16
|
ObjectID uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
PutAuthkeyResponse struct {
|
GetOpaqueResponse struct {
|
||||||
ObjectID uint16
|
Data []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
SignDataPkcs1Response struct {
|
||||||
|
Signature []byte
|
||||||
|
}
|
||||||
|
|
||||||
|
SignAttestationCertResponse struct {
|
||||||
|
Cert []byte
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -131,8 +139,6 @@ func ParseResponse(data []byte) (Response, error) {
|
||||||
return parseSignDataEddsaResponse(payload)
|
return parseSignDataEddsaResponse(payload)
|
||||||
case CommandTypeSignDataEcdsa:
|
case CommandTypeSignDataEcdsa:
|
||||||
return parseSignDataEcdsaResponse(payload)
|
return parseSignDataEcdsaResponse(payload)
|
||||||
case CommandTypeSignDataPkcs1:
|
|
||||||
return parseSignDataPkcs1Response(payload)
|
|
||||||
case CommandTypePutAsymmetric:
|
case CommandTypePutAsymmetric:
|
||||||
return parsePutAsymmetricKeyResponse(payload)
|
return parsePutAsymmetricKeyResponse(payload)
|
||||||
case CommandTypeListObjects:
|
case CommandTypeListObjects:
|
||||||
|
@ -149,14 +155,18 @@ func ParseResponse(data []byte) (Response, error) {
|
||||||
return parseEchoResponse(payload)
|
return parseEchoResponse(payload)
|
||||||
case CommandTypeDeriveEcdh:
|
case CommandTypeDeriveEcdh:
|
||||||
return parseDeriveEcdhResponse(payload)
|
return parseDeriveEcdhResponse(payload)
|
||||||
|
case CommandTypePutAuthKey:
|
||||||
|
return parsePutAuthenticationKeyResponse(payload)
|
||||||
case CommandTypeChangeAuthenticationKey:
|
case CommandTypeChangeAuthenticationKey:
|
||||||
return parseChangeAuthenticationKeyResponse(payload)
|
return parseChangeAuthenticationKeyResponse(payload)
|
||||||
case CommandTypeGetPseudoRandom:
|
case CommandTypePutOpaque:
|
||||||
return parseGetPseudoRandomResponse(payload), nil
|
return parsePutOpaqueResponse(payload)
|
||||||
case CommandTypePutWrapKey:
|
case CommandTypeGetOpaque:
|
||||||
return parsePutWrapkeyResponse(payload)
|
return parseGetOpaqueResponse(payload)
|
||||||
case CommandTypePutAuthKey:
|
case CommandTypeSignDataPkcs1:
|
||||||
return parsePutAuthkeyResponse(payload)
|
return parseSignDataPkcs1Response(payload)
|
||||||
|
case CommandTypeAttestAsymmetric:
|
||||||
|
return parseAttestationCertResponse(payload)
|
||||||
case ErrorResponseCode:
|
case ErrorResponseCode:
|
||||||
return nil, parseErrorResponse(payload)
|
return nil, parseErrorResponse(payload)
|
||||||
default:
|
default:
|
||||||
|
@ -216,12 +226,6 @@ func parseSignDataEddsaResponse(payload []byte) (Response, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSignDataPkcs1Response(payload []byte) (Response, error) {
|
|
||||||
return &SignDataPkcs1Response{
|
|
||||||
Signature: payload,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseSignDataEcdsaResponse(payload []byte) (Response, error) {
|
func parseSignDataEcdsaResponse(payload []byte) (Response, error) {
|
||||||
return &SignDataEcdsaResponse{
|
return &SignDataEcdsaResponse{
|
||||||
Signature: payload,
|
Signature: payload,
|
||||||
|
@ -294,6 +298,20 @@ func parseDeriveEcdhResponse(payload []byte) (Response, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parsePutAuthenticationKeyResponse(payload []byte) (Response, error) {
|
||||||
|
if len(payload) != 2 {
|
||||||
|
return nil, errors.New("invalid response payload length")
|
||||||
|
}
|
||||||
|
|
||||||
|
var objectID uint16
|
||||||
|
err := binary.Read(bytes.NewReader(payload), binary.BigEndian, &objectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &PutAuthenticationKeyResponse{ObjectID: objectID}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func parseChangeAuthenticationKeyResponse(payload []byte) (Response, error) {
|
func parseChangeAuthenticationKeyResponse(payload []byte) (Response, error) {
|
||||||
if len(payload) != 2 {
|
if len(payload) != 2 {
|
||||||
return nil, errors.New("invalid response payload length")
|
return nil, errors.New("invalid response payload length")
|
||||||
|
@ -308,11 +326,7 @@ func parseChangeAuthenticationKeyResponse(payload []byte) (Response, error) {
|
||||||
return &ChangeAuthenticationKeyResponse{ObjectID: objectID}, nil
|
return &ChangeAuthenticationKeyResponse{ObjectID: objectID}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseGetPseudoRandomResponse(payload []byte) Response {
|
func parsePutOpaqueResponse(payload []byte) (Response, error) {
|
||||||
return payload
|
|
||||||
}
|
|
||||||
|
|
||||||
func parsePutWrapkeyResponse(payload []byte) (Response, error) {
|
|
||||||
if len(payload) != 2 {
|
if len(payload) != 2 {
|
||||||
return nil, errors.New("invalid response payload length")
|
return nil, errors.New("invalid response payload length")
|
||||||
}
|
}
|
||||||
|
@ -322,20 +336,40 @@ func parsePutWrapkeyResponse(payload []byte) (Response, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &PutWrapkeyResponse{ObjectID: objectID}, nil
|
|
||||||
|
return &PutOpaqueResponse{
|
||||||
|
ObjectID: objectID,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parsePutAuthkeyResponse(payload []byte) (Response, error) {
|
func parseGetOpaqueResponse(payload []byte) (Response, error) {
|
||||||
if len(payload) != 2 {
|
if len(payload) < 1 {
|
||||||
return nil, errors.New("invalid response payload length")
|
return nil, errors.New("invalid response payload length")
|
||||||
}
|
}
|
||||||
|
|
||||||
var objectID uint16
|
return &GetOpaqueResponse{
|
||||||
err := binary.Read(bytes.NewReader(payload), binary.BigEndian, &objectID)
|
Data: payload,
|
||||||
if err != nil {
|
}, nil
|
||||||
return nil, err
|
}
|
||||||
|
|
||||||
|
func parseSignDataPkcs1Response(payload []byte) (Response, error) {
|
||||||
|
if len(payload) < 1 {
|
||||||
|
return nil, errors.New("invalid response payload length")
|
||||||
}
|
}
|
||||||
return &PutAuthkeyResponse{ObjectID: objectID}, nil
|
|
||||||
|
return &SignDataPkcs1Response{
|
||||||
|
Signature: payload,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseAttestationCertResponse(payload []byte) (Response, error) {
|
||||||
|
if len(payload) < 1 {
|
||||||
|
return nil, errors.New("invalid response payload length")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SignAttestationCertResponse{
|
||||||
|
Cert: payload,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error formats a card error message into a human readable format
|
// Error formats a card error message into a human readable format
|
||||||
|
@ -366,12 +400,18 @@ func (e *Error) Error() string {
|
||||||
message = "Log full"
|
message = "Log full"
|
||||||
case ErrorCodeObjectNotFound:
|
case ErrorCodeObjectNotFound:
|
||||||
message = "Object not found"
|
message = "Object not found"
|
||||||
case ErrorCodeIDIllegal:
|
case ErrorCodeInvalidID:
|
||||||
message = "ID illegal"
|
message = "Invalid ID"
|
||||||
case ErrorCodeCommandUnexecuted:
|
case ErrorCodeSSHCAConstraintViolation:
|
||||||
message = "Command unexecuted"
|
message = "SSH CA constraint violation"
|
||||||
|
case ErrorCodeInvalidOTP:
|
||||||
|
message = "Invalid OTP"
|
||||||
|
case ErrorCodeDemoMode:
|
||||||
|
message = "Demo mode"
|
||||||
|
case ErrorCodeObjectExists:
|
||||||
|
message = "Object exists"
|
||||||
default:
|
default:
|
||||||
message = "unknown"
|
message = "Unknown"
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("card responded with error: %s", message)
|
return fmt.Sprintf("card responded with error: %s", message)
|
||||||
|
|
|
@ -76,19 +76,23 @@ const (
|
||||||
ErrorCodeInvalidPermission ErrorCode = 0x09
|
ErrorCodeInvalidPermission ErrorCode = 0x09
|
||||||
ErrorCodeLogFull ErrorCode = 0x0a
|
ErrorCodeLogFull ErrorCode = 0x0a
|
||||||
ErrorCodeObjectNotFound ErrorCode = 0x0b
|
ErrorCodeObjectNotFound ErrorCode = 0x0b
|
||||||
ErrorCodeIDIllegal ErrorCode = 0x0c
|
ErrorCodeInvalidID ErrorCode = 0x0c
|
||||||
ErrorCodeCommandUnexecuted ErrorCode = 0xff
|
ErrorCodeSSHCAConstraintViolation ErrorCode = 0x0e
|
||||||
|
ErrorCodeInvalidOTP ErrorCode = 0x0f
|
||||||
|
ErrorCodeDemoMode ErrorCode = 0x10
|
||||||
|
ErrorCodeObjectExists ErrorCode = 0x11
|
||||||
|
|
||||||
// Algorithms
|
// Algorithms
|
||||||
|
AlgorithmRSA2048 Algorithm = 9
|
||||||
AlgorithmP256 Algorithm = 12
|
AlgorithmP256 Algorithm = 12
|
||||||
AlgorithmSecp256k1 Algorithm = 15
|
AlgorithmSecp256k1 Algorithm = 15
|
||||||
|
AlgorithmOpaqueData Algorithm = 30
|
||||||
|
AlgorithmOpaqueX509Certificate Algorithm = 31
|
||||||
AlgorithmYubicoAESAuthentication Algorithm = 38
|
AlgorithmYubicoAESAuthentication Algorithm = 38
|
||||||
AlgorighmED25519 Algorithm = 46
|
AlgorithmED25519 Algorithm = 46
|
||||||
AlgorithmAES128CCMWrap Algorithm = 29
|
|
||||||
AlgorithmAES192CCMWrap Algorithm = 41
|
|
||||||
AlgorithmAES256CCMWrap Algorithm = 42
|
|
||||||
|
|
||||||
// Capabilities
|
// Capabilities
|
||||||
|
CapabilityNone uint64 = 0x0000000000000000
|
||||||
CapabilityGetOpaque uint64 = 0x0000000000000001
|
CapabilityGetOpaque uint64 = 0x0000000000000001
|
||||||
CapabilityPutOpaque uint64 = 0x0000000000000002
|
CapabilityPutOpaque uint64 = 0x0000000000000002
|
||||||
CapabilityPutAuthKey uint64 = 0x0000000000000004
|
CapabilityPutAuthKey uint64 = 0x0000000000000004
|
||||||
|
@ -106,7 +110,7 @@ const (
|
||||||
CapabilityImportWrapped uint64 = 0x0000000000002000
|
CapabilityImportWrapped uint64 = 0x0000000000002000
|
||||||
CapabilityPutWrapKey uint64 = 0x0000000000004000
|
CapabilityPutWrapKey uint64 = 0x0000000000004000
|
||||||
CapabilityGenerateWrapKey uint64 = 0x0000000000008000
|
CapabilityGenerateWrapKey uint64 = 0x0000000000008000
|
||||||
CapabilityExportUnderWrap uint64 = 0x0000000000010000
|
CapabilityExportableUnderWrap uint64 = 0x0000000000010000
|
||||||
CapabilityPutOption uint64 = 0x0000000000020000
|
CapabilityPutOption uint64 = 0x0000000000020000
|
||||||
CapabilityGetOption uint64 = 0x0000000000040000
|
CapabilityGetOption uint64 = 0x0000000000040000
|
||||||
CapabilityGetRandomness uint64 = 0x0000000000080000
|
CapabilityGetRandomness uint64 = 0x0000000000080000
|
||||||
|
@ -136,6 +140,7 @@ const (
|
||||||
CapabilityDeleteHmacKey uint64 = 0x0000080000000000
|
CapabilityDeleteHmacKey uint64 = 0x0000080000000000
|
||||||
CapabilityDeleteTemplate uint64 = 0x0000100000000000
|
CapabilityDeleteTemplate uint64 = 0x0000100000000000
|
||||||
CapabilityDeleteOtpAeadKey uint64 = 0x0000200000000000
|
CapabilityDeleteOtpAeadKey uint64 = 0x0000200000000000
|
||||||
|
CapabilityChangeAuthKey uint64 = 0x0000400000000000
|
||||||
|
|
||||||
// Domains
|
// Domains
|
||||||
Domain1 uint16 = 0x0001
|
Domain1 uint16 = 0x0001
|
||||||
|
@ -167,13 +172,8 @@ const (
|
||||||
// list objects params
|
// list objects params
|
||||||
ListObjectParamID uint8 = 0x01
|
ListObjectParamID uint8 = 0x01
|
||||||
ListObjectParamType uint8 = 0x02
|
ListObjectParamType uint8 = 0x02
|
||||||
|
ListObjectParamDomains uint8 = 0x03
|
||||||
|
ListObjectParamCapabilities uint8 = 0x04
|
||||||
|
ListObjectParamAlgorithm uint8 = 0x05
|
||||||
|
ListObjectParamLabel uint8 = 0x06
|
||||||
)
|
)
|
||||||
|
|
||||||
// CapabilityPrimitiveFromSlice OR's all the capabilitites together.
|
|
||||||
func CapabilityPrimitiveFromSlice(capabilitites []uint64) uint64 {
|
|
||||||
var primitive uint64
|
|
||||||
for _, c := range capabilitites {
|
|
||||||
primitive |= c
|
|
||||||
}
|
|
||||||
return primitive
|
|
||||||
}
|
|
||||||
|
|
4
go.mod
4
go.mod
|
@ -1,6 +1,8 @@
|
||||||
module github.com/certusone/yubihsm-go
|
module github.com/certusone/yubihsm-go
|
||||||
|
|
||||||
|
go 1.14
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815
|
github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815
|
||||||
golang.org/x/crypto v0.0.0-20180830192347-182538f80094
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||||
)
|
)
|
||||||
|
|
7
go.sum
7
go.sum
|
@ -2,3 +2,10 @@ github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815 h1:D22EM5TeYZJp43hGD
|
||||||
github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw=
|
github.com/enceve/crypto v0.0.0-20160707101852-34d48bb93815/go.mod h1:wYFFK4LYXbX7j+76mOq7aiC/EAw2S22CrzPHqgsisPw=
|
||||||
golang.org/x/crypto v0.0.0-20180830192347-182538f80094 h1:rVTAlhYa4+lCfNxmAIEOGQRoD23UqP72M3+rSWVGDTg=
|
golang.org/x/crypto v0.0.0-20180830192347-182538f80094 h1:rVTAlhYa4+lCfNxmAIEOGQRoD23UqP72M3+rSWVGDTg=
|
||||||
golang.org/x/crypto v0.0.0-20180830192347-182538f80094/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20180830192347-182538f80094/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||||
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||||
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
|
|
@ -85,6 +85,8 @@ const (
|
||||||
MaxMessagesPerSession = 10000
|
MaxMessagesPerSession = 10000
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrAuthCryptogram = errors.New("authentication failed: device sent wrong cryptogram")
|
||||||
|
|
||||||
// NewSecureChannel initiates a new secure channel to communicate with an HSM using the given authKey
|
// NewSecureChannel initiates a new secure channel to communicate with an HSM using the given authKey
|
||||||
// Call Authenticate next to establish a session.
|
// Call Authenticate next to establish a session.
|
||||||
func NewSecureChannel(connector connector.Connector, authKeySlot uint16, password string) (*SecureChannel, error) {
|
func NewSecureChannel(connector connector.Connector, authKeySlot uint16, password string) (*SecureChannel, error) {
|
||||||
|
@ -143,7 +145,7 @@ func (s *SecureChannel) Authenticate() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bytes.Equal(deviceCryptogram, createSessionResp.CardCryptogram) {
|
if !bytes.Equal(deviceCryptogram, createSessionResp.CardCryptogram) {
|
||||||
return errors.New("authentication failed: device sent wrong cryptogram")
|
return ErrAuthCryptogram
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create host cryptogram
|
// Create host cryptogram
|
||||||
|
|
Loading…
Reference in New Issue