mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-11-02 03:27:54 +00:00
add ce changes for ecdsa hybrid (#29123)
This commit is contained in:
@@ -135,6 +135,16 @@ key.`,
|
||||
Description: `The parameter set to use. Applies to ML-DSA and SLH-DSA key types.
|
||||
For ML-DSA key types, valid values are 44, 65, or 87.`,
|
||||
},
|
||||
"hybrid_key_type_pqc": {
|
||||
Type: framework.TypeString,
|
||||
Description: `The key type of the post-quantum key to use for hybrid signature schemes.
|
||||
Supported types are: ML-DSA.`,
|
||||
},
|
||||
"hybrid_key_type_ec": {
|
||||
Type: framework.TypeString,
|
||||
Description: `The key type of the elliptic curve key to use for hybrid signature schemes.
|
||||
Supported types are: ecdsa-p256, ecdsa-p384, ecdsa-p521.`,
|
||||
},
|
||||
},
|
||||
|
||||
Operations: map[logical.Operation]framework.OperationHandler{
|
||||
@@ -184,6 +194,8 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
|
||||
managedKeyName := d.Get("managed_key_name").(string)
|
||||
managedKeyId := d.Get("managed_key_id").(string)
|
||||
parameterSet := d.Get("parameter_set").(string)
|
||||
pqcKeyType := d.Get("hybrid_key_type_pqc").(string)
|
||||
ecKeyType := d.Get("hybrid_key_type_ec").(string)
|
||||
|
||||
if autoRotatePeriod != 0 && autoRotatePeriod < time.Hour {
|
||||
return logical.ErrorResponse("auto rotate period must be 0 to disable or at least an hour"), nil
|
||||
@@ -241,6 +253,16 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
|
||||
return logical.ErrorResponse(fmt.Sprintf("invalid parameter set %s for key type %s", parameterSet, keyType)), logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
polReq.ParameterSet = parameterSet
|
||||
case "hybrid":
|
||||
polReq.KeyType = keysutil.KeyType_HYBRID
|
||||
|
||||
var err error
|
||||
polReq.HybridConfig, err = getHybridKeyConfig(pqcKeyType, parameterSet, ecKeyType)
|
||||
if err != nil {
|
||||
return logical.ErrorResponse(fmt.Sprintf("invalid config for hybrid key: %s", err)), logical.ErrInvalidRequest
|
||||
}
|
||||
|
||||
polReq.ParameterSet = parameterSet
|
||||
default:
|
||||
return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest
|
||||
@@ -393,6 +415,11 @@ func (b *backend) formatKeyPolicy(p *keysutil.Policy, context []byte) (*logical.
|
||||
resp.Data["parameter_set"] = p.ParameterSet
|
||||
}
|
||||
|
||||
if p.Type == keysutil.KeyType_HYBRID {
|
||||
resp.Data["hybrid_key_type_pqc"] = p.HybridConfig.PQCKeyType.String()
|
||||
resp.Data["hybrid_key_type_ec"] = p.HybridConfig.ECKeyType.String()
|
||||
}
|
||||
|
||||
switch p.Type {
|
||||
case keysutil.KeyType_AES128_GCM96, keysutil.KeyType_AES256_GCM96, keysutil.KeyType_ChaCha20_Poly1305:
|
||||
retKeys := map[string]int64{}
|
||||
@@ -401,7 +428,7 @@ func (b *backend) formatKeyPolicy(p *keysutil.Policy, context []byte) (*logical.
|
||||
}
|
||||
resp.Data["keys"] = retKeys
|
||||
|
||||
case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096, keysutil.KeyType_ML_DSA:
|
||||
case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096, keysutil.KeyType_ML_DSA, keysutil.KeyType_HYBRID:
|
||||
retKeys := map[string]map[string]interface{}{}
|
||||
for k, v := range p.Keys {
|
||||
key := asymKey{
|
||||
@@ -488,6 +515,36 @@ func (b *backend) pathPolicyDelete(ctx context.Context, req *logical.Request, d
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getHybridKeyConfig(pqcKeyType, parameterSet, ecKeyType string) (keysutil.HybridKeyConfig, error) {
|
||||
config := keysutil.HybridKeyConfig{}
|
||||
|
||||
switch pqcKeyType {
|
||||
case "ml-dsa":
|
||||
config.PQCKeyType = keysutil.KeyType_ML_DSA
|
||||
|
||||
if parameterSet != keysutil.ParameterSet_ML_DSA_44 &&
|
||||
parameterSet != keysutil.ParameterSet_ML_DSA_65 &&
|
||||
parameterSet != keysutil.ParameterSet_ML_DSA_87 {
|
||||
return keysutil.HybridKeyConfig{}, fmt.Errorf("invalid parameter set %s for key type %s", parameterSet, pqcKeyType)
|
||||
}
|
||||
default:
|
||||
return keysutil.HybridKeyConfig{}, fmt.Errorf("invalid PQC key type: %s", pqcKeyType)
|
||||
}
|
||||
|
||||
switch ecKeyType {
|
||||
case "ecdsa-p256":
|
||||
config.ECKeyType = keysutil.KeyType_ECDSA_P256
|
||||
case "ecdsa-p384":
|
||||
config.ECKeyType = keysutil.KeyType_ECDSA_P384
|
||||
case "ecdsa-p521":
|
||||
config.ECKeyType = keysutil.KeyType_ECDSA_P521
|
||||
default:
|
||||
return keysutil.HybridKeyConfig{}, fmt.Errorf("invalid key type for hybrid key: %s", ecKeyType)
|
||||
}
|
||||
|
||||
return config, nil
|
||||
}
|
||||
|
||||
const pathPolicyHelpSyn = `Managed named encryption keys`
|
||||
|
||||
const pathPolicyHelpDesc = `
|
||||
|
||||
@@ -254,6 +254,42 @@ func TestTransit_CreateKey(t *testing.T) {
|
||||
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-44-ECDSA-P256": {
|
||||
creationParams: map[string]interface{}{"type": "hybrid", "parameter_set": "44", "hybrid_key_type_ec": "ecdsa-p256", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-44-ECDSA-P384": {
|
||||
creationParams: map[string]interface{}{"type": "hybrid", "parameter_set": "44", "hybrid_key_type_ec": "ecdsa-p384", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-44-ECDSA-P521": {
|
||||
creationParams: map[string]interface{}{"type": "hybrid", "parameter_set": "44", "hybrid_key_type_ec": "ecdsa-p521", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-65-ECDSA-P256": {
|
||||
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "65", "hybrid_key_type_ec": "ecdsa-p256", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-65-ECDSA-P384": {
|
||||
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "65", "hybrid_key_type_ec": "ecdsa-p384", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-65-ECDSA-P521": {
|
||||
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "65", "hybrid_key_type_ec": "ecdsa-p521", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-87-ECDSA-P256": {
|
||||
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87", "hybrid_key_type_ec": "ecdsa-p256", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-87-ECDSA-P384": {
|
||||
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87", "hybrid_key_type_ec": "ecdsa-p384", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"Hybrid ML-DSA-87-ECDSA-P521": {
|
||||
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87", "hybrid_key_type_ec": "ecdsa-p521", "hybrid_key_type_pqc": "ml-dsa"},
|
||||
entOnly: true,
|
||||
},
|
||||
"bad key type": {
|
||||
creationParams: map[string]interface{}{"type": "fake-key-type"},
|
||||
shouldError: true,
|
||||
|
||||
@@ -71,6 +71,14 @@ type PolicyRequest struct {
|
||||
|
||||
// ParameterSet indicates the parameter set to use with ML-DSA and SLH-DSA keys
|
||||
ParameterSet string
|
||||
|
||||
// HybridConfig contains the key types and parameters for hybrid keys
|
||||
HybridConfig HybridKeyConfig
|
||||
}
|
||||
|
||||
type HybridKeyConfig struct {
|
||||
PQCKeyType KeyType
|
||||
ECKeyType KeyType
|
||||
}
|
||||
|
||||
type LockManager struct {
|
||||
@@ -412,6 +420,12 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io
|
||||
return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType)
|
||||
}
|
||||
|
||||
case KeyType_HYBRID:
|
||||
if req.Derived || req.Convergent {
|
||||
cleanup()
|
||||
return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType)
|
||||
}
|
||||
|
||||
default:
|
||||
cleanup()
|
||||
return nil, false, fmt.Errorf("unsupported key type %v", req.KeyType)
|
||||
@@ -427,6 +441,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io
|
||||
AutoRotatePeriod: req.AutoRotatePeriod,
|
||||
KeySize: req.KeySize,
|
||||
ParameterSet: req.ParameterSet,
|
||||
HybridConfig: req.HybridConfig,
|
||||
}
|
||||
|
||||
if req.Derived {
|
||||
|
||||
@@ -73,6 +73,7 @@ const (
|
||||
KeyType_AES128_CMAC
|
||||
KeyType_AES256_CMAC
|
||||
KeyType_ML_DSA
|
||||
KeyType_HYBRID
|
||||
// If adding to this list please update allTestKeyTypes in policy_test.go
|
||||
)
|
||||
|
||||
@@ -189,7 +190,7 @@ func (kt KeyType) DecryptionSupported() bool {
|
||||
|
||||
func (kt KeyType) SigningSupported() bool {
|
||||
switch kt {
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_MANAGED_KEY, KeyType_ML_DSA:
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_MANAGED_KEY, KeyType_ML_DSA, KeyType_HYBRID:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -241,7 +242,7 @@ func (kt KeyType) HMACSupported() bool {
|
||||
|
||||
func (kt KeyType) IsPQC() bool {
|
||||
switch kt {
|
||||
case KeyType_ML_DSA:
|
||||
case KeyType_ML_DSA, KeyType_HYBRID:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
@@ -297,6 +298,8 @@ func (kt KeyType) String() string {
|
||||
return "aes256-cmac"
|
||||
case KeyType_ML_DSA:
|
||||
return "ml-dsa"
|
||||
case KeyType_HYBRID:
|
||||
return "hybrid"
|
||||
}
|
||||
|
||||
return "[unknown]"
|
||||
@@ -570,6 +573,9 @@ type Policy struct {
|
||||
|
||||
// ParameterSet indicates the parameter set to use with ML-DSA and SLH-DSA keys
|
||||
ParameterSet string
|
||||
|
||||
// HybridConfig contains the key types and parameters for hybrid keys
|
||||
HybridConfig HybridKeyConfig
|
||||
}
|
||||
|
||||
func (p *Policy) Lock(exclusive bool) {
|
||||
@@ -1266,69 +1272,7 @@ func (p *Policy) SignWithOptions(ver int, context, input []byte, options *Signin
|
||||
|
||||
switch p.Type {
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521:
|
||||
var curveBits int
|
||||
var curve elliptic.Curve
|
||||
switch p.Type {
|
||||
case KeyType_ECDSA_P384:
|
||||
curveBits = 384
|
||||
curve = elliptic.P384()
|
||||
case KeyType_ECDSA_P521:
|
||||
curveBits = 521
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
curveBits = 256
|
||||
curve = elliptic.P256()
|
||||
}
|
||||
|
||||
key := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: keyParams.EC_X,
|
||||
Y: keyParams.EC_Y,
|
||||
},
|
||||
D: keyParams.EC_D,
|
||||
}
|
||||
|
||||
r, s, err := ecdsa.Sign(rand.Reader, key, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch marshaling {
|
||||
case MarshalingTypeASN1:
|
||||
// This is used by openssl and X.509
|
||||
sig, err = asn1.Marshal(ecdsaSignature{
|
||||
R: r,
|
||||
S: s,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case MarshalingTypeJWS:
|
||||
// This is used by JWS
|
||||
|
||||
// First we have to get the length of the curve in bytes. Although
|
||||
// we only support 256 now, we'll do this in an agnostic way so we
|
||||
// can reuse this marshaling if we support e.g. 521. Getting the
|
||||
// number of bytes without rounding up would be 65.125 so we need
|
||||
// to add one in that case.
|
||||
keyLen := curveBits / 8
|
||||
if curveBits%8 > 0 {
|
||||
keyLen++
|
||||
}
|
||||
|
||||
// Now create the output array
|
||||
sig = make([]byte, keyLen*2)
|
||||
rb := r.Bytes()
|
||||
sb := s.Bytes()
|
||||
copy(sig[keyLen-len(rb):], rb)
|
||||
copy(sig[2*keyLen-len(sb):], sb)
|
||||
|
||||
default:
|
||||
return nil, errutil.UserError{Err: "requested marshaling type is invalid"}
|
||||
}
|
||||
|
||||
sig, err = signWithECDSA(p.Type, keyParams, input, marshaling)
|
||||
case KeyType_ED25519:
|
||||
var key ed25519.PrivateKey
|
||||
|
||||
@@ -1403,6 +1347,76 @@ func (p *Policy) SignWithOptions(ver int, context, input []byte, options *Signin
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func signWithECDSA(keyType KeyType, keyParams KeyEntry, input []byte, marshaling MarshalingType) ([]byte, error) {
|
||||
var curveBits int
|
||||
var curve elliptic.Curve
|
||||
switch keyType {
|
||||
case KeyType_ECDSA_P256:
|
||||
curveBits = 256
|
||||
curve = elliptic.P256()
|
||||
case KeyType_ECDSA_P384:
|
||||
curveBits = 384
|
||||
curve = elliptic.P384()
|
||||
case KeyType_ECDSA_P521:
|
||||
curveBits = 521
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid key type %s for ECDSA", keyType)
|
||||
}
|
||||
|
||||
key := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: keyParams.EC_X,
|
||||
Y: keyParams.EC_Y,
|
||||
},
|
||||
D: keyParams.EC_D,
|
||||
}
|
||||
|
||||
r, s, err := ecdsa.Sign(rand.Reader, key, input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var sig []byte
|
||||
switch marshaling {
|
||||
case MarshalingTypeASN1:
|
||||
// This is used by openssl and X.509
|
||||
sig, err = asn1.Marshal(ecdsaSignature{
|
||||
R: r,
|
||||
S: s,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
case MarshalingTypeJWS:
|
||||
// This is used by JWS
|
||||
|
||||
// First we have to get the length of the curve in bytes. Although
|
||||
// we only support 256 now, we'll do this in an agnostic way so we
|
||||
// can reuse this marshaling if we support e.g. 521. Getting the
|
||||
// number of bytes without rounding up would be 65.125 so we need
|
||||
// to add one in that case.
|
||||
keyLen := curveBits / 8
|
||||
if curveBits%8 > 0 {
|
||||
keyLen++
|
||||
}
|
||||
|
||||
// Now create the output array
|
||||
sig = make([]byte, keyLen*2)
|
||||
rb := r.Bytes()
|
||||
sb := s.Bytes()
|
||||
copy(sig[keyLen-len(rb):], rb)
|
||||
copy(sig[2*keyLen-len(sb):], sb)
|
||||
|
||||
default:
|
||||
return nil, errutil.UserError{Err: "requested marshaling type is invalid"}
|
||||
}
|
||||
|
||||
return sig, nil
|
||||
}
|
||||
|
||||
func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType, sigAlgorithm string, marshaling MarshalingType, sig string) (bool, error) {
|
||||
return p.VerifySignatureWithOptions(context, input, sig, &SigningOptions{
|
||||
HashAlgorithm: hashAlgorithm,
|
||||
@@ -1465,49 +1479,11 @@ func (p *Policy) VerifySignatureWithOptions(context, input []byte, sig string, o
|
||||
|
||||
switch p.Type {
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521:
|
||||
var curve elliptic.Curve
|
||||
switch p.Type {
|
||||
case KeyType_ECDSA_P384:
|
||||
curve = elliptic.P384()
|
||||
case KeyType_ECDSA_P521:
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
curve = elliptic.P256()
|
||||
}
|
||||
|
||||
var ecdsaSig ecdsaSignature
|
||||
|
||||
switch marshaling {
|
||||
case MarshalingTypeASN1:
|
||||
rest, err := asn1.Unmarshal(sigBytes, &ecdsaSig)
|
||||
if err != nil {
|
||||
return false, errutil.UserError{Err: "supplied signature is invalid"}
|
||||
}
|
||||
if rest != nil && len(rest) != 0 {
|
||||
return false, errutil.UserError{Err: "supplied signature contains extra data"}
|
||||
}
|
||||
|
||||
case MarshalingTypeJWS:
|
||||
paramLen := len(sigBytes) / 2
|
||||
rb := sigBytes[:paramLen]
|
||||
sb := sigBytes[paramLen:]
|
||||
ecdsaSig.R = new(big.Int)
|
||||
ecdsaSig.R.SetBytes(rb)
|
||||
ecdsaSig.S = new(big.Int)
|
||||
ecdsaSig.S.SetBytes(sb)
|
||||
}
|
||||
|
||||
keyParams, err := p.safeGetKeyEntry(ver)
|
||||
key, err := p.safeGetKeyEntry(ver)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
key := &ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: keyParams.EC_X,
|
||||
Y: keyParams.EC_Y,
|
||||
}
|
||||
|
||||
return ecdsa.Verify(key, input, ecdsaSig.R, ecdsaSig.S), nil
|
||||
return verifyWithECDSA(p.Type, key, input, sigBytes, marshaling)
|
||||
|
||||
case KeyType_ED25519:
|
||||
var pub ed25519.PublicKey
|
||||
@@ -1586,6 +1562,50 @@ func (p *Policy) VerifySignatureWithOptions(context, input []byte, sig string, o
|
||||
}
|
||||
}
|
||||
|
||||
func verifyWithECDSA(keyType KeyType, keyParams KeyEntry, input, sigBytes []byte, marshaling MarshalingType) (bool, error) {
|
||||
var curve elliptic.Curve
|
||||
switch keyType {
|
||||
case KeyType_ECDSA_P256:
|
||||
curve = elliptic.P256()
|
||||
case KeyType_ECDSA_P384:
|
||||
curve = elliptic.P384()
|
||||
case KeyType_ECDSA_P521:
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
return false, fmt.Errorf("invalid key type %s for ECDSA", keyType)
|
||||
}
|
||||
|
||||
var ecdsaSig ecdsaSignature
|
||||
|
||||
switch marshaling {
|
||||
case MarshalingTypeASN1:
|
||||
rest, err := asn1.Unmarshal(sigBytes, &ecdsaSig)
|
||||
if err != nil {
|
||||
return false, errutil.UserError{Err: "supplied signature is invalid"}
|
||||
}
|
||||
if rest != nil && len(rest) != 0 {
|
||||
return false, errutil.UserError{Err: "supplied signature contains extra data"}
|
||||
}
|
||||
|
||||
case MarshalingTypeJWS:
|
||||
paramLen := len(sigBytes) / 2
|
||||
rb := sigBytes[:paramLen]
|
||||
sb := sigBytes[paramLen:]
|
||||
ecdsaSig.R = new(big.Int)
|
||||
ecdsaSig.R.SetBytes(rb)
|
||||
ecdsaSig.S = new(big.Int)
|
||||
ecdsaSig.S.SetBytes(sb)
|
||||
}
|
||||
|
||||
key := &ecdsa.PublicKey{
|
||||
Curve: curve,
|
||||
X: keyParams.EC_X,
|
||||
Y: keyParams.EC_Y,
|
||||
}
|
||||
|
||||
return ecdsa.Verify(key, input, ecdsaSig.R, ecdsaSig.S), nil
|
||||
}
|
||||
|
||||
func (p *Policy) Import(ctx context.Context, storage logical.Storage, key []byte, randReader io.Reader) error {
|
||||
return p.ImportPublicOrPrivate(ctx, storage, key, true, randReader)
|
||||
}
|
||||
@@ -1772,36 +1792,9 @@ func (p *Policy) RotateInMemory(randReader io.Reader) (retErr error) {
|
||||
}
|
||||
|
||||
case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521:
|
||||
var curve elliptic.Curve
|
||||
switch p.Type {
|
||||
case KeyType_ECDSA_P384:
|
||||
curve = elliptic.P384()
|
||||
case KeyType_ECDSA_P521:
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
curve = elliptic.P256()
|
||||
}
|
||||
|
||||
privKey, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
if err = generateECDSAKey(p.Type, &entry); err != nil {
|
||||
return err
|
||||
}
|
||||
entry.EC_D = privKey.D
|
||||
entry.EC_X = privKey.X
|
||||
entry.EC_Y = privKey.Y
|
||||
derBytes, err := x509.MarshalPKIXPublicKey(privKey.Public())
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("error marshaling public key: {{err}}", err)
|
||||
}
|
||||
pemBlock := &pem.Block{
|
||||
Type: "PUBLIC KEY",
|
||||
Bytes: derBytes,
|
||||
}
|
||||
pemBytes := pem.EncodeToMemory(pemBlock)
|
||||
if pemBytes == nil || len(pemBytes) == 0 {
|
||||
return fmt.Errorf("error PEM-encoding public key")
|
||||
}
|
||||
entry.FormattedPublicKey = string(pemBytes)
|
||||
|
||||
case KeyType_ED25519:
|
||||
// Go uses a 64-byte private key for Ed25519 keys (private+public, each
|
||||
@@ -2758,3 +2751,40 @@ func (p *Policy) ValidateAndPersistCertificateChain(ctx context.Context, keyVers
|
||||
p.Keys[strconv.Itoa(keyVersion)] = keyEntry
|
||||
return p.Persist(ctx, storage)
|
||||
}
|
||||
|
||||
func generateECDSAKey(keyType KeyType, entry *KeyEntry) error {
|
||||
var curve elliptic.Curve
|
||||
switch keyType {
|
||||
case KeyType_ECDSA_P256:
|
||||
curve = elliptic.P256()
|
||||
case KeyType_ECDSA_P384:
|
||||
curve = elliptic.P384()
|
||||
case KeyType_ECDSA_P521:
|
||||
curve = elliptic.P521()
|
||||
default:
|
||||
return fmt.Errorf("invalid key type %s for ECDSA", keyType)
|
||||
}
|
||||
|
||||
privKey, err := ecdsa.GenerateKey(curve, rand.Reader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
entry.EC_D = privKey.D
|
||||
entry.EC_X = privKey.X
|
||||
entry.EC_Y = privKey.Y
|
||||
derBytes, err := x509.MarshalPKIXPublicKey(privKey.Public())
|
||||
if err != nil {
|
||||
return errwrap.Wrapf("error marshaling public key: {{err}}", err)
|
||||
}
|
||||
pemBlock := &pem.Block{
|
||||
Type: "PUBLIC KEY",
|
||||
Bytes: derBytes,
|
||||
}
|
||||
pemBytes := pem.EncodeToMemory(pemBlock)
|
||||
if pemBytes == nil || len(pemBytes) == 0 {
|
||||
return fmt.Errorf("error PEM-encoding public key")
|
||||
}
|
||||
entry.FormattedPublicKey = string(pemBytes)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ var allTestKeyTypes = []KeyType{
|
||||
KeyType_AES256_GCM96, KeyType_ECDSA_P256, KeyType_ED25519, KeyType_RSA2048,
|
||||
KeyType_RSA4096, KeyType_ChaCha20_Poly1305, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_AES128_GCM96,
|
||||
KeyType_RSA3072, KeyType_MANAGED_KEY, KeyType_HMAC, KeyType_AES128_CMAC, KeyType_AES256_CMAC, KeyType_ML_DSA,
|
||||
KeyType_HYBRID,
|
||||
}
|
||||
|
||||
func TestPolicy_KeyTypes(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user