-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
288 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
// Copyright 2023 Contributors to the Veraison project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package comid | ||
|
||
import ( | ||
"crypto/x509" | ||
"encoding/json" | ||
"encoding/pem" | ||
"errors" | ||
"fmt" | ||
) | ||
|
||
const ( | ||
PKIXBase64KeyType = "PKIXBase64Key" | ||
) | ||
|
||
// CryptoKey is the struct implementing vCoRIM crypto-key-type-choice. See | ||
// https://www.ietf.org/archive/id/draft-ietf-rats-corim-02.html#name-crypto-keys | ||
type CryptoKey struct { | ||
Value ICryptoKeyValue | ||
} | ||
|
||
func (o CryptoKey) String() string { | ||
return o.Value.String() | ||
} | ||
|
||
func (o CryptoKey) Valid() error { | ||
return o.Value.Valid() | ||
} | ||
|
||
func (o CryptoKey) MarshalJSON() ([]byte, error) { | ||
value := struct { | ||
Type string `json:"type"` | ||
Value string `json:"value"` | ||
}{ | ||
Value: o.Value.String(), | ||
} | ||
|
||
switch o.Value.(type) { | ||
case TaggedPKIXBase64Key: | ||
value.Type = PKIXBase64KeyType | ||
default: | ||
return nil, fmt.Errorf("unexpected ICryptoKeyValue type: %T", o.Value) | ||
} | ||
|
||
return json.Marshal(value) | ||
} | ||
|
||
func (o *CryptoKey) UnmarshalJSON(b []byte) error { | ||
var value struct { | ||
Type string `json:"type"` | ||
Value string `json:"value"` | ||
} | ||
|
||
if err := json.Unmarshal(b, &value); err != nil { | ||
return err | ||
} | ||
|
||
if value.Type == "" { | ||
return errors.New("key type not set") | ||
} | ||
|
||
switch value.Type { | ||
case PKIXBase64KeyType: | ||
o.Value = TaggedPKIXBase64Key(value.Value) | ||
default: | ||
return fmt.Errorf("unexpected ICryptoKeyValue type: %q", value.Type) | ||
} | ||
|
||
return o.Valid() | ||
} | ||
|
||
func (o CryptoKey) MarshalCBOR() ([]byte, error) { | ||
return em.Marshal(o.Value) | ||
} | ||
|
||
func (o *CryptoKey) UnmarshalCBOR(b []byte) error { | ||
return dm.Unmarshal(b, &o.Value) | ||
} | ||
|
||
type ICryptoKeyValue interface { | ||
String() string | ||
Valid() error | ||
} | ||
|
||
type TaggedPKIXBase64Key string | ||
|
||
func NewPKIXBase64Key(s string) (*CryptoKey, error) { | ||
key := TaggedPKIXBase64Key(s) | ||
if err := key.Valid(); err != nil { | ||
return nil, err | ||
} | ||
return &CryptoKey{key}, nil | ||
} | ||
|
||
func MustNewPKIXBase64Key(s string) *CryptoKey { | ||
key, err := NewPKIXBase64Key(s) | ||
if err != nil { | ||
panic(err) | ||
} | ||
return key | ||
} | ||
|
||
func (o TaggedPKIXBase64Key) String() string { | ||
return string(o) | ||
} | ||
|
||
func (o TaggedPKIXBase64Key) Valid() error { | ||
if string(o) == "" { | ||
return errors.New("key value not set") | ||
} | ||
|
||
block, rest := pem.Decode([]byte(o)) | ||
if block == nil { | ||
return errors.New("could not extract PKIX PEM block") | ||
} | ||
|
||
if len(rest) != 0 { | ||
return errors.New("trailing data found after PEM block") | ||
} | ||
|
||
if block.Type != "PUBLIC KEY" { | ||
return fmt.Errorf("unsupported PEM block type: %q", block.Type) | ||
} | ||
|
||
_, err := x509.ParsePKIXPublicKey(block.Bytes) | ||
if err != nil { | ||
return fmt.Errorf("unable to parse public key: %w", err) | ||
} | ||
|
||
return nil | ||
} | ||
|
||
type TaggedPKIXBase64Cert string | ||
type TaggedPKIXBase64CertPath string | ||
type TaggedThumbprint string | ||
type TaggedCOSEKey string | ||
type TaggedCertThumbprint string | ||
type TaggedCertPathThumbprint string |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// Copyright 2023 Contributors to the Veraison project. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package comid | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func Test_CryptoKey_NewPKIXBase64Key(t *testing.T) { | ||
key, err := NewPKIXBase64Key(TestECPubKey) | ||
assert.NoError(t, err) | ||
assert.Equal(t, TestECPubKey, key.String()) | ||
|
||
_, err = NewPKIXBase64Key("") | ||
assert.EqualError(t, err, "key value not set") | ||
|
||
noPem := "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEW1BvqF+/ry8BWa7ZEMU1xYYHEQ8BlLT4MFHOaO+ICTtIvrEeEpr/sfTAP66H2hCHdb5HEXKtRKod6QLcOLPA1Q==" | ||
_, err = NewPKIXBase64Key(noPem) | ||
assert.EqualError(t, err, "could not extract PKIX PEM block") | ||
|
||
badKey := "-----BEGIN PUBLIC KEY-----\nDEADBEEF\n-----END PUBLIC KEY-----" | ||
_, err = NewPKIXBase64Key(badKey) | ||
assert.Contains(t, err.Error(), "unable to parse public key") | ||
} | ||
|
||
func Test_CryptoKey_JSON(t *testing.T) { | ||
key := MustNewPKIXBase64Key(TestECPubKey) | ||
data, err := json.Marshal(key) | ||
require.NoError(t, err) | ||
|
||
expected := fmt.Sprintf(`{"type": "PKIXBase64Key", "value": %q}`, TestECPubKey) | ||
assert.JSONEq(t, expected, string(data)) | ||
|
||
var key2 CryptoKey | ||
err = json.Unmarshal(data, &key2) | ||
require.NoError(t, err) | ||
assert.Equal(t, *key, key2) | ||
} | ||
|
||
func Test_CryptoKey_CBOR(t *testing.T) { | ||
key := MustNewPKIXBase64Key(TestECPubKey) | ||
data, err := em.Marshal(key) | ||
require.NoError(t, err) | ||
|
||
expected := MustHexDecode(t, "d9022a78b12d2d2d2d2d424547494e205055424c4943204b45592d2d2d2d2d0a4d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741455731427671462b2f727938425761375a454d553178595948455138420a6c4c54344d46484f614f2b4943547449767245654570722f7366544150363648326843486462354845584b74524b6f6436514c634f4c504131513d3d0a2d2d2d2d2d454e44205055424c4943204b45592d2d2d2d2d") | ||
assert.Equal(t, expected, data) | ||
|
||
var key2 CryptoKey | ||
err = dm.Unmarshal(data, &key2) | ||
require.NoError(t, err) | ||
assert.Equal(t, key.String(), key2.String()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.