// Copyright 2011 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package x509import ()// pkcs1PrivateKey is a structure which mirrors the PKCS #1 ASN.1 for an RSA private key.type pkcs1PrivateKey struct { Version int N *big.Int E int D *big.Int P *big.Int Q *big.Int Dp *big.Int`asn1:"optional"` Dq *big.Int`asn1:"optional"` Qinv *big.Int`asn1:"optional"` AdditionalPrimes []pkcs1AdditionalRSAPrime`asn1:"optional,omitempty"`}type pkcs1AdditionalRSAPrime struct { Prime *big.Int// We ignore these values because rsa will calculate them. Exp *big.Int Coeff *big.Int}// pkcs1PublicKey reflects the ASN.1 structure of a PKCS #1 public key.type pkcs1PublicKey struct { N *big.Int E int}// x509rsacrt, if zero, makes ParsePKCS1PrivateKey ignore and recompute invalid// CRT values in the RSA private key.var x509rsacrt = godebug.New("x509rsacrt")// ParsePKCS1PrivateKey parses an [RSA] private key in PKCS #1, ASN.1 DER form.//// This kind of key is commonly encoded in PEM blocks of type "RSA PRIVATE KEY".//// Before Go 1.24, the CRT parameters were ignored and recomputed. To restore// the old behavior, use the GODEBUG=x509rsacrt=0 environment variable.func ( []byte) (*rsa.PrivateKey, error) {varpkcs1PrivateKey , := asn1.Unmarshal(, &)iflen() > 0 {returnnil, asn1.SyntaxError{Msg: "trailing data"} }if != nil {if , := asn1.Unmarshal(, &ecPrivateKey{}); == nil {returnnil, errors.New("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)") }if , := asn1.Unmarshal(, &pkcs8{}); == nil {returnnil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)") }returnnil, }if .Version > 1 {returnnil, errors.New("x509: unsupported private key version") }if .N.Sign() <= 0 || .D.Sign() <= 0 || .P.Sign() <= 0 || .Q.Sign() <= 0 || .Dp.Sign() <= 0 || .Dq.Sign() <= 0 || .Qinv.Sign() <= 0 {returnnil, errors.New("x509: private key contains zero or negative value") } := new(rsa.PrivateKey) .PublicKey = rsa.PublicKey{E: .E,N: .N, } .D = .D .Primes = make([]*big.Int, 2+len(.AdditionalPrimes)) .Primes[0] = .P .Primes[1] = .Q .Precomputed.Dp = .Dp .Precomputed.Dq = .Dq .Precomputed.Qinv = .Qinvfor , := range .AdditionalPrimes {if .Prime.Sign() <= 0 {returnnil, errors.New("x509: private key contains zero or negative prime") } .Primes[+2] = .Prime// We ignore the other two values because rsa will calculate // them as needed. } .Precompute()if := .Validate(); != nil {// If x509rsacrt=0 is set, try dropping the CRT values and // rerunning precomputation and key validation.ifx509rsacrt.Value() == "0" { .Precomputed.Dp = nil .Precomputed.Dq = nil .Precomputed.Qinv = nil .Precompute()if := .Validate(); == nil {x509rsacrt.IncNonDefault()return , nil } }returnnil, }return , nil}// MarshalPKCS1PrivateKey converts an [RSA] private key to PKCS #1, ASN.1 DER form.//// This kind of key is commonly encoded in PEM blocks of type "RSA PRIVATE KEY".// For a more flexible key format which is not [RSA] specific, use// [MarshalPKCS8PrivateKey].//// The key must have passed validation by calling [rsa.PrivateKey.Validate]// first. MarshalPKCS1PrivateKey calls [rsa.PrivateKey.Precompute], which may// modify the key if not already precomputed.func ( *rsa.PrivateKey) []byte { .Precompute() := 0iflen(.Primes) > 2 { = 1 } := pkcs1PrivateKey{Version: ,N: .N,E: .PublicKey.E,D: .D,P: .Primes[0],Q: .Primes[1],Dp: .Precomputed.Dp,Dq: .Precomputed.Dq,Qinv: .Precomputed.Qinv, } .AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(.Precomputed.CRTValues))for , := range .Precomputed.CRTValues { .AdditionalPrimes[].Prime = .Primes[2+] .AdditionalPrimes[].Exp = .Exp .AdditionalPrimes[].Coeff = .Coeff } , := asn1.Marshal()return}// ParsePKCS1PublicKey parses an [RSA] public key in PKCS #1, ASN.1 DER form.//// This kind of key is commonly encoded in PEM blocks of type "RSA PUBLIC KEY".func ( []byte) (*rsa.PublicKey, error) {varpkcs1PublicKey , := asn1.Unmarshal(, &)if != nil {if , := asn1.Unmarshal(, &publicKeyInfo{}); == nil {returnnil, errors.New("x509: failed to parse public key (use ParsePKIXPublicKey instead for this key format)") }returnnil, }iflen() > 0 {returnnil, asn1.SyntaxError{Msg: "trailing data"} }if .N.Sign() <= 0 || .E <= 0 {returnnil, errors.New("x509: public key contains zero or negative value") }if .E > 1<<31-1 {returnnil, errors.New("x509: public key contains large public exponent") }return &rsa.PublicKey{E: .E,N: .N, }, nil}// MarshalPKCS1PublicKey converts an [RSA] public key to PKCS #1, ASN.1 DER form.//// This kind of key is commonly encoded in PEM blocks of type "RSA PUBLIC KEY".func ( *rsa.PublicKey) []byte { , := asn1.Marshal(pkcs1PublicKey{N: .N,E: .E, })return}
The pages are generated with Goldsv0.7.3-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.