package x509
import (
cryptobyte_asn1
)
func ( byte) bool {
return 'a' <= && <= 'z' ||
'A' <= && <= 'Z' ||
'0' <= && <= '9' ||
'\'' <= && <= ')' ||
'+' <= && <= '/' ||
== ' ' ||
== ':' ||
== '=' ||
== '?' ||
== '*' ||
== '&'
}
func ( cryptobyte_asn1.Tag, []byte) (string, error) {
switch {
case cryptobyte_asn1.T61String:
return string(), nil
case cryptobyte_asn1.PrintableString:
for , := range {
if !isPrintable() {
return "", errors.New("invalid PrintableString")
}
}
return string(), nil
case cryptobyte_asn1.UTF8String:
if !utf8.Valid() {
return "", errors.New("invalid UTF-8 string")
}
return string(), nil
case cryptobyte_asn1.Tag(asn1.TagBMPString):
if len()%2 != 0 {
return "", errors.New("invalid BMPString")
}
if := len(); >= 2 && [-1] == 0 && [-2] == 0 {
= [:-2]
}
:= make([]uint16, 0, len()/2)
for len() > 0 {
= append(, uint16([0])<<8+uint16([1]))
= [2:]
}
return string(utf16.Decode()), nil
case cryptobyte_asn1.IA5String:
:= string()
if isIA5String() != nil {
return "", errors.New("invalid IA5String")
}
return , nil
case cryptobyte_asn1.Tag(asn1.TagNumericString):
for , := range {
if !('0' <= && <= '9' || == ' ') {
return "", errors.New("invalid NumericString")
}
}
return string(), nil
}
return "", fmt.Errorf("unsupported string type: %v", )
}
func ( cryptobyte.String) (*pkix.RDNSequence, error) {
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: invalid RDNSequence")
}
var pkix.RDNSequence
for !.Empty() {
var pkix.RelativeDistinguishedNameSET
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SET) {
return nil, errors.New("x509: invalid RDNSequence")
}
for !.Empty() {
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: invalid RDNSequence: invalid attribute")
}
var pkix.AttributeTypeAndValue
if !.ReadASN1ObjectIdentifier(&.Type) {
return nil, errors.New("x509: invalid RDNSequence: invalid attribute type")
}
var cryptobyte.String
var cryptobyte_asn1.Tag
if !.ReadAnyASN1(&, &) {
return nil, errors.New("x509: invalid RDNSequence: invalid attribute value")
}
var error
.Value, = parseASN1String(, )
if != nil {
return nil, fmt.Errorf("x509: invalid RDNSequence: invalid attribute value: %s", )
}
= append(, )
}
= append(, )
}
return &, nil
}
func ( cryptobyte.String) (pkix.AlgorithmIdentifier, error) {
:= pkix.AlgorithmIdentifier{}
if !.ReadASN1ObjectIdentifier(&.Algorithm) {
return , errors.New("x509: malformed OID")
}
if .Empty() {
return , nil
}
var cryptobyte.String
var cryptobyte_asn1.Tag
if !.ReadAnyASN1Element(&, &) {
return , errors.New("x509: malformed parameters")
}
.Parameters.Tag = int()
.Parameters.FullBytes =
return , nil
}
func ( *cryptobyte.String) (time.Time, error) {
var time.Time
switch {
case .PeekASN1Tag(cryptobyte_asn1.UTCTime):
if !.ReadASN1UTCTime(&) {
return , errors.New("x509: malformed UTCTime")
}
case .PeekASN1Tag(cryptobyte_asn1.GeneralizedTime):
if !.ReadASN1GeneralizedTime(&) {
return , errors.New("x509: malformed GeneralizedTime")
}
default:
return , errors.New("x509: unsupported time format")
}
return , nil
}
func ( cryptobyte.String) (time.Time, time.Time, error) {
, := parseTime(&)
if != nil {
return time.Time{}, time.Time{},
}
, := parseTime(&)
if != nil {
return time.Time{}, time.Time{},
}
return , , nil
}
func ( cryptobyte.String) (pkix.Extension, error) {
var pkix.Extension
if !.ReadASN1ObjectIdentifier(&.Id) {
return , errors.New("x509: malformed extension OID field")
}
if .PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
if !.ReadASN1Boolean(&.Critical) {
return , errors.New("x509: malformed extension critical field")
}
}
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.OCTET_STRING) {
return , errors.New("x509: malformed extension value field")
}
.Value =
return , nil
}
func ( *publicKeyInfo) (any, error) {
:= .Algorithm.Algorithm
:= .Algorithm.Parameters
:= cryptobyte.String(.PublicKey.RightAlign())
switch {
case .Equal(oidPublicKeyRSA):
if !bytes.Equal(.FullBytes, asn1.NullBytes) {
return nil, errors.New("x509: RSA key missing NULL parameters")
}
:= &pkcs1PublicKey{N: new(big.Int)}
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: invalid RSA public key")
}
if !.ReadASN1Integer(.N) {
return nil, errors.New("x509: invalid RSA modulus")
}
if !.ReadASN1Integer(&.E) {
return nil, errors.New("x509: invalid RSA public exponent")
}
if .N.Sign() <= 0 {
return nil, errors.New("x509: RSA modulus is not a positive number")
}
if .E <= 0 {
return nil, errors.New("x509: RSA public exponent is not a positive number")
}
:= &rsa.PublicKey{
E: .E,
N: .N,
}
return , nil
case .Equal(oidPublicKeyECDSA):
:= cryptobyte.String(.FullBytes)
:= new(asn1.ObjectIdentifier)
if !.ReadASN1ObjectIdentifier() {
return nil, errors.New("x509: invalid ECDSA parameters")
}
:= namedCurveFromOID(*)
if == nil {
return nil, errors.New("x509: unsupported elliptic curve")
}
, := elliptic.Unmarshal(, )
if == nil {
return nil, errors.New("x509: failed to unmarshal elliptic curve point")
}
:= &ecdsa.PublicKey{
Curve: ,
X: ,
Y: ,
}
return , nil
case .Equal(oidPublicKeyEd25519):
if len(.FullBytes) != 0 {
return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
}
if len() != ed25519.PublicKeySize {
return nil, errors.New("x509: wrong Ed25519 public key size")
}
return ed25519.PublicKey(), nil
case .Equal(oidPublicKeyX25519):
if len(.FullBytes) != 0 {
return nil, errors.New("x509: X25519 key encoded with illegal parameters")
}
return ecdh.X25519().NewPublicKey()
case .Equal(oidPublicKeyDSA):
:= new(big.Int)
if !.ReadASN1Integer() {
return nil, errors.New("x509: invalid DSA public key")
}
:= &dsa.PublicKey{
Y: ,
Parameters: dsa.Parameters{
P: new(big.Int),
Q: new(big.Int),
G: new(big.Int),
},
}
:= cryptobyte.String(.FullBytes)
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) ||
!.ReadASN1Integer(.Parameters.P) ||
!.ReadASN1Integer(.Parameters.Q) ||
!.ReadASN1Integer(.Parameters.G) {
return nil, errors.New("x509: invalid DSA parameters")
}
if .Y.Sign() <= 0 || .Parameters.P.Sign() <= 0 ||
.Parameters.Q.Sign() <= 0 || .Parameters.G.Sign() <= 0 {
return nil, errors.New("x509: zero or negative DSA parameter")
}
return , nil
default:
return nil, errors.New("x509: unknown public key algorithm")
}
}
func ( cryptobyte.String) (KeyUsage, error) {
var asn1.BitString
if !.ReadASN1BitString(&) {
return 0, errors.New("x509: invalid key usage")
}
var int
for := 0; < 9; ++ {
if .At() != 0 {
|= 1 << uint()
}
}
return KeyUsage(), nil
}
func ( cryptobyte.String) (bool, int, error) {
var bool
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return false, 0, errors.New("x509: invalid basic constraints")
}
if .PeekASN1Tag(cryptobyte_asn1.BOOLEAN) {
if !.ReadASN1Boolean(&) {
return false, 0, errors.New("x509: invalid basic constraints")
}
}
:= -1
if .PeekASN1Tag(cryptobyte_asn1.INTEGER) {
if !.ReadASN1Integer(&) {
return false, 0, errors.New("x509: invalid basic constraints")
}
}
return , , nil
}
func ( cryptobyte.String, func( int, []byte) error) error {
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return errors.New("x509: invalid subject alternative names")
}
for !.Empty() {
var cryptobyte.String
var cryptobyte_asn1.Tag
if !.ReadAnyASN1(&, &) {
return errors.New("x509: invalid subject alternative name")
}
if := (int(^0x80), ); != nil {
return
}
}
return nil
}
func ( cryptobyte.String) (, []string, []net.IP, []*url.URL, error) {
= forEachSAN(, func( int, []byte) error {
switch {
case nameTypeEmail:
:= string()
if := isIA5String(); != nil {
return errors.New("x509: SAN rfc822Name is malformed")
}
= append(, )
case nameTypeDNS:
:= string()
if := isIA5String(); != nil {
return errors.New("x509: SAN dNSName is malformed")
}
= append(, string())
case nameTypeURI:
:= string()
if := isIA5String(); != nil {
return errors.New("x509: SAN uniformResourceIdentifier is malformed")
}
, := url.Parse()
if != nil {
return fmt.Errorf("x509: cannot parse URI %q: %s", , )
}
if len(.Host) > 0 {
if , := domainToReverseLabels(.Host); ! {
return fmt.Errorf("x509: cannot parse URI %q: invalid domain", )
}
}
= append(, )
case nameTypeIP:
switch len() {
case net.IPv4len, net.IPv6len:
= append(, )
default:
return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len()))
}
}
return nil
})
return
}
func ( pkix.Extension) ([]byte, error) {
if .Critical {
return nil, errors.New("x509: authority key identifier incorrectly marked critical")
}
:= cryptobyte.String(.Value)
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: invalid authority key identifier")
}
if .PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
if !.ReadASN1(&, cryptobyte_asn1.Tag(0).ContextSpecific()) {
return nil, errors.New("x509: invalid authority key identifier")
}
return , nil
}
return nil, nil
}
func ( cryptobyte.String) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
var []ExtKeyUsage
var []asn1.ObjectIdentifier
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, nil, errors.New("x509: invalid extended key usages")
}
for !.Empty() {
var asn1.ObjectIdentifier
if !.ReadASN1ObjectIdentifier(&) {
return nil, nil, errors.New("x509: invalid extended key usages")
}
if , := extKeyUsageFromOID(); {
= append(, )
} else {
= append(, )
}
}
return , , nil
}
func ( cryptobyte.String) ([]OID, error) {
var []OID
:= map[string]bool{}
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: invalid certificate policies")
}
for !.Empty() {
var cryptobyte.String
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) || !.ReadASN1(&, cryptobyte_asn1.OBJECT_IDENTIFIER) {
return nil, errors.New("x509: invalid certificate policies")
}
if [string()] {
return nil, errors.New("x509: invalid certificate policies")
}
[string()] = true
, := newOIDFromDER()
if ! {
return nil, errors.New("x509: invalid certificate policies")
}
= append(, )
}
return , nil
}
func ( []byte) bool {
:= false
for , := range {
if {
if != 0 {
return false
}
continue
}
switch {
case 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe:
= true
case 0xff:
default:
return false
}
}
return true
}
func ( *Certificate, pkix.Extension) ( bool, error) {
:= cryptobyte.String(.Value)
var , , cryptobyte.String
var , bool
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) ||
!.Empty() ||
!.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
!.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
!.Empty() {
return false, errors.New("x509: invalid NameConstraints extension")
}
if ! && ! || len() == 0 && len() == 0 {
return false, errors.New("x509: empty name constraints extension")
}
:= func( cryptobyte.String) ( []string, []*net.IPNet, , []string, error) {
for !.Empty() {
var , cryptobyte.String
var cryptobyte_asn1.Tag
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) ||
!.ReadAnyASN1(&, &) {
return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
}
var (
= cryptobyte_asn1.Tag(2).ContextSpecific()
= cryptobyte_asn1.Tag(1).ContextSpecific()
= cryptobyte_asn1.Tag(7).ContextSpecific()
= cryptobyte_asn1.Tag(6).ContextSpecific()
)
switch {
case :
:= string()
if := isIA5String(); != nil {
return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error())
}
:=
if len() > 0 && [0] == '.' {
= [1:]
}
if , := domainToReverseLabels(); ! {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", )
}
= append(, )
case :
:= len()
var , []byte
switch {
case 8:
= [:4]
= [4:]
case 32:
= [:16]
= [16:]
default:
return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", )
}
if !isValidIPMask() {
return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", )
}
= append(, &net.IPNet{IP: net.IP(), Mask: net.IPMask()})
case :
:= string()
if := isIA5String(); != nil {
return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error())
}
if strings.Contains(, "@") {
if , := parseRFC2821Mailbox(); ! {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", )
}
} else {
:=
if len() > 0 && [0] == '.' {
= [1:]
}
if , := domainToReverseLabels(); ! {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", )
}
}
= append(, )
case :
:= string()
if := isIA5String(); != nil {
return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error())
}
if net.ParseIP() != nil {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", )
}
:=
if len() > 0 && [0] == '.' {
= [1:]
}
if , := domainToReverseLabels(); ! {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", )
}
= append(, )
default:
= true
}
}
return , , , , nil
}
if .PermittedDNSDomains, .PermittedIPRanges, .PermittedEmailAddresses, .PermittedURIDomains, = (); != nil {
return false,
}
if .ExcludedDNSDomains, .ExcludedIPRanges, .ExcludedEmailAddresses, .ExcludedURIDomains, = (); != nil {
return false,
}
.PermittedDNSDomainsCritical = .Critical
return , nil
}
func ( *Certificate) error {
var error
for , := range .Extensions {
:= false
if len(.Id) == 4 && .Id[0] == 2 && .Id[1] == 5 && .Id[2] == 29 {
switch .Id[3] {
case 15:
.KeyUsage, = parseKeyUsageExtension(.Value)
if != nil {
return
}
case 19:
.IsCA, .MaxPathLen, = parseBasicConstraintsExtension(.Value)
if != nil {
return
}
.BasicConstraintsValid = true
.MaxPathLenZero = .MaxPathLen == 0
case 17:
.DNSNames, .EmailAddresses, .IPAddresses, .URIs, = parseSANExtension(.Value)
if != nil {
return
}
if len(.DNSNames) == 0 && len(.EmailAddresses) == 0 && len(.IPAddresses) == 0 && len(.URIs) == 0 {
= true
}
case 30:
, = parseNameConstraintsExtension(, )
if != nil {
return
}
case 31:
:= cryptobyte.String(.Value)
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return errors.New("x509: invalid CRL distribution points")
}
for !.Empty() {
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return errors.New("x509: invalid CRL distribution point")
}
var cryptobyte.String
var bool
if !.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
return errors.New("x509: invalid CRL distribution point")
}
if ! {
continue
}
if !.ReadASN1(&, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
return errors.New("x509: invalid CRL distribution point")
}
for !.Empty() {
if !.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
break
}
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.Tag(6).ContextSpecific()) {
return errors.New("x509: invalid CRL distribution point")
}
.CRLDistributionPoints = append(.CRLDistributionPoints, string())
}
}
case 35:
.AuthorityKeyId, = parseAuthorityKeyIdentifier()
if != nil {
return
}
case 36:
:= cryptobyte.String(.Value)
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return errors.New("x509: invalid policy constraints extension")
}
if .PeekASN1Tag(cryptobyte_asn1.Tag(0).ContextSpecific()) {
var int64
if !.ReadASN1Int64WithTag(&, cryptobyte_asn1.Tag(0).ContextSpecific()) {
return errors.New("x509: invalid policy constraints extension")
}
.RequireExplicitPolicy = int()
if int64(.RequireExplicitPolicy) != {
return errors.New("x509: policy constraints requireExplicitPolicy field overflows int")
}
.RequireExplicitPolicyZero = .RequireExplicitPolicy == 0
}
if .PeekASN1Tag(cryptobyte_asn1.Tag(1).ContextSpecific()) {
var int64
if !.ReadASN1Int64WithTag(&, cryptobyte_asn1.Tag(1).ContextSpecific()) {
return errors.New("x509: invalid policy constraints extension")
}
.InhibitPolicyMapping = int()
if int64(.InhibitPolicyMapping) != {
return errors.New("x509: policy constraints inhibitPolicyMapping field overflows int")
}
.InhibitPolicyMappingZero = .InhibitPolicyMapping == 0
}
case 37:
.ExtKeyUsage, .UnknownExtKeyUsage, = parseExtKeyUsageExtension(.Value)
if != nil {
return
}
case 14:
if .Critical {
return errors.New("x509: subject key identifier incorrectly marked critical")
}
:= cryptobyte.String(.Value)
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.OCTET_STRING) {
return errors.New("x509: invalid subject key identifier")
}
.SubjectKeyId =
case 32:
.Policies, = parseCertificatePoliciesExtension(.Value)
if != nil {
return
}
.PolicyIdentifiers = make([]asn1.ObjectIdentifier, 0, len(.Policies))
for , := range .Policies {
if , := .toASN1OID(); {
.PolicyIdentifiers = append(.PolicyIdentifiers, )
}
}
case 33:
:= cryptobyte.String(.Value)
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return errors.New("x509: invalid policy mappings extension")
}
for !.Empty() {
var cryptobyte.String
var , cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) ||
!.ReadASN1(&, cryptobyte_asn1.OBJECT_IDENTIFIER) ||
!.ReadASN1(&, cryptobyte_asn1.OBJECT_IDENTIFIER) {
return errors.New("x509: invalid policy mappings extension")
}
.PolicyMappings = append(.PolicyMappings, PolicyMapping{OID{}, OID{}})
}
case 54:
:= cryptobyte.String(.Value)
if !.ReadASN1Integer(&.InhibitAnyPolicy) {
return errors.New("x509: invalid inhibit any policy extension")
}
.InhibitAnyPolicyZero = .InhibitAnyPolicy == 0
default:
= true
}
} else if .Id.Equal(oidExtensionAuthorityInfoAccess) {
if .Critical {
return errors.New("x509: authority info access incorrectly marked critical")
}
:= cryptobyte.String(.Value)
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return errors.New("x509: invalid authority info access")
}
for !.Empty() {
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return errors.New("x509: invalid authority info access")
}
var asn1.ObjectIdentifier
if !.ReadASN1ObjectIdentifier(&) {
return errors.New("x509: invalid authority info access")
}
if !.PeekASN1Tag(cryptobyte_asn1.Tag(6).ContextSpecific()) {
continue
}
if !.ReadASN1(&, cryptobyte_asn1.Tag(6).ContextSpecific()) {
return errors.New("x509: invalid authority info access")
}
switch {
case .Equal(oidAuthorityInfoAccessOcsp):
.OCSPServer = append(.OCSPServer, string())
case .Equal(oidAuthorityInfoAccessIssuers):
.IssuingCertificateURL = append(.IssuingCertificateURL, string())
}
}
} else {
= true
}
if .Critical && {
.UnhandledCriticalExtensions = append(.UnhandledCriticalExtensions, .Id)
}
}
return nil
}
var x509negativeserial = godebug.New("x509negativeserial")
func ( []byte) (*Certificate, error) {
:= &Certificate{}
:= cryptobyte.String()
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed certificate")
}
.Raw =
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed certificate")
}
var cryptobyte.String
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed tbs certificate")
}
.RawTBSCertificate =
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed tbs certificate")
}
if !.ReadOptionalASN1Integer(&.Version, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific(), 0) {
return nil, errors.New("x509: malformed version")
}
if .Version < 0 {
return nil, errors.New("x509: malformed version")
}
.Version++
if .Version > 3 {
return nil, errors.New("x509: invalid version")
}
:= new(big.Int)
if !.ReadASN1Integer() {
return nil, errors.New("x509: malformed serial number")
}
if .Sign() == -1 {
if x509negativeserial.Value() != "1" {
return nil, errors.New("x509: negative serial number")
} else {
x509negativeserial.IncNonDefault()
}
}
.SerialNumber =
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed signature algorithm identifier")
}
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed algorithm identifier")
}
if !bytes.Equal(, ) {
return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
}
, := parseAI()
if != nil {
return nil,
}
.SignatureAlgorithm = getSignatureAlgorithmFromAI()
var cryptobyte.String
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed issuer")
}
.RawIssuer =
, := parseName()
if != nil {
return nil,
}
.Issuer.FillFromRDNSequence()
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed validity")
}
.NotBefore, .NotAfter, = parseValidity()
if != nil {
return nil,
}
var cryptobyte.String
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed issuer")
}
.RawSubject =
, := parseName()
if != nil {
return nil,
}
.Subject.FillFromRDNSequence()
var cryptobyte.String
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed spki")
}
.RawSubjectPublicKeyInfo =
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed spki")
}
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed public key algorithm identifier")
}
, := parseAI()
if != nil {
return nil,
}
.PublicKeyAlgorithm = getPublicKeyAlgorithmFromOID(.Algorithm)
var asn1.BitString
if !.ReadASN1BitString(&) {
return nil, errors.New("x509: malformed subjectPublicKey")
}
if .PublicKeyAlgorithm != UnknownPublicKeyAlgorithm {
.PublicKey, = parsePublicKey(&publicKeyInfo{
Algorithm: ,
PublicKey: ,
})
if != nil {
return nil,
}
}
if .Version > 1 {
if !.SkipOptionalASN1(cryptobyte_asn1.Tag(1).ContextSpecific()) {
return nil, errors.New("x509: malformed issuerUniqueID")
}
if !.SkipOptionalASN1(cryptobyte_asn1.Tag(2).ContextSpecific()) {
return nil, errors.New("x509: malformed subjectUniqueID")
}
if .Version == 3 {
var cryptobyte.String
var bool
if !.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(3).Constructed().ContextSpecific()) {
return nil, errors.New("x509: malformed extensions")
}
if {
:= make(map[string]bool)
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed extensions")
}
for !.Empty() {
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed extension")
}
, := parseExtension()
if != nil {
return nil,
}
:= .Id.String()
if [] {
return nil, fmt.Errorf("x509: certificate contains duplicate extension with OID %q", )
}
[] = true
.Extensions = append(.Extensions, )
}
= processExtensions()
if != nil {
return nil,
}
}
}
}
var asn1.BitString
if !.ReadASN1BitString(&) {
return nil, errors.New("x509: malformed signature")
}
.Signature = .RightAlign()
return , nil
}
func ( []byte) (*Certificate, error) {
, := parseCertificate()
if != nil {
return nil,
}
if len() != len(.Raw) {
return nil, errors.New("x509: trailing data")
}
return ,
}
func ( []byte) ([]*Certificate, error) {
var []*Certificate
for len() > 0 {
, := parseCertificate()
if != nil {
return nil,
}
= append(, )
= [len(.Raw):]
}
return , nil
}
const x509v2Version = 1
func ( []byte) (*RevocationList, error) {
:= &RevocationList{}
:= cryptobyte.String()
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed crl")
}
.Raw =
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed crl")
}
var cryptobyte.String
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed tbs crl")
}
.RawTBSRevocationList =
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed tbs crl")
}
var int
if !.PeekASN1Tag(cryptobyte_asn1.INTEGER) {
return nil, errors.New("x509: unsupported crl version")
}
if !.ReadASN1Integer(&) {
return nil, errors.New("x509: malformed crl")
}
if != x509v2Version {
return nil, fmt.Errorf("x509: unsupported crl version: %d", )
}
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed signature algorithm identifier")
}
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed algorithm identifier")
}
if !bytes.Equal(, ) {
return nil, errors.New("x509: inner and outer signature algorithm identifiers don't match")
}
, := parseAI()
if != nil {
return nil,
}
.SignatureAlgorithm = getSignatureAlgorithmFromAI()
var asn1.BitString
if !.ReadASN1BitString(&) {
return nil, errors.New("x509: malformed signature")
}
.Signature = .RightAlign()
var cryptobyte.String
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed issuer")
}
.RawIssuer =
, := parseName()
if != nil {
return nil,
}
.Issuer.FillFromRDNSequence()
.ThisUpdate, = parseTime(&)
if != nil {
return nil,
}
if .PeekASN1Tag(cryptobyte_asn1.GeneralizedTime) || .PeekASN1Tag(cryptobyte_asn1.UTCTime) {
.NextUpdate, = parseTime(&)
if != nil {
return nil,
}
}
if .PeekASN1Tag(cryptobyte_asn1.SEQUENCE) {
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed crl")
}
for !.Empty() {
:= RevocationListEntry{}
var cryptobyte.String
if !.ReadASN1Element(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed crl")
}
.Raw =
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed crl")
}
.SerialNumber = new(big.Int)
if !.ReadASN1Integer(.SerialNumber) {
return nil, errors.New("x509: malformed serial number")
}
.RevocationTime, = parseTime(&)
if != nil {
return nil,
}
var cryptobyte.String
var bool
if !.ReadOptionalASN1(&, &, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed extensions")
}
if {
for !.Empty() {
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed extension")
}
, := parseExtension()
if != nil {
return nil,
}
if .Id.Equal(oidExtensionReasonCode) {
:= cryptobyte.String(.Value)
if !.ReadASN1Enum(&.ReasonCode) {
return nil, fmt.Errorf("x509: malformed reasonCode extension")
}
}
.Extensions = append(.Extensions, )
}
}
.RevokedCertificateEntries = append(.RevokedCertificateEntries, )
:= pkix.RevokedCertificate{
SerialNumber: .SerialNumber,
RevocationTime: .RevocationTime,
Extensions: .Extensions,
}
.RevokedCertificates = append(.RevokedCertificates, )
}
}
var cryptobyte.String
var bool
if !.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(0).Constructed().ContextSpecific()) {
return nil, errors.New("x509: malformed extensions")
}
if {
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed extensions")
}
for !.Empty() {
var cryptobyte.String
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) {
return nil, errors.New("x509: malformed extension")
}
, := parseExtension()
if != nil {
return nil,
}
if .Id.Equal(oidExtensionAuthorityKeyId) {
.AuthorityKeyId, = parseAuthorityKeyIdentifier()
if != nil {
return nil,
}
} else if .Id.Equal(oidExtensionCRLNumber) {
:= cryptobyte.String(.Value)
.Number = new(big.Int)
if !.ReadASN1Integer(.Number) {
return nil, errors.New("x509: malformed crl number")
}
}
.Extensions = append(.Extensions, )
}
}
return , nil
}