2024-01-27 16:35:35 +00:00
|
|
|
package pkcs15
|
|
|
|
|
|
|
|
import (
|
2024-06-24 22:23:05 +00:00
|
|
|
"crypto"
|
2024-09-17 22:44:33 +00:00
|
|
|
"crypto/ecdsa"
|
|
|
|
"crypto/rsa"
|
2024-01-27 16:35:35 +00:00
|
|
|
"crypto/x509"
|
|
|
|
)
|
|
|
|
|
|
|
|
// pkcs15KeyCert holds the data for a key and certificate pair; it provides
|
|
|
|
// various methods to transform pkcs15 data
|
|
|
|
type pkcs15KeyCert struct {
|
2024-06-24 22:23:05 +00:00
|
|
|
key crypto.PrivateKey
|
2024-01-27 16:35:35 +00:00
|
|
|
cert *x509.Certificate
|
2024-09-17 22:44:33 +00:00
|
|
|
// store the encrypted enveloped Private Key for re-use
|
|
|
|
envelopedPrivateKey []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// KeyType is used by consumers to check for compatibility
|
|
|
|
type KeyType int
|
|
|
|
|
|
|
|
const (
|
|
|
|
KeyTypeRSA1024 KeyType = iota
|
|
|
|
KeyTypeRSA2048
|
|
|
|
KeyTypeRSA3072
|
|
|
|
KeyTypeRSA4096
|
|
|
|
|
|
|
|
KeyTypeECP256
|
|
|
|
KeyTypeECP384
|
|
|
|
KeyTypeECP521
|
|
|
|
|
|
|
|
KeyTypeUnknown
|
|
|
|
)
|
|
|
|
|
|
|
|
// KeyType returns the private key type
|
|
|
|
func (p15 *pkcs15KeyCert) KeyType() KeyType {
|
|
|
|
switch pKey := p15.key.(type) {
|
|
|
|
case *rsa.PrivateKey:
|
|
|
|
switch pKey.N.BitLen() {
|
|
|
|
case 1024:
|
|
|
|
return KeyTypeRSA1024
|
|
|
|
case 2048:
|
|
|
|
return KeyTypeRSA2048
|
|
|
|
case 3072:
|
|
|
|
return KeyTypeRSA3072
|
|
|
|
case 4096:
|
|
|
|
return KeyTypeRSA4096
|
|
|
|
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
case *ecdsa.PrivateKey:
|
|
|
|
switch pKey.Curve.Params().Name {
|
|
|
|
case "P-256":
|
|
|
|
return KeyTypeECP256
|
|
|
|
case "P-384":
|
|
|
|
return KeyTypeECP384
|
|
|
|
case "P-521":
|
|
|
|
return KeyTypeECP521
|
|
|
|
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
}
|
|
|
|
|
|
|
|
return KeyTypeUnknown
|
2024-01-27 16:35:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ParsePEMToPKCS15 parses the provide pem files to a pkcs15 struct; it also does some
|
|
|
|
// basic sanity check; if any of this fails, an error is returned
|
|
|
|
func ParsePEMToPKCS15(keyPem, certPem []byte) (*pkcs15KeyCert, error) {
|
|
|
|
// decode / check key
|
|
|
|
key, err := pemKeyDecode(keyPem)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// decode / check cert
|
|
|
|
cert, err := pemCertDecode(certPem, keyPem)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-09-17 22:44:33 +00:00
|
|
|
// create p15 struct
|
2024-01-27 16:35:35 +00:00
|
|
|
p15 := &pkcs15KeyCert{
|
|
|
|
key: key,
|
|
|
|
cert: cert,
|
|
|
|
}
|
|
|
|
|
2024-09-17 22:44:33 +00:00
|
|
|
// pre-calculate encrypted envelope
|
|
|
|
err = p15.computeEncryptedKeyEnvelope()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-01-27 16:35:35 +00:00
|
|
|
return p15, nil
|
|
|
|
}
|