mirror of
https://github.com/emmansun/gmsm.git
synced 2025-04-27 04:36: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
|
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())
|
der := cryptobyte.String(keyData.PublicKey.RightAlign())
|
||||||
switch algo {
|
switch {
|
||||||
case RSA:
|
case oid.Equal(oidPublicKeyRSA):
|
||||||
// RSA public keys must have a NULL in the parameters.
|
// RSA public keys must have a NULL in the parameters.
|
||||||
// See RFC 3279, Section 2.3.1.
|
// 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")
|
return nil, errors.New("x509: RSA key missing NULL parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,8 +268,8 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
|||||||
N: p.N,
|
N: p.N,
|
||||||
}
|
}
|
||||||
return pub, nil
|
return pub, nil
|
||||||
case ECDSA:
|
case oid.Equal(oidPublicKeyECDSA):
|
||||||
paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
|
paramsDer := cryptobyte.String(params.FullBytes)
|
||||||
namedCurveOID := new(asn1.ObjectIdentifier)
|
namedCurveOID := new(asn1.ObjectIdentifier)
|
||||||
if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
|
if !paramsDer.ReadASN1ObjectIdentifier(namedCurveOID) {
|
||||||
return nil, errors.New("x509: invalid ECDSA parameters")
|
return nil, errors.New("x509: invalid ECDSA parameters")
|
||||||
@ -286,17 +288,25 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
|||||||
Y: y,
|
Y: y,
|
||||||
}
|
}
|
||||||
return pub, nil
|
return pub, nil
|
||||||
case Ed25519:
|
case oid.Equal(oidPublicKeyEd25519):
|
||||||
// RFC 8410, Section 3
|
// RFC 8410, Section 3
|
||||||
// > For all of the OIDs, the parameters MUST be absent.
|
// > 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")
|
return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
|
||||||
}
|
}
|
||||||
if len(der) != ed25519.PublicKeySize {
|
if len(der) != ed25519.PublicKeySize {
|
||||||
return nil, errors.New("x509: wrong Ed25519 public key size")
|
return nil, errors.New("x509: wrong Ed25519 public key size")
|
||||||
}
|
}
|
||||||
return ed25519.PublicKey(der), nil
|
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)
|
y := new(big.Int)
|
||||||
if !der.ReadASN1Integer(y) {
|
if !der.ReadASN1Integer(y) {
|
||||||
return nil, errors.New("x509: invalid DSA public key")
|
return nil, errors.New("x509: invalid DSA public key")
|
||||||
@ -309,7 +319,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
|||||||
G: new(big.Int),
|
G: new(big.Int),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
paramsDer := cryptobyte.String(keyData.Algorithm.Parameters.FullBytes)
|
paramsDer := cryptobyte.String(params.FullBytes)
|
||||||
if !paramsDer.ReadASN1(¶msDer, cryptobyte_asn1.SEQUENCE) ||
|
if !paramsDer.ReadASN1(¶msDer, cryptobyte_asn1.SEQUENCE) ||
|
||||||
!paramsDer.ReadASN1Integer(pub.Parameters.P) ||
|
!paramsDer.ReadASN1Integer(pub.Parameters.P) ||
|
||||||
!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
|
!paramsDer.ReadASN1Integer(pub.Parameters.Q) ||
|
||||||
@ -322,7 +332,7 @@ func parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{
|
|||||||
}
|
}
|
||||||
return pub, nil
|
return pub, nil
|
||||||
default:
|
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) {
|
if !spki.ReadASN1BitString(&spk) {
|
||||||
return nil, errors.New("x509: malformed subjectPublicKey")
|
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,
|
Algorithm: pkAI,
|
||||||
PublicKey: spk,
|
PublicKey: spk,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if cert.Version > 1 {
|
if cert.Version > 1 {
|
||||||
if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
|
if !tbs.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
|
||||||
|
@ -78,11 +78,7 @@ func ParsePKIXPublicKey(derBytes []byte) (interface{}, error) {
|
|||||||
} else if len(rest) != 0 {
|
} else if len(rest) != 0 {
|
||||||
return nil, errors.New("x509: trailing data after ASN.1 of public-key")
|
return nil, errors.New("x509: trailing data after ASN.1 of public-key")
|
||||||
}
|
}
|
||||||
algo := getPublicKeyAlgorithmFromOID(pki.Algorithm.Algorithm)
|
return parsePublicKey(&pki)
|
||||||
if algo == UnknownPublicKeyAlgorithm {
|
|
||||||
return nil, errors.New("x509: unknown public key algorithm")
|
|
||||||
}
|
|
||||||
return parsePublicKey(algo, &pki)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
|
func marshalPublicKey(pub interface{}) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {
|
||||||
@ -235,7 +231,7 @@ const (
|
|||||||
UnknownPublicKeyAlgorithm = x509.UnknownPublicKeyAlgorithm
|
UnknownPublicKeyAlgorithm = x509.UnknownPublicKeyAlgorithm
|
||||||
|
|
||||||
RSA = x509.RSA
|
RSA = x509.RSA
|
||||||
DSA = x509.DSA // Unsupported.
|
DSA = x509.DSA // Only supported for parsing.
|
||||||
ECDSA = x509.ECDSA
|
ECDSA = x509.ECDSA
|
||||||
Ed25519 = x509.Ed25519
|
Ed25519 = x509.Ed25519
|
||||||
)
|
)
|
||||||
@ -434,27 +430,34 @@ func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm
|
|||||||
return UnknownSignatureAlgorithm
|
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 (
|
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}
|
oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
|
||||||
oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 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}
|
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 {
|
func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {
|
||||||
switch {
|
switch {
|
||||||
case oid.Equal(oidPublicKeyRSA):
|
case oid.Equal(oidPublicKeyRSA):
|
||||||
@ -1388,6 +1391,10 @@ func CreateCertificate(rand io.Reader, template, parent *x509.Certificate, pub,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if getPublicKeyAlgorithmFromOID(publicKeyAlgorithm.Algorithm) == UnknownPublicKeyAlgorithm {
|
||||||
|
return nil, fmt.Errorf("x509: unsupported public key type: %T", pub)
|
||||||
|
}
|
||||||
|
|
||||||
asn1Issuer, err := subjectBytes(parent)
|
asn1Issuer, err := subjectBytes(parent)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -1902,10 +1909,12 @@ func parseCertificateRequest(in *certificateRequest) (*CertificateRequest, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
var err 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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var subject pkix.RDNSequence
|
var subject pkix.RDNSequence
|
||||||
if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
|
if rest, err := asn1.Unmarshal(in.TBSCSR.Subject.FullBytes, &subject); err != nil {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user