mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-26 20:26:19 +08:00
x509: add support for PKCS8/PKIX X25519 key encodings preparation
This commit is contained in:
parent
6c7ddbb206
commit
289bfe16c0
@ -233,13 +233,15 @@ func parseExtension(der cryptobyte.String) (pkix.Extension, error) {
|
||||
return ext, nil
|
||||
}
|
||||
|
||||
func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
|
||||
func parsePublicKey(keyData *publicKeyInfo) (interface{}, error) {
|
||||
oid := keyData.Algorithm.Algorithm
|
||||
params := keyData.Algorithm.Parameters
|
||||
der := cryptobyte.String(keyData.PublicKey.RightAlign())
|
||||
switch algo {
|
||||
case RSA:
|
||||
switch {
|
||||
case oid.Equal(oidPublicKeyRSA):
|
||||
// RSA public keys must have a NULL in the parameters.
|
||||
// See RFC 3279, Section 2.3.1.
|
||||
if !bytes.Equal(keyData.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
|
||||
if !bytes.Equal(params.FullBytes, asn1.NullBytes) {
|
||||
return nil, errors.New("x509: RSA key missing NULL parameters")
|
||||
}
|
||||
|
||||
@ -266,8 +268,8 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
||||
N: p.N,
|
||||
}
|
||||
return pub, nil
|
||||
case ECDSA:
|
||||
paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
|
||||
case oid.Equal(oidPublicKeyECDSA):
|
||||
paramsDer := cryptobyte.String(params.FullBytes)
|
||||
namedCurveOID := new(asn1.ObjectIdentifier)
|
||||
if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
|
||||
return nil, errors.New("x509: invalid ECDSA parameters")
|
||||
@ -286,17 +288,25 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
||||
Y: y,
|
||||
}
|
||||
return pub, nil
|
||||
case Ed25519:
|
||||
case oid.Equal(oidPublicKeyEd25519):
|
||||
// RFC 8410, Section 3
|
||||
// > For all of the OIDs, the parameters MUST be absent.
|
||||
if len(keyData.Algorithm.Parameters.FullBytes) != 0 {
|
||||
if len(params.FullBytes) != 0 {
|
||||
return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
|
||||
}
|
||||
if len(der) != ed25519.PublicKeySize {
|
||||
return nil, errors.New("x509: wrong Ed25519 public key size")
|
||||
}
|
||||
return ed25519.PublicKey(der), nil
|
||||
case DSA:
|
||||
//TODO: will enable it since golang 1.19.x
|
||||
//case oid.Equal(oidPublicKeyX25519):
|
||||
// RFC 8410, Section 3
|
||||
// > For all of the OIDs, the parameters MUST be absent.
|
||||
// if len(params.FullBytes) != 0 {
|
||||
// return nil, errors.New("x509: X25519 key encoded with illegal parameters")
|
||||
// }
|
||||
// return ecdh.X25519().NewPublicKey(der)
|
||||
case oid.Equal(oidPublicKeyDSA):
|
||||
y := new(big.Int)
|
||||
if !der.ReadASN1Integer(y) {
|
||||
return nil, errors.New("x509: invalid DSA public key")
|
||||
@ -309,7 +319,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
||||
G: new(big.Int),
|
||||
},
|
||||
}
|
||||
paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
|
||||
paramsDer := cryptobyte.String(params.FullBytes)
|
||||
if !paramsDer.ReadASN1(¶msDer, cryptobyte_asn1.SEQUENCE) ||
|
||||
!paramsDer.ReadASN1Integer(pub.Parameters.P) ||
|
||||
!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
|
||||
@ -322,7 +332,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
||||
}
|
||||
return pub, nil
|
||||
default:
|
||||
return nil, nil
|
||||
return nil, errors.New("x509: unknown public key algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
@ -929,13 +939,15 @@ func parseCertificate(der []byte) (*Certificate, error) {
|
||||
if !spki.ReadASN1BitString(&spk) {
|
||||
return nil, errors.New("x509: malformed subjectPublicKey")
|
||||
}
|
||||
cert.PublicKey, err = parsePublicKey(cert.PublicKeyAlgorithm, &publicKeyInfo{
|
||||
if cert.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
|
||||
cert.PublicKey, err = parsePublicKey(&publicKeyInfo{
|
||||
Algorithm: pkAI,
|
||||
PublicKey: spk,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if cert.Version > 1 {
|
||||
if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
|
||||
|
@ -78,11 +78,7 @@ func ParsePKIXPublicKey(derBytes []byte) (interface{}, error) {
|
||||
} else if len(rest) != 0 {
|
||||
return nil, errors.New("x509: trailing data after ASN.1 of public-key")
|
||||
}
|
||||
algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm)
|
||||
if algo == UnknownPublicKeyAlgorithm {
|
||||
return nil, errors.New("x509: unknown public key algorithm")
|
||||
}
|
||||
return parsePublicKey(algo, &pki)
|
||||
return parsePublicKey(&pki)
|
||||
}
|
||||
|
||||
func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
|
||||
@ -235,7 +231,7 @@ const (
|
||||
UnknownPublicKeyAlgorithm = x509.UnknownPublicKeyAlgorithm
|
||||
|
||||
RSA = x509.RSA
|
||||
DSA = x509.DSA // Unsupported.
|
||||
DSA = x509.DSA // Only supported for parsing.
|
||||
ECDSA = x509.ECDSA
|
||||
Ed25519 = x509.Ed25519
|
||||
)
|
||||
@ -434,27 +430,34 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm
|
||||
return UnknownSignatureAlgorithm
|
||||
}
|
||||
|
||||
// RFC 3279, 2.3 Public Key Algorithms
|
||||
//
|
||||
// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
|
||||
// rsadsi(113549) pkcs(1) 1 }
|
||||
//
|
||||
// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
|
||||
//
|
||||
// id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
|
||||
// x9-57(10040) x9cm(4) 1 }
|
||||
//
|
||||
// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
|
||||
//
|
||||
// id-ecPublicKey OBJECT IDENTIFIER ::= {
|
||||
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
|
||||
var (
|
||||
// RFC 3279, 2.3 Public Key Algorithms
|
||||
//
|
||||
// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
|
||||
// rsadsi(113549) pkcs(1) 1 }
|
||||
//
|
||||
// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
|
||||
//
|
||||
// id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
|
||||
// x9-57(10040) x9cm(4) 1 }
|
||||
oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
|
||||
oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
|
||||
// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
|
||||
//
|
||||
// id-ecPublicKey OBJECT IDENTIFIER ::= {
|
||||
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
|
||||
oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
|
||||
oidPublicKeyEd25519 = oidSignatureEd25519
|
||||
// RFC 8410, Section 3
|
||||
//
|
||||
// id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
|
||||
// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
|
||||
oidPublicKeyX25519 = asn1.ObjectIdentifier{1, 3, 101, 110}
|
||||
oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
|
||||
)
|
||||
|
||||
// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm
|
||||
// identifier for public key types supported in certificates and CSRs. Marshal
|
||||
// and Parse functions may support a different set of public key types.
|
||||
func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
|
||||
switch {
|
||||
case oid.Equal(oidPublicKeyRSA):
|
||||
@ -1388,6 +1391,10 @@ func CreateCertificate(rand io.Reader, template, parent *x509.Certificate, pub,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if getPublicKeyAlgorithmFromOID(publicKeyAlgorithm.Algorithm) == UnknownPublicKeyAlgorithm {
|
||||
return nil, fmt.Errorf("x509: unsupported public key type: %T", pub)
|
||||
}
|
||||
|
||||
asn1Issuer, err := subjectBytes(parent)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@ -1902,10 +1909,12 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
|
||||
}
|
||||
|
||||
var err error
|
||||
out.PublicKey, err = parsePublicKey(out.PublicKeyAlgorithm, &in.TBSCSR.PublicKey)
|
||||
if out.PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
|
||||
out.PublicKey, err = parsePublicKey(&in.TBSCSR.PublicKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var subject pkix.RDNSequence
|
||||
if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user