Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support assymetric key #14

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ _testmain.go
*.prof

coverage.txt
.idea
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should not go to the per-project .gitignore, but rather to your local .gitignore which is not tied to any project

2 changes: 1 addition & 1 deletion attribute.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (a *Attribute) BuildFieldValue(name string) (v interface{}, err error) {
v = ""
case ATTRIBUTE_NAME_OBJECT_TYPE, ATTRIBUTE_NAME_STATE:
v = Enum(0)
case ATTRIBUTE_NAME_INITIAL_DATE, ATTRIBUTE_NAME_LAST_CHANGE_DATE:
case ATTRIBUTE_NAME_INITIAL_DATE, ATTRIBUTE_NAME_LAST_CHANGE_DATE, ATTRIBUTE_NAME_ACTIVATION_DATE, ATTRIBUTE_NAME_DEACTIVATION_DATE:
v = time.Time{}
case ATTRIBUTE_NAME_NAME:
v = &Name{}
Expand Down
17 changes: 12 additions & 5 deletions auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,33 @@ import "github.com/pkg/errors"
type Authentication struct {
Tag `kmip:"AUTHENTICATION"`

CredentialType Enum `kmip:"CREDENTIAL_TYPE,required"`
CredentialValue interface{} `kmip:"CREDENTIAL_VALUE,required"`
Credential Credential `kmip:"CREDENTIAL"`
}

// BuildFieldValue builds value for CredentialValue based on CredentialType
func (a *Authentication) BuildFieldValue(name string) (v interface{}, err error) {
switch a.CredentialType {
switch a.Credential.CredentialType {
case CREDENTIAL_TYPE_USERNAME_AND_PASSWORD:
v = &CredentialUsernamePassword{}
default:
err = errors.Errorf("unsupported credential type: %v", a.CredentialType)
err = errors.Errorf("unsupported credential type: %v", a.Credential.CredentialType)
}

return
}

// CredentialUsernamePassword is a Credential structure for username/password authentication
// CredentialUsernamePassword is a CredentialValue structure for username/password authentication
type CredentialUsernamePassword struct {
Tag `kmip:"CREDENTIAL_VALUE"`

Username string `kmip:"USERNAME,required"`
Password string `kmip:"PASSWORD,required"`
}

// Credential is a structure for that contains a credentail value and type
type Credential struct {
Tag `kmip:"CREDENTIAL"`

CredentialType Enum `kmip:"CREDENTIAL_TYPE,required"`
CredentialValue interface{} `kmip:"CREDENTIAL_VALUE,required"`
}
18 changes: 18 additions & 0 deletions consts.go
Original file line number Diff line number Diff line change
Expand Up @@ -842,6 +842,24 @@ const (
ATTRIBUTE_NAME_ORIGINAL_CREATION_DATE = "Original Creation Date"
)

// kmip query functions
const (
QUERY_OPERATIONS Enum = 0x00000001
QUERY_OBJECTS Enum = 0x00000002
QUERY_SERVER_INFORMATION Enum = 0x00000003
QUERY_APPLICATION_NAMESPACES Enum = 0x00000004
QUERY_EXTENSION_LIST Enum = 0x00000005
QUERY_EXTENSION_MAP Enum = 0x00000006
QUERY_ATTESTATION_TYPES Enum = 0x00000007
QUERY_RNGS Enum = 0x00000008
QUERY_VALIDATIONS Enum = 0x00000009
QUERY_PROFILES Enum = 0x0000000A
QUERY_CAPABILITIES Enum = 0x0000000B
QUERY_CLIENT_REGISTRATION_METHODS Enum = 0x0000000C
QUERY_DEFAULTS_INFORMATION Enum = 0x0000000D
QUERY_STORAGE_PROTECTION_MASKS Enum = 0x0000000E
)

var tagMap = map[string]Tag{
"-": ANY_TAG,
"ANY_TAG": ANY_TAG,
Expand Down
85 changes: 85 additions & 0 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,91 @@ func (s *DecoderSuite) TestDecodeMessageCreate() {
}, m)
}

func (s *DecoderSuite) TestDecodeMessageCreateWithAuthentication() {
var m Request
var buf bytes.Buffer

c := Request{
Header: RequestHeader{
Version: ProtocolVersion{Major: 1, Minor: 1},
BatchCount: 1,
Authentication: Authentication{
Credential: Credential{
CredentialType: CREDENTIAL_TYPE_DEVICE,
CredentialValue: nil,
},
},
},
BatchItems: []RequestBatchItem{
{
Operation: OPERATION_CREATE,
RequestPayload: CreateRequest{
ObjectType: OBJECT_TYPE_SYMMETRIC_KEY,
TemplateAttribute: TemplateAttribute{
Attributes: []Attribute{
{
Name: ATTRIBUTE_NAME_CRYPTOGRAPHIC_ALGORITHM,
Value: CRYPTO_AES,
},
{
Name: ATTRIBUTE_NAME_CRYPTOGRAPHIC_LENGTH,
Value: int32(128),
},
{
Name: ATTRIBUTE_NAME_CRYPTOGRAPHIC_USAGE_MASK,
Value: int32(12),
},
{
Name: ATTRIBUTE_NAME_INITIAL_DATE,
Value: time.Unix(12345, 0),
},
},
},
},
},
},
}
err := NewEncoder(&buf).Encode(c)

err = NewDecoder(bytes.NewReader(buf.Bytes())).Decode(&m)
s.Assert().NoError(err)
s.Assert().Equal(
Request{
Header: RequestHeader{
Version: ProtocolVersion{Major: 1, Minor: 1},
BatchCount: 1,
},
BatchItems: []RequestBatchItem{
{
Operation: OPERATION_CREATE,
RequestPayload: CreateRequest{
ObjectType: OBJECT_TYPE_SYMMETRIC_KEY,
TemplateAttribute: TemplateAttribute{
Attributes: []Attribute{
{
Name: ATTRIBUTE_NAME_CRYPTOGRAPHIC_ALGORITHM,
Value: CRYPTO_AES,
},
{
Name: ATTRIBUTE_NAME_CRYPTOGRAPHIC_LENGTH,
Value: int32(128),
},
{
Name: ATTRIBUTE_NAME_CRYPTOGRAPHIC_USAGE_MASK,
Value: int32(12),
},
{
Name: ATTRIBUTE_NAME_INITIAL_DATE,
Value: time.Unix(12345, 0),
},
},
},
},
},
},
}, m)
}

func (s *DecoderSuite) TestDecodeMessageGet() {
var m Request

Expand Down
3 changes: 2 additions & 1 deletion encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,8 @@ func (e *Encoder) encode(rv reflect.Value, sd *structDesc) (err error) {
return
}

if isZero {
isVersion := f.name == "Minor" || f.name == "Major"
if isZero && !isVersion {
continue
}
}
Expand Down
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
module github.com/smira/go-kmip
module github.com/akeylesslabs/go-kmip
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this shouldn't change


go 1.16

require (
github.com/pkg/errors v0.8.1
Expand Down
38 changes: 38 additions & 0 deletions operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,41 @@ type SignResponse struct {
SignatureData []byte `kmip:"SIGNATURE_DATA"`
CorrelationValue []byte `kmip:"CORRELATION_VALUE"`
}

// RegisterRequest is a Register Request Payload
type RegisterRequest struct {
ObjectType Enum `kmip:"OBJECT_TYPE,required"`
TemplateAttribute TemplateAttribute `kmip:"TEMPLATE_ATTRIBUTE,required"`
// Request might contain one of SymmetricKey, Certificate, ...
SymmetricKey SymmetricKey `kmip:"SYMMETRIC_KEY"`
PrivateKey PrivateKey `kmip:"PRIVATE_KEY"`
PublicKey PublicKey `kmip:"PUBLIC_KEY"`
}

// RegisterResponse is a Register Response Payload
type RegisterResponse struct {
UniqueIdentifier string `kmip:"UNIQUE_IDENTIFIER,required"`
TemplateAttribute TemplateAttribute `kmip:"TEMPLATE_ATTRIBUTE"`
}

// LocateRequest is a Locate Request Payload
type LocateRequest struct {
MaximumItems int32 `kmip:"MAXIMUM_ITEMS"`
OffsetItems int32 `kmip:"OFFSET_ITEMS"`
StorageStatusMask int32 `kmip:"STORAGE_STATUS_MASK"`
ObjectGroupMember Enum `kmip:"OBJECT_GROUP_MEMBER"`
Attributes Attributes `kmip:"ATTRIBUTE"`
}

// LocateResponse is a Locate Response Payload
type LocateResponse struct {
LocatedItems int32 `kmip:"LOCATED_ITEMS"`
UniqueIdentifiers []string `kmip:"UNIQUE_IDENTIFIER"`
}
type ReKeyRequest struct {
UniqueIdentifier string `kmip:"UNIQUE_IDENTIFIER,required"`
}

type ReKeyResponse struct {
UniqueIdentifier string `kmip:"UNIQUE_IDENTIFIER,required"`
}
43 changes: 31 additions & 12 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,19 @@ type Request struct {
type RequestHeader struct {
Tag `kmip:"REQUEST_HEADER"`

Version ProtocolVersion `kmip:"PROTOCOL_VERSION,required"`
MaxResponseSize int32 `kmip:"MAXIMUM_RESPONSE_SIZE"`
ClientCorrelationValue string `kmip:"CLIENT_CORRELATION_VALUE"`
ServerCorrelationValue string `kmip:"SERVER_CORRELATION_VALUE"`
AsynchronousIndicator bool `kmip:"ASYNCHRONOUS_INDICATOR"`
AttestationCapableIndicator bool `kmip:"ATTESTATION_CAPABLE_INDICATOR"`
AttestationType []Enum `kmip:"ATTESTATION_TYPE"`
Authentication Authentication `kmip:"AUTHENTICATION"`
BatchErrorContinuationOption Enum `kmip:"BATCH_ERROR_CONTINUATION_OPTION"`
BatchOrderOption bool `kmip:"BATCH_ORDER_OPTION"`
TimeStamp time.Time `kmip:"TIME_STAMP"`
BatchCount int32 `kmip:"BATCH_COUNT,required"`
Version ProtocolVersion `kmip:"PROTOCOL_VERSION,required"`
MaxResponseSize int32 `kmip:"MAXIMUM_RESPONSE_SIZE"`
ClientCorrelationValue string `kmip:"CLIENT_CORRELATION_VALUE"`
ServerCorrelationValue string `kmip:"SERVER_CORRELATION_VALUE"`
AsynchronousIndicator bool `kmip:"ASYNCHRONOUS_INDICATOR"`
AttestationCapableIndicator bool `kmip:"ATTESTATION_CAPABLE_INDICATOR"`
AttestationType []Enum `kmip:"ATTESTATION_TYPE"`
// Request authentication not implemented for now
Authentication Authentication `kmip:"AUTHENTICATION,skip"`
BatchErrorContinuationOption Enum `kmip:"BATCH_ERROR_CONTINUATION_OPTION"`
BatchOrderOption bool `kmip:"BATCH_ORDER_OPTION"`
TimeStamp time.Time `kmip:"TIME_STAMP"`
BatchCount int32 `kmip:"BATCH_COUNT,required"`
}

// RequestBatchItem is a Request Batch Item Structure
Expand All @@ -51,6 +52,8 @@ func (bi *RequestBatchItem) BuildFieldValue(name string) (v interface{}, err err
switch bi.Operation {
case OPERATION_CREATE:
v = &CreateRequest{}
case OPERATION_CREATE_KEY_PAIR:
v = &CreateKeyPairRequest{}
case OPERATION_GET:
v = &GetRequest{}
case OPERATION_GET_ATTRIBUTES:
Expand All @@ -61,6 +64,22 @@ func (bi *RequestBatchItem) BuildFieldValue(name string) (v interface{}, err err
v = &DestroyRequest{}
case OPERATION_DISCOVER_VERSIONS:
v = &DiscoverVersionsRequest{}
case OPERATION_REGISTER:
v = &RegisterRequest{}
case OPERATION_ACTIVATE:
v = &ActivateRequest{}
case OPERATION_LOCATE:
v = &LocateRequest{}
case OPERATION_REVOKE:
v = &RevokeRequest{}
case OPERATION_REKEY:
v = &ReKeyRequest{}
case OPERATION_DECRYPT:
v = &DecryptRequest{}
case OPERATION_ENCRYPT:
v = &EncryptRequest{}
case OPERATION_QUERY:
v = &QueryRequest{}
default:
err = errors.Errorf("unsupported operation: %v", bi.Operation)
}
Expand Down
8 changes: 8 additions & 0 deletions response.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ func (bi *ResponseBatchItem) BuildFieldValue(name string) (v interface{}, err er
v = &DecryptResponse{}
case OPERATION_SIGN:
v = &SignResponse{}
case OPERATION_REGISTER:
v = &RegisterResponse{}
case OPERATION_LOCATE:
v = &LocateResponse{}
case OPERATION_REKEY:
v = &ReKeyResponse{}
case OPERATION_QUERY:
v = &QueryResponse{}
default:
err = errors.Errorf("unsupported operation: %v", bi.Operation)
}
Expand Down
2 changes: 1 addition & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ func (s *Server) handleBatch(session *SessionContext, req *Request) (resp *Respo
SessionContext: *session,
}

if req.Header.Authentication.CredentialType != 0 {
if req.Header.Authentication.Credential.CredentialType != 0 {
if s.RequestAuthHandler == nil {
err = errors.New("request has authentication set, but no auth handler configured")
return
Expand Down