Ensure errors are handled or logged
if err != nil {
1// Copyright 2009 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45// Package x509 implements a subset of the X.509 standard.6//7// It allows parsing and generating certificates, certificate signing8// requests, certificate revocation lists, and encoded public and private keys.9// It provides a certificate verifier, complete with a chain builder.10//11// The package targets the X.509 technical profile defined by the IETF (RFC12// 2459/3280/5280), and as further restricted by the CA/Browser Forum Baseline13// Requirements. There is minimal support for features outside of these14// profiles, as the primary goal of the package is to provide compatibility15// with the publicly trusted TLS certificate ecosystem and its policies and16// constraints.17//18// On macOS and Windows, certificate verification is handled by system APIs, but19// the package aims to apply consistent validation rules across operating20// systems.21package x5092223import (24 "bytes"25 "crypto"26 "crypto/ecdh"27 "crypto/ecdsa"28 "crypto/ed25519"29 "crypto/elliptic"30 "crypto/fips140"31 "crypto/mldsa"32 "crypto/rsa"33 "crypto/sha1"34 "crypto/sha256"35 "crypto/x509/pkix"36 "encoding/asn1"37 "encoding/pem"38 "errors"39 "fmt"40 "internal/godebug"41 "io"42 "math/big"43 "net"44 "net/url"45 "strconv"46 "time"47 "unicode"4849 // Explicitly import these for their crypto.RegisterHash init side-effects.50 // Keep these as blank imports, even if they're imported above.51 _ "crypto/sha1"52 _ "crypto/sha256"53 _ "crypto/sha512"5455 "golang.org/x/crypto/cryptobyte"56 cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"57)5859// pkixPublicKey reflects a PKIX public key structure. See SubjectPublicKeyInfo60// in RFC 3280.61type pkixPublicKey struct {62 Algo pkix.AlgorithmIdentifier63 BitString asn1.BitString64}6566// ParsePKIXPublicKey parses a public key in PKIX, ASN.1 DER form. The encoded67// public key is a SubjectPublicKeyInfo structure (see RFC 5280, Section 4.1).68//69// It returns a *[rsa.PublicKey], *[dsa.PublicKey], *[ecdsa.PublicKey],70// [ed25519.PublicKey] (not a pointer), *[mldsa.PublicKey], or *[ecdh.PublicKey]71// (for X25519). More types might be supported in the future.72//73// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".74func ParsePKIXPublicKey(derBytes []byte) (pub any, err error) {75 var pki publicKeyInfo76 if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil {77 if _, err := asn1.Unmarshal(derBytes, &pkcs1PublicKey{}); err == nil {78 return nil, errors.New("x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)")79 }80 return nil, err81 } else if len(rest) != 0 {82 return nil, errors.New("x509: trailing data after ASN.1 of public-key")83 }84 return parsePublicKey(&pki)85}8687func marshalPublicKey(pub any) (publicKeyBytes []byte, publicKeyAlgorithm pkix.AlgorithmIdentifier, err error) {88 switch pub := pub.(type) {89 case *rsa.PublicKey:90 publicKeyBytes, err = asn1.Marshal(pkcs1PublicKey{91 N: pub.N,92 E: pub.E,93 })94 if err != nil {95 return nil, pkix.AlgorithmIdentifier{}, err96 }97 publicKeyAlgorithm.Algorithm = oidPublicKeyRSA98 // This is a NULL parameters value which is required by99 // RFC 3279, Section 2.3.1.100 publicKeyAlgorithm.Parameters = asn1.NullRawValue101 case *ecdsa.PublicKey:102 oid, ok := oidFromNamedCurve(pub.Curve)103 if !ok {104 return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")105 }106 publicKeyBytes, err = pub.Bytes()107 if err != nil {108 return nil, pkix.AlgorithmIdentifier{}, err109 }110 publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA111 var paramBytes []byte112 paramBytes, err = asn1.Marshal(oid)113 if err != nil {114 return115 }116 publicKeyAlgorithm.Parameters.FullBytes = paramBytes117 case ed25519.PublicKey:118 publicKeyBytes = pub119 publicKeyAlgorithm.Algorithm = oidPublicKeyEd25519120 case *mldsa.PublicKey:121 oid, ok := oidFromMLDSAParameters(pub.Parameters())122 if !ok {123 return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported ML-DSA parameters")124 }125 publicKeyBytes = pub.Bytes()126 publicKeyAlgorithm.Algorithm = oid127 case *ecdh.PublicKey:128 publicKeyBytes = pub.Bytes()129 if pub.Curve() == ecdh.X25519() {130 publicKeyAlgorithm.Algorithm = oidPublicKeyX25519131 } else {132 oid, ok := oidFromECDHCurve(pub.Curve())133 if !ok {134 return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")135 }136 publicKeyAlgorithm.Algorithm = oidPublicKeyECDSA137 var paramBytes []byte138 paramBytes, err = asn1.Marshal(oid)139 if err != nil {140 return141 }142 publicKeyAlgorithm.Parameters.FullBytes = paramBytes143 }144 default:145 return nil, pkix.AlgorithmIdentifier{}, fmt.Errorf("x509: unsupported public key type: %T", pub)146 }147148 return publicKeyBytes, publicKeyAlgorithm, nil149}150151// MarshalPKIXPublicKey converts a public key to PKIX, ASN.1 DER form.152// The encoded public key is a SubjectPublicKeyInfo structure153// (see RFC 5280, Section 4.1).154//155// The following key types are currently supported: *[rsa.PublicKey],156// *[ecdsa.PublicKey], [ed25519.PublicKey] (not a pointer), *[mldsa.PublicKey],157// and *[ecdh.PublicKey]. Unsupported key types result in an error.158//159// This kind of key is commonly encoded in PEM blocks of type "PUBLIC KEY".160func MarshalPKIXPublicKey(pub any) ([]byte, error) {161 var publicKeyBytes []byte162 var publicKeyAlgorithm pkix.AlgorithmIdentifier163 var err error164165 if publicKeyBytes, publicKeyAlgorithm, err = marshalPublicKey(pub); err != nil {166 return nil, err167 }168169 pkix := pkixPublicKey{170 Algo: publicKeyAlgorithm,171 BitString: asn1.BitString{172 Bytes: publicKeyBytes,173 BitLength: 8 * len(publicKeyBytes),174 },175 }176177 ret, _ := asn1.Marshal(pkix)178 return ret, nil179}180181// These structures reflect the ASN.1 structure of X.509 certificates.:182183type certificate struct {184 TBSCertificate tbsCertificate185 SignatureAlgorithm pkix.AlgorithmIdentifier186 SignatureValue asn1.BitString187}188189type tbsCertificate struct {190 Raw asn1.RawContent191 Version int `asn1:"optional,explicit,default:0,tag:0"`192 SerialNumber *big.Int193 SignatureAlgorithm pkix.AlgorithmIdentifier194 Issuer asn1.RawValue195 Validity validity196 Subject asn1.RawValue197 PublicKey publicKeyInfo198 UniqueId asn1.BitString `asn1:"optional,tag:1"`199 SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`200 Extensions []pkix.Extension `asn1:"omitempty,optional,explicit,tag:3"`201}202203type dsaAlgorithmParameters struct {204 P, Q, G *big.Int205}206207type validity struct {208 NotBefore, NotAfter time.Time209}210211type publicKeyInfo struct {212 Raw asn1.RawContent213 Algorithm pkix.AlgorithmIdentifier214 PublicKey asn1.BitString215}216217// RFC 5280, 4.2.1.1218type authKeyId struct {219 Id []byte `asn1:"optional,tag:0"`220}221222type SignatureAlgorithm int223224const (225 UnknownSignatureAlgorithm SignatureAlgorithm = iota226227 MD2WithRSA // Unsupported.228 MD5WithRSA // Only supported for signing, not verification.229 SHA1WithRSA // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.230 SHA256WithRSA231 SHA384WithRSA232 SHA512WithRSA233 DSAWithSHA1 // Unsupported.234 DSAWithSHA256 // Unsupported.235 ECDSAWithSHA1 // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.236 ECDSAWithSHA256237 ECDSAWithSHA384238 ECDSAWithSHA512239 SHA256WithRSAPSS240 SHA384WithRSAPSS241 SHA512WithRSAPSS242 PureEd25519243 MLDSA44244 MLDSA65245 MLDSA87246)247248func (algo SignatureAlgorithm) isRSAPSS() bool {249 for _, details := range signatureAlgorithmDetails {250 if details.algo == algo {251 return details.isRSAPSS252 }253 }254 return false255}256257func (algo SignatureAlgorithm) hashFunc() crypto.Hash {258 for _, details := range signatureAlgorithmDetails {259 if details.algo == algo {260 return details.hash261 }262 }263 return crypto.Hash(0)264}265266func (algo SignatureAlgorithm) String() string {267 for _, details := range signatureAlgorithmDetails {268 if details.algo == algo {269 return details.name270 }271 }272 return strconv.Itoa(int(algo))273}274275type PublicKeyAlgorithm int276277const (278 UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota279 RSA280 DSA // Only supported for parsing.281 ECDSA282 Ed25519283 MLDSA284)285286var publicKeyAlgoName = [...]string{287 RSA: "RSA",288 DSA: "DSA",289 ECDSA: "ECDSA",290 Ed25519: "Ed25519",291 MLDSA: "ML-DSA",292}293294func (algo PublicKeyAlgorithm) String() string {295 if 0 < algo && int(algo) < len(publicKeyAlgoName) {296 return publicKeyAlgoName[algo]297 }298 return strconv.Itoa(int(algo))299}300301// OIDs for signature algorithms302//303// pkcs-1 OBJECT IDENTIFIER ::= {304// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }305//306// RFC 3279 2.2.1 RSA Signature Algorithms307//308// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }309//310// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }311//312// dsaWithSha1 OBJECT IDENTIFIER ::= {313// iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }314//315// RFC 3279 2.2.3 ECDSA Signature Algorithm316//317// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {318// iso(1) member-body(2) us(840) ansi-x962(10045)319// signatures(4) ecdsa-with-SHA1(1)}320//321// RFC 4055 5 PKCS #1 Version 1.5322//323// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }324//325// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }326//327// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }328//329// RFC 5758 3.1 DSA Signature Algorithms330//331// dsaWithSha256 OBJECT IDENTIFIER ::= {332// joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)333// csor(3) algorithms(4) id-dsa-with-sha2(3) 2}334//335// RFC 5758 3.2 ECDSA Signature Algorithm336//337// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)338// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }339//340// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)341// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }342//343// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)344// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }345//346// RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers347//348// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }349var (350 oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}351 oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}352 oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}353 oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}354 oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}355 oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}356 oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}357 oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}358 oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}359 oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}360 oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}361 oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}362 oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}363364 oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}365 oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}366 oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}367368 oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8}369370 // oidISOSignatureSHA1WithRSA means the same as oidSignatureSHA1WithRSA371 // but it's specified by ISO. Microsoft's makecert.exe has been known372 // to produce certificates with this OID.373 oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}374)375376var signatureAlgorithmDetails = []struct {377 algo SignatureAlgorithm378 name string379 oid asn1.ObjectIdentifier380 params asn1.RawValue381 pubKeyAlgo PublicKeyAlgorithm382 hash crypto.Hash383 isRSAPSS bool384}{385 {MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, asn1.NullRawValue, RSA, crypto.MD5, false},386 {SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},387 {SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},388 {SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, asn1.NullRawValue, RSA, crypto.SHA256, false},389 {SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, asn1.NullRawValue, RSA, crypto.SHA384, false},390 {SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, asn1.NullRawValue, RSA, crypto.SHA512, false},391 {SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, pssParametersSHA256, RSA, crypto.SHA256, true},392 {SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, pssParametersSHA384, RSA, crypto.SHA384, true},393 {SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, pssParametersSHA512, RSA, crypto.SHA512, true},394 {DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, emptyRawValue, DSA, crypto.SHA1, false},395 {DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, emptyRawValue, DSA, crypto.SHA256, false},396 {ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, emptyRawValue, ECDSA, crypto.SHA1, false},397 {ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, emptyRawValue, ECDSA, crypto.SHA256, false},398 {ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, emptyRawValue, ECDSA, crypto.SHA384, false},399 {ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, emptyRawValue, ECDSA, crypto.SHA512, false},400 {PureEd25519, "Ed25519", oidSignatureEd25519, emptyRawValue, Ed25519, crypto.Hash(0) /* no pre-hashing */, false},401 {MLDSA44, "ML-DSA-44", oidPublicKeyMLDSA44, emptyRawValue, MLDSA, crypto.Hash(0) /* no pre-hashing */, false},402 {MLDSA65, "ML-DSA-65", oidPublicKeyMLDSA65, emptyRawValue, MLDSA, crypto.Hash(0) /* no pre-hashing */, false},403 {MLDSA87, "ML-DSA-87", oidPublicKeyMLDSA87, emptyRawValue, MLDSA, crypto.Hash(0) /* no pre-hashing */, false},404}405406var emptyRawValue = asn1.RawValue{}407408// DER encoded RSA PSS parameters for the409// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.410// The parameters contain the following values:411// - hashAlgorithm contains the associated hash identifier with NULL parameters412// - maskGenAlgorithm always contains the default mgf1SHA1 identifier413// - saltLength contains the length of the associated hash414// - trailerField always contains the default trailerFieldBC value415var (416 pssParametersSHA256 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 1, 5, 0, 162, 3, 2, 1, 32}}417 pssParametersSHA384 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 2, 5, 0, 162, 3, 2, 1, 48}}418 pssParametersSHA512 = asn1.RawValue{FullBytes: []byte{48, 52, 160, 15, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 161, 28, 48, 26, 6, 9, 42, 134, 72, 134, 247, 13, 1, 1, 8, 48, 13, 6, 9, 96, 134, 72, 1, 101, 3, 4, 2, 3, 5, 0, 162, 3, 2, 1, 64}}419)420421// pssParameters reflects the parameters in an AlgorithmIdentifier that422// specifies RSA PSS. See RFC 3447, Appendix A.2.3.423type pssParameters struct {424 // The following three fields are not marked as425 // optional because the default values specify SHA-1,426 // which is no longer suitable for use in signatures.427 Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"`428 MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"`429 SaltLength int `asn1:"explicit,tag:2"`430 TrailerField int `asn1:"optional,explicit,tag:3,default:1"`431}432433func getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) SignatureAlgorithm {434 if ai.Algorithm.Equal(oidSignatureEd25519) ||435 ai.Algorithm.Equal(oidPublicKeyMLDSA44) ||436 ai.Algorithm.Equal(oidPublicKeyMLDSA65) ||437 ai.Algorithm.Equal(oidPublicKeyMLDSA87) {438 // RFC 8410, Section 3439 // > For all of the OIDs, the parameters MUST be absent.440 // RFC 9881, Section 2441 // > The contents of the parameters component for each algorithm MUST be absent.442 if len(ai.Parameters.FullBytes) != 0 {443 return UnknownSignatureAlgorithm444 }445 }446447 if !ai.Algorithm.Equal(oidSignatureRSAPSS) {448 for _, details := range signatureAlgorithmDetails {449 if ai.Algorithm.Equal(details.oid) {450 return details.algo451 }452 }453 return UnknownSignatureAlgorithm454 }455456 // RSA PSS is special because it encodes important parameters457 // in the Parameters.458459 var params pssParameters460 if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, ¶ms); err != nil {461 return UnknownSignatureAlgorithm462 }463464 var mgf1HashFunc pkix.AlgorithmIdentifier465 if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {466 return UnknownSignatureAlgorithm467 }468469 // PSS is greatly overburdened with options. This code forces them into470 // three buckets by requiring that the MGF1 hash function always match the471 // message hash function (as recommended in RFC 3447, Section 8.1), that the472 // salt length matches the hash length, and that the trailer field has the473 // default value.474 if (len(params.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes)) ||475 !params.MGF.Algorithm.Equal(oidMGF1) ||476 !mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||477 (len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||478 params.TrailerField != 1 {479 return UnknownSignatureAlgorithm480 }481482 switch {483 case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:484 return SHA256WithRSAPSS485 case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:486 return SHA384WithRSAPSS487 case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:488 return SHA512WithRSAPSS489 }490491 return UnknownSignatureAlgorithm492}493494var (495 // RFC 3279, 2.3 Public Key Algorithms496 //497 // pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)498 // rsadsi(113549) pkcs(1) 1 }499 //500 // rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }501 //502 // id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)503 // x9-57(10040) x9cm(4) 1 }504 oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}505 oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}506 // RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters507 //508 // id-ecPublicKey OBJECT IDENTIFIER ::= {509 // iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }510 oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}511 // RFC 8410, Section 3512 //513 // id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }514 // id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }515 oidPublicKeyX25519 = asn1.ObjectIdentifier{1, 3, 101, 110}516 oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}517 // RFC 9881, Section 2518 //519 // id-ml-dsa-44 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2)520 // country(16) us(840) organization(1) gov(101) csor(3)521 // nistAlgorithm(4) sigAlgs(3) id-ml-dsa-44(17) }522 //523 // id-ml-dsa-65 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2)524 // country(16) us(840) organization(1) gov(101) csor(3)525 // nistAlgorithm(4) sigAlgs(3) id-ml-dsa-65(18) }526 //527 // id-ml-dsa-87 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2)528 // country(16) us(840) organization(1) gov(101) csor(3)529 // nistAlgorithm(4) sigAlgs(3) id-ml-dsa-87(19) }530 oidPublicKeyMLDSA44 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 17}531 oidPublicKeyMLDSA65 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 18}532 oidPublicKeyMLDSA87 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 19}533)534535// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm536// identifier for public key types supported in certificates and CSRs. Marshal537// and Parse functions may support a different set of public key types.538func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) PublicKeyAlgorithm {539 switch {540 case oid.Equal(oidPublicKeyRSA):541 return RSA542 case oid.Equal(oidPublicKeyDSA):543 return DSA544 case oid.Equal(oidPublicKeyECDSA):545 return ECDSA546 case oid.Equal(oidPublicKeyEd25519):547 return Ed25519548 case oid.Equal(oidPublicKeyMLDSA44),549 oid.Equal(oidPublicKeyMLDSA65),550 oid.Equal(oidPublicKeyMLDSA87):551 // ML-DSA is not available in FIPS 140-3 module v1.0.0.552 if fips140.Version() == "v1.0.0" {553 return UnknownPublicKeyAlgorithm554 }555 return MLDSA556 }557 return UnknownPublicKeyAlgorithm558}559560// RFC 5480, 2.1.1.1. Named Curve561//562// secp224r1 OBJECT IDENTIFIER ::= {563// iso(1) identified-organization(3) certicom(132) curve(0) 33 }564//565// secp256r1 OBJECT IDENTIFIER ::= {566// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)567// prime(1) 7 }568//569// secp384r1 OBJECT IDENTIFIER ::= {570// iso(1) identified-organization(3) certicom(132) curve(0) 34 }571//572// secp521r1 OBJECT IDENTIFIER ::= {573// iso(1) identified-organization(3) certicom(132) curve(0) 35 }574//575// NB: secp256r1 is equivalent to prime256v1576var (577 oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}578 oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}579 oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}580 oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}581)582583func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {584 switch {585 case oid.Equal(oidNamedCurveP224):586 return elliptic.P224()587 case oid.Equal(oidNamedCurveP256):588 return elliptic.P256()589 case oid.Equal(oidNamedCurveP384):590 return elliptic.P384()591 case oid.Equal(oidNamedCurveP521):592 return elliptic.P521()593 }594 return nil595}596597func oidFromNamedCurve(curve elliptic.Curve) (asn1.ObjectIdentifier, bool) {598 switch curve {599 case elliptic.P224():600 return oidNamedCurveP224, true601 case elliptic.P256():602 return oidNamedCurveP256, true603 case elliptic.P384():604 return oidNamedCurveP384, true605 case elliptic.P521():606 return oidNamedCurveP521, true607 }608609 return nil, false610}611612func oidFromECDHCurve(curve ecdh.Curve) (asn1.ObjectIdentifier, bool) {613 switch curve {614 case ecdh.X25519():615 return oidPublicKeyX25519, true616 case ecdh.P256():617 return oidNamedCurveP256, true618 case ecdh.P384():619 return oidNamedCurveP384, true620 case ecdh.P521():621 return oidNamedCurveP521, true622 }623624 return nil, false625}626627func mldsaParametersFromOID(oid asn1.ObjectIdentifier) (mldsa.Parameters, bool) {628 switch {629 case oid.Equal(oidPublicKeyMLDSA44):630 return mldsa.MLDSA44(), true631 case oid.Equal(oidPublicKeyMLDSA65):632 return mldsa.MLDSA65(), true633 case oid.Equal(oidPublicKeyMLDSA87):634 return mldsa.MLDSA87(), true635 }636 return mldsa.Parameters{}, false637}638639func oidFromMLDSAParameters(params mldsa.Parameters) (asn1.ObjectIdentifier, bool) {640 switch {641 case params == mldsa.MLDSA44():642 return oidPublicKeyMLDSA44, true643 case params == mldsa.MLDSA65():644 return oidPublicKeyMLDSA65, true645 case params == mldsa.MLDSA87():646 return oidPublicKeyMLDSA87, true647 }648 return nil, false649}650651// KeyUsage represents the set of actions that are valid for a given key. It's652// a bitmap of the KeyUsage* constants.653type KeyUsage int654655//go:generate stringer -linecomment -type=KeyUsage,ExtKeyUsage -output=x509_string.go656657const (658 KeyUsageDigitalSignature KeyUsage = 1 << iota // digitalSignature659 KeyUsageContentCommitment // contentCommitment660 KeyUsageKeyEncipherment // keyEncipherment661 KeyUsageDataEncipherment // dataEncipherment662 KeyUsageKeyAgreement // keyAgreement663 KeyUsageCertSign // keyCertSign664 KeyUsageCRLSign // cRLSign665 KeyUsageEncipherOnly // encipherOnly666 KeyUsageDecipherOnly // decipherOnly667)668669// RFC 5280, 4.2.1.12 Extended Key Usage670//671// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }672//673// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }674//675// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }676// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }677// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }678// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }679// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }680// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }681//682// https://www.iana.org/assignments/smi-numbers/smi-numbers.xhtml#smi-numbers-1.3.6.1.5.5.7.3683var (684 oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0}685 oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}686 oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}687 oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}688 oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}689 oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}690 oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}691 oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}692 oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}693 oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}694 oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}695 oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}696 oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22}697 oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}698)699700// ExtKeyUsage represents an extended set of actions that are valid for a given key.701// Each of the ExtKeyUsage* constants define a unique action.702type ExtKeyUsage int703704const (705 ExtKeyUsageAny ExtKeyUsage = iota // anyExtendedKeyUsage706 ExtKeyUsageServerAuth // serverAuth707 ExtKeyUsageClientAuth // clientAuth708 ExtKeyUsageCodeSigning // codeSigning709 ExtKeyUsageEmailProtection // emailProtection710 ExtKeyUsageIPSECEndSystem // ipsecEndSystem711 ExtKeyUsageIPSECTunnel // ipsecTunnel712 ExtKeyUsageIPSECUser // ipsecUser713 ExtKeyUsageTimeStamping // timeStamping714 ExtKeyUsageOCSPSigning // OCSPSigning715 ExtKeyUsageMicrosoftServerGatedCrypto // msSGC716 ExtKeyUsageNetscapeServerGatedCrypto // nsSGC717 ExtKeyUsageMicrosoftCommercialCodeSigning // msCodeCom718 ExtKeyUsageMicrosoftKernelCodeSigning // msKernelCode719)720721// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.722var extKeyUsageOIDs = []struct {723 extKeyUsage ExtKeyUsage724 oid asn1.ObjectIdentifier725}{726 {ExtKeyUsageAny, oidExtKeyUsageAny},727 {ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},728 {ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},729 {ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},730 {ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},731 {ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},732 {ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},733 {ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},734 {ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},735 {ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},736 {ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},737 {ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},738 {ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},739 {ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning},740}741742func extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {743 for _, pair := range extKeyUsageOIDs {744 if oid.Equal(pair.oid) {745 return pair.extKeyUsage, true746 }747 }748 return749}750751func oidFromExtKeyUsage(eku ExtKeyUsage) (oid asn1.ObjectIdentifier, ok bool) {752 for _, pair := range extKeyUsageOIDs {753 if eku == pair.extKeyUsage {754 return pair.oid, true755 }756 }757 return758}759760// OID returns the ASN.1 object identifier of the EKU.761func (eku ExtKeyUsage) OID() OID {762 asn1OID, ok := oidFromExtKeyUsage(eku)763 if !ok {764 panic("x509: internal error: known ExtKeyUsage has no OID")765 }766 oid, err := OIDFromASN1OID(asn1OID)767 if err != nil {768 panic("x509: internal error: known ExtKeyUsage has invalid OID")769 }770 return oid771}772773// A Certificate represents an X.509 certificate.774type Certificate struct {775 Raw []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).776 RawTBSCertificate []byte // Certificate part of raw ASN.1 DER content.777 RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.778 RawSubject []byte // DER encoded Subject779 RawIssuer []byte // DER encoded Issuer780 RawSignatureAlgorithm []byte // DER encoded AlgorithmIdentifier781782 Signature []byte783 SignatureAlgorithm SignatureAlgorithm784785 PublicKeyAlgorithm PublicKeyAlgorithm786 PublicKey any787788 Version int789 SerialNumber *big.Int790 Issuer pkix.Name791 Subject pkix.Name792 NotBefore, NotAfter time.Time // Validity bounds.793 KeyUsage KeyUsage794795 // Extensions contains raw X.509 extensions. When parsing certificates,796 // this can be used to extract non-critical extensions that are not797 // parsed by this package. When marshaling certificates, the Extensions798 // field is ignored, see ExtraExtensions.799 Extensions []pkix.Extension800801 // ExtraExtensions contains extensions to be copied, raw, into any802 // marshaled certificates. Values override any extensions that would803 // otherwise be produced based on the other fields. The ExtraExtensions804 // field is not populated when parsing certificates, see Extensions.805 ExtraExtensions []pkix.Extension806807 // UnhandledCriticalExtensions contains a list of extension IDs that808 // were not (fully) processed when parsing. Verify will fail if this809 // slice is non-empty, unless verification is delegated to an OS810 // library which understands all the critical extensions.811 //812 // Users can access these extensions using Extensions and can remove813 // elements from this slice if they believe that they have been814 // handled.815 UnhandledCriticalExtensions []asn1.ObjectIdentifier816817 ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages.818 UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.819820 // BasicConstraintsValid indicates whether IsCA, MaxPathLen,821 // and MaxPathLenZero are valid.822 BasicConstraintsValid bool823 IsCA bool824825 // MaxPathLen and MaxPathLenZero indicate the presence and826 // value of the BasicConstraints' "pathLenConstraint".827 //828 // When parsing a certificate, a positive non-zero MaxPathLen829 // means that the field was specified, -1 means it was unset,830 // and MaxPathLenZero being true mean that the field was831 // explicitly set to zero. The case of MaxPathLen==0 with MaxPathLenZero==false832 // should be treated equivalent to -1 (unset).833 //834 // When generating a certificate, an unset pathLenConstraint835 // can be requested with either MaxPathLen == -1 or using the836 // zero value for both MaxPathLen and MaxPathLenZero.837 MaxPathLen int838 // MaxPathLenZero indicates that BasicConstraintsValid==true839 // and MaxPathLen==0 should be interpreted as an actual840 // maximum path length of zero. Otherwise, that combination is841 // interpreted as MaxPathLen not being set.842 MaxPathLenZero bool843844 SubjectKeyId []byte845 AuthorityKeyId []byte846847 // RFC 5280, 4.2.2.1 (Authority Information Access)848 OCSPServer []string849 IssuingCertificateURL []string850851 // Subject Alternate Name values. (Note that these values may not be valid852 // if invalid values were contained within a parsed certificate. For853 // example, an element of DNSNames may not be a valid DNS domain name.)854 DNSNames []string855 EmailAddresses []string856 IPAddresses []net.IP857 URIs []*url.URL858859 // Name constraints860 PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.861 PermittedDNSDomains []string862 ExcludedDNSDomains []string863 PermittedIPRanges []*net.IPNet864 ExcludedIPRanges []*net.IPNet865 PermittedEmailAddresses []string866 ExcludedEmailAddresses []string867 PermittedURIDomains []string868 ExcludedURIDomains []string869870 // CRL Distribution Points871 CRLDistributionPoints []string872873 // PolicyIdentifiers contains asn1.ObjectIdentifiers, the components874 // of which are limited to int32. If a certificate contains a policy which875 // cannot be represented by asn1.ObjectIdentifier, it will not be included in876 // PolicyIdentifiers, but will be present in Policies, which contains all parsed877 // policy OIDs.878 // See CreateCertificate for context about how this field and the Policies field879 // interact.880 PolicyIdentifiers []asn1.ObjectIdentifier881882 // Policies contains all policy identifiers included in the certificate.883 // See CreateCertificate for context about how this field and the PolicyIdentifiers field884 // interact.885 // In Go 1.22, encoding/gob cannot handle and ignores this field.886 Policies []OID887888 // InhibitAnyPolicy and InhibitAnyPolicyZero indicate the presence and value889 // of the inhibitAnyPolicy extension.890 //891 // The value of InhibitAnyPolicy indicates the number of additional892 // certificates in the path after this certificate that may use the893 // anyPolicy policy OID to indicate a match with any other policy.894 //895 // When parsing a certificate, a positive non-zero InhibitAnyPolicy means896 // that the field was specified, -1 means it was unset, and897 // InhibitAnyPolicyZero being true mean that the field was explicitly set to898 // zero. The case of InhibitAnyPolicy==0 with InhibitAnyPolicyZero==false899 // should be treated equivalent to -1 (unset).900 InhibitAnyPolicy int901 // InhibitAnyPolicyZero indicates that InhibitAnyPolicy==0 should be902 // interpreted as an actual maximum path length of zero. Otherwise, that903 // combination is interpreted as InhibitAnyPolicy not being set.904 InhibitAnyPolicyZero bool905906 // InhibitPolicyMapping and InhibitPolicyMappingZero indicate the presence907 // and value of the inhibitPolicyMapping field of the policyConstraints908 // extension.909 //910 // The value of InhibitPolicyMapping indicates the number of additional911 // certificates in the path after this certificate that may use policy912 // mapping.913 //914 // When parsing a certificate, a positive non-zero InhibitPolicyMapping915 // means that the field was specified, -1 means it was unset, and916 // InhibitPolicyMappingZero being true mean that the field was explicitly917 // set to zero. The case of InhibitPolicyMapping==0 with918 // InhibitPolicyMappingZero==false should be treated equivalent to -1919 // (unset).920 InhibitPolicyMapping int921 // InhibitPolicyMappingZero indicates that InhibitPolicyMapping==0 should be922 // interpreted as an actual maximum path length of zero. Otherwise, that923 // combination is interpreted as InhibitAnyPolicy not being set.924 InhibitPolicyMappingZero bool925926 // RequireExplicitPolicy and RequireExplicitPolicyZero indicate the presence927 // and value of the requireExplicitPolicy field of the policyConstraints928 // extension.929 //930 // The value of RequireExplicitPolicy indicates the number of additional931 // certificates in the path after this certificate before an explicit policy932 // is required for the rest of the path. When an explicit policy is required,933 // each subsequent certificate in the path must contain a required policy OID,934 // or a policy OID which has been declared as equivalent through the policy935 // mapping extension.936 //937 // When parsing a certificate, a positive non-zero RequireExplicitPolicy938 // means that the field was specified, -1 means it was unset, and939 // RequireExplicitPolicyZero being true mean that the field was explicitly940 // set to zero. The case of RequireExplicitPolicy==0 with941 // RequireExplicitPolicyZero==false should be treated equivalent to -1942 // (unset).943 RequireExplicitPolicy int944 // RequireExplicitPolicyZero indicates that RequireExplicitPolicy==0 should be945 // interpreted as an actual maximum path length of zero. Otherwise, that946 // combination is interpreted as InhibitAnyPolicy not being set.947 RequireExplicitPolicyZero bool948949 // PolicyMappings contains a list of policy mappings included in the certificate.950 PolicyMappings []PolicyMapping951}952953// PolicyMapping represents a policy mapping entry in the policyMappings extension.954type PolicyMapping struct {955 // IssuerDomainPolicy contains a policy OID the issuing certificate considers956 // equivalent to SubjectDomainPolicy in the subject certificate.957 IssuerDomainPolicy OID958 // SubjectDomainPolicy contains a OID the issuing certificate considers959 // equivalent to IssuerDomainPolicy in the subject certificate.960 SubjectDomainPolicy OID961}962963// ErrUnsupportedAlgorithm results from attempting to perform an operation that964// involves algorithms that are not currently implemented.965var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")966967// An InsecureAlgorithmError indicates that the [SignatureAlgorithm] used to968// generate the signature is not secure, and the signature has been rejected.969type InsecureAlgorithmError SignatureAlgorithm970971func (e InsecureAlgorithmError) Error() string {972 return fmt.Sprintf("x509: cannot verify signature: insecure algorithm %v", SignatureAlgorithm(e))973}974975// ConstraintViolationError results when a requested usage is not permitted by976// a certificate. For example: checking a signature when the public key isn't a977// certificate signing key.978type ConstraintViolationError struct{}979980func (ConstraintViolationError) Error() string {981 return "x509: invalid signature: parent certificate cannot sign this kind of certificate"982}983984func (c *Certificate) Equal(other *Certificate) bool {985 if c == nil || other == nil {986 return c == other987 }988 return bytes.Equal(c.Raw, other.Raw)989}990991func (c *Certificate) hasSANExtension() bool {992 return oidInExtensions(oidExtensionSubjectAltName, c.Extensions)993}994995// CheckSignatureFrom verifies that the signature on c is a valid signature from parent.996//997// This is a low-level API that performs very limited checks, and not a full998// path verifier. Most users should use [Certificate.Verify] instead.999func (c *Certificate) CheckSignatureFrom(parent *Certificate) error {1000 // RFC 5280, 4.2.1.9:1001 // "If the basic constraints extension is not present in a version 31002 // certificate, or the extension is present but the cA boolean is not1003 // asserted, then the certified public key MUST NOT be used to verify1004 // certificate signatures."1005 if parent.Version == 3 && !parent.BasicConstraintsValid ||1006 parent.BasicConstraintsValid && !parent.IsCA {1007 return ConstraintViolationError{}1008 }10091010 if parent.KeyUsage != 0 && parent.KeyUsage&KeyUsageCertSign == 0 {1011 return ConstraintViolationError{}1012 }10131014 if parent.PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {1015 return ErrUnsupportedAlgorithm1016 }10171018 return checkSignature(c.SignatureAlgorithm, c.RawTBSCertificate, c.Signature, parent.PublicKey, false)1019}10201021// CheckSignature verifies that signature is a valid signature over signed from1022// c's public key.1023//1024// This is a low-level API that performs no validity checks on the certificate.1025//1026// [MD5WithRSA] signatures are rejected, while [SHA1WithRSA] and [ECDSAWithSHA1]1027// signatures are currently accepted.1028func (c *Certificate) CheckSignature(algo SignatureAlgorithm, signed, signature []byte) error {1029 return checkSignature(algo, signed, signature, c.PublicKey, true)1030}10311032func (c *Certificate) hasNameConstraints() bool {1033 return oidInExtensions(oidExtensionNameConstraints, c.Extensions)1034}10351036func (c *Certificate) getSANExtension() []byte {1037 for _, e := range c.Extensions {1038 if e.Id.Equal(oidExtensionSubjectAltName) {1039 return e.Value1040 }1041 }1042 return nil1043}10441045func signaturePublicKeyAlgoMismatchError(expectedPubKeyAlgo PublicKeyAlgorithm, pubKey any) error {1046 return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", expectedPubKeyAlgo.String(), pubKey)1047}10481049func signatureMLDSAParametersMismatchError(expectedSigAlgo SignatureAlgorithm, pubKey *mldsa.PublicKey) error {1050 return fmt.Errorf("x509: signature algorithm specifies an ML-DSA public key with %s parameters, but have a public key with %s parameters", expectedSigAlgo, pubKey.Parameters())1051}10521053// checkSignature verifies that signature is a valid signature over signed from1054// a crypto.PublicKey.1055func checkSignature(algo SignatureAlgorithm, signed, signature []byte, publicKey crypto.PublicKey, allowSHA1 bool) (err error) {1056 var hashType crypto.Hash1057 var pubKeyAlgo PublicKeyAlgorithm10581059 for _, details := range signatureAlgorithmDetails {1060 if details.algo == algo {1061 hashType = details.hash1062 pubKeyAlgo = details.pubKeyAlgo1063 break1064 }1065 }10661067 switch hashType {1068 case crypto.Hash(0):1069 if pubKeyAlgo != Ed25519 && pubKeyAlgo != MLDSA {1070 return ErrUnsupportedAlgorithm1071 }1072 case crypto.MD5:1073 return InsecureAlgorithmError(algo)1074 case crypto.SHA1:1075 // SHA-1 signatures are only allowed for CRLs and CSRs.1076 if !allowSHA1 {1077 return InsecureAlgorithmError(algo)1078 }1079 fallthrough1080 default:1081 if !hashType.Available() {1082 return ErrUnsupportedAlgorithm1083 }1084 h := hashType.New()1085 h.Write(signed)1086 signed = h.Sum(nil)1087 }10881089 switch pub := publicKey.(type) {1090 case *rsa.PublicKey:1091 if pubKeyAlgo != RSA {1092 return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)1093 }1094 if algo.isRSAPSS() {1095 return rsa.VerifyPSS(pub, hashType, signed, signature, &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash})1096 } else {1097 return rsa.VerifyPKCS1v15(pub, hashType, signed, signature)1098 }1099 case *ecdsa.PublicKey:1100 if pubKeyAlgo != ECDSA {1101 return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)1102 }1103 if !ecdsa.VerifyASN1(pub, signed, signature) {1104 return errors.New("x509: ECDSA verification failure")1105 }1106 return1107 case ed25519.PublicKey:1108 if pubKeyAlgo != Ed25519 {1109 return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)1110 }1111 if !ed25519.Verify(pub, signed, signature) {1112 return errors.New("x509: Ed25519 verification failure")1113 }1114 return1115 case *mldsa.PublicKey:1116 if pubKeyAlgo != MLDSA {1117 return signaturePublicKeyAlgoMismatchError(pubKeyAlgo, pub)1118 }1119 switch pub.Parameters() {1120 case mldsa.MLDSA44():1121 if algo != MLDSA44 {1122 return signatureMLDSAParametersMismatchError(algo, pub)1123 }1124 case mldsa.MLDSA65():1125 if algo != MLDSA65 {1126 return signatureMLDSAParametersMismatchError(algo, pub)1127 }1128 case mldsa.MLDSA87():1129 if algo != MLDSA87 {1130 return signatureMLDSAParametersMismatchError(algo, pub)1131 }1132 default:1133 return fmt.Errorf("x509: unknown ML-DSA parameters: %s", pub.Parameters())1134 }1135 if err := mldsa.Verify(pub, signed, signature, nil); err != nil {1136 return fmt.Errorf("x509: ML-DSA verification failure: %w", err)1137 }1138 return1139 }1140 return ErrUnsupportedAlgorithm1141}11421143// CheckCRLSignature checks that the signature in crl is from c.1144//1145// Deprecated: Use [RevocationList.CheckSignatureFrom] instead.1146func (c *Certificate) CheckCRLSignature(crl *pkix.CertificateList) error {1147 algo := getSignatureAlgorithmFromAI(crl.SignatureAlgorithm)1148 return c.CheckSignature(algo, crl.TBSCertList.Raw, crl.SignatureValue.RightAlign())1149}11501151type UnhandledCriticalExtension struct{}11521153func (h UnhandledCriticalExtension) Error() string {1154 return "x509: unhandled critical extension"1155}11561157type basicConstraints struct {1158 IsCA bool `asn1:"optional"`1159 MaxPathLen int `asn1:"optional,default:-1"`1160}11611162// RFC 5280 4.2.1.41163type policyInformation struct {1164 Policy asn1.ObjectIdentifier1165 // policyQualifiers omitted1166}11671168const (1169 nameTypeEmail = 11170 nameTypeDNS = 21171 nameTypeURI = 61172 nameTypeIP = 71173)11741175// RFC 5280, 4.2.2.11176type authorityInfoAccess struct {1177 Method asn1.ObjectIdentifier1178 Location asn1.RawValue1179}11801181// RFC 5280, 4.2.1.141182type distributionPoint struct {1183 DistributionPoint distributionPointName `asn1:"optional,tag:0"`1184 Reason asn1.BitString `asn1:"optional,tag:1"`1185 CRLIssuer asn1.RawValue `asn1:"optional,tag:2"`1186}11871188type distributionPointName struct {1189 FullName []asn1.RawValue `asn1:"optional,tag:0"`1190 RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`1191}11921193func reverseBitsInAByte(in byte) byte {1194 b1 := in>>4 | in<<41195 b2 := b1>>2&0x33 | b1<<2&0xcc1196 b3 := b2>>1&0x55 | b2<<1&0xaa1197 return b31198}11991200// asn1BitLength returns the bit-length of bitString by considering the1201// most-significant bit in a byte to be the "first" bit. This convention1202// matches ASN.1, but differs from almost everything else.1203func asn1BitLength(bitString []byte) int {1204 bitLen := len(bitString) * 812051206 for i := range bitString {1207 b := bitString[len(bitString)-i-1]12081209 for bit := uint(0); bit < 8; bit++ {1210 if (b>>bit)&1 == 1 {1211 return bitLen1212 }1213 bitLen--1214 }1215 }12161217 return 01218}12191220var (1221 oidExtensionSubjectKeyId = []int{2, 5, 29, 14}1222 oidExtensionKeyUsage = []int{2, 5, 29, 15}1223 oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37}1224 oidExtensionAuthorityKeyId = []int{2, 5, 29, 35}1225 oidExtensionBasicConstraints = []int{2, 5, 29, 19}1226 oidExtensionSubjectAltName = []int{2, 5, 29, 17}1227 oidExtensionCertificatePolicies = []int{2, 5, 29, 32}1228 oidExtensionNameConstraints = []int{2, 5, 29, 30}1229 oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31}1230 oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}1231 oidExtensionCRLNumber = []int{2, 5, 29, 20}1232 oidExtensionReasonCode = []int{2, 5, 29, 21}1233)12341235var (1236 oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}1237 oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}1238)12391240// oidInExtensions reports whether an extension with the given oid exists in1241// extensions.1242func oidInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) bool {1243 for _, e := range extensions {1244 if e.Id.Equal(oid) {1245 return true1246 }1247 }1248 return false1249}12501251// marshalSANs marshals a list of addresses into a the contents of an X.5091252// SubjectAlternativeName extension.1253func marshalSANs(dnsNames, emailAddresses []string, ipAddresses []net.IP, uris []*url.URL) (derBytes []byte, err error) {1254 var rawValues []asn1.RawValue1255 for _, name := range dnsNames {1256 if err := isIA5String(name); err != nil {1257 return nil, err1258 }1259 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})1260 }1261 for _, email := range emailAddresses {1262 if err := isIA5String(email); err != nil {1263 return nil, err1264 }1265 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})1266 }1267 for _, rawIP := range ipAddresses {1268 // If possible, we always want to encode IPv4 addresses in 4 bytes.1269 ip := rawIP.To4()1270 if ip == nil {1271 ip = rawIP1272 }1273 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip})1274 }1275 for _, uri := range uris {1276 uriStr := uri.String()1277 if err := isIA5String(uriStr); err != nil {1278 return nil, err1279 }1280 rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uriStr)})1281 }1282 return asn1.Marshal(rawValues)1283}12841285func isIA5String(s string) error {1286 for _, r := range s {1287 // Per RFC5280 "IA5String is limited to the set of ASCII characters"1288 if r > unicode.MaxASCII {1289 return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)1290 }1291 }12921293 return nil1294}12951296var x509usepolicies = godebug.New("x509usepolicies")12971298func buildCertExtensions(template *Certificate, subjectIsEmpty bool, authorityKeyId []byte, subjectKeyId []byte) (ret []pkix.Extension, err error) {1299 ret = make([]pkix.Extension, 10 /* maximum number of elements. */)1300 n := 013011302 if template.KeyUsage != 0 &&1303 !oidInExtensions(oidExtensionKeyUsage, template.ExtraExtensions) {1304 ret[n], err = marshalKeyUsage(template.KeyUsage)1305 if err != nil {1306 return nil, err1307 }1308 n++1309 }13101311 if (len(template.ExtKeyUsage) > 0 || len(template.UnknownExtKeyUsage) > 0) &&1312 !oidInExtensions(oidExtensionExtendedKeyUsage, template.ExtraExtensions) {1313 ret[n], err = marshalExtKeyUsage(template.ExtKeyUsage, template.UnknownExtKeyUsage)1314 if err != nil {1315 return nil, err1316 }1317 n++1318 }13191320 if template.BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, template.ExtraExtensions) {1321 ret[n], err = marshalBasicConstraints(template.IsCA, template.MaxPathLen, template.MaxPathLenZero)1322 if err != nil {1323 return nil, err1324 }1325 n++1326 }13271328 if len(subjectKeyId) > 0 && !oidInExtensions(oidExtensionSubjectKeyId, template.ExtraExtensions) {1329 ret[n].Id = oidExtensionSubjectKeyId1330 ret[n].Value, err = asn1.Marshal(subjectKeyId)1331 if err != nil {1332 return1333 }1334 n++1335 }13361337 if len(authorityKeyId) > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, template.ExtraExtensions) {1338 ret[n].Id = oidExtensionAuthorityKeyId1339 ret[n].Value, err = asn1.Marshal(authKeyId{authorityKeyId})1340 if err != nil {1341 return1342 }1343 n++1344 }13451346 if (len(template.OCSPServer) > 0 || len(template.IssuingCertificateURL) > 0) &&1347 !oidInExtensions(oidExtensionAuthorityInfoAccess, template.ExtraExtensions) {1348 ret[n].Id = oidExtensionAuthorityInfoAccess1349 var aiaValues []authorityInfoAccess1350 for _, name := range template.OCSPServer {1351 aiaValues = append(aiaValues, authorityInfoAccess{1352 Method: oidAuthorityInfoAccessOcsp,1353 Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},1354 })1355 }1356 for _, name := range template.IssuingCertificateURL {1357 aiaValues = append(aiaValues, authorityInfoAccess{1358 Method: oidAuthorityInfoAccessIssuers,1359 Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},1360 })1361 }1362 ret[n].Value, err = asn1.Marshal(aiaValues)1363 if err != nil {1364 return1365 }1366 n++1367 }13681369 if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&1370 !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {1371 ret[n].Id = oidExtensionSubjectAltName1372 // From RFC 5280, Section 4.2.1.6:1373 // “If the subject field contains an empty sequence ... then1374 // subjectAltName extension ... is marked as critical”1375 ret[n].Critical = subjectIsEmpty1376 ret[n].Value, err = marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)1377 if err != nil {1378 return1379 }1380 n++1381 }13821383 usePolicies := x509usepolicies.Value() != "0"1384 if ((!usePolicies && len(template.PolicyIdentifiers) > 0) || (usePolicies && len(template.Policies) > 0)) &&1385 !oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) {1386 ret[n], err = marshalCertificatePolicies(template.Policies, template.PolicyIdentifiers)1387 if err != nil {1388 return nil, err1389 }1390 n++1391 }13921393 if (len(template.PermittedDNSDomains) > 0 || len(template.ExcludedDNSDomains) > 0 ||1394 len(template.PermittedIPRanges) > 0 || len(template.ExcludedIPRanges) > 0 ||1395 len(template.PermittedEmailAddresses) > 0 || len(template.ExcludedEmailAddresses) > 0 ||1396 len(template.PermittedURIDomains) > 0 || len(template.ExcludedURIDomains) > 0) &&1397 !oidInExtensions(oidExtensionNameConstraints, template.ExtraExtensions) {1398 ret[n].Id = oidExtensionNameConstraints1399 ret[n].Critical = template.PermittedDNSDomainsCritical14001401 ipAndMask := func(ipNet *net.IPNet) ([]byte, error) {1402 maskedIP := ipNet.IP.Mask(ipNet.Mask)1403 // This is extremely unlikely to actually happen, but lets save people from doing something they1404 // probably shouldn't.1405 if len(maskedIP) == net.IPv6len && maskedIP.To4() != nil {1406 return nil, errors.New("x509: IP constraint contained IPv4-mapped IPv6 address with a IPv6 mask")1407 }1408 ipAndMask := make([]byte, 0, len(maskedIP)+len(ipNet.Mask))1409 ipAndMask = append(ipAndMask, maskedIP...)1410 ipAndMask = append(ipAndMask, ipNet.Mask...)1411 return ipAndMask, nil1412 }14131414 serialiseConstraints := func(dns []string, ips []*net.IPNet, emails []string, uriDomains []string) (der []byte, err error) {1415 var b cryptobyte.Builder14161417 for _, name := range dns {1418 if err = isIA5String(name); err != nil {1419 return nil, err1420 }14211422 b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {1423 b.AddASN1(cryptobyte_asn1.Tag(2).ContextSpecific(), func(b *cryptobyte.Builder) {1424 b.AddBytes([]byte(name))1425 })1426 })1427 }14281429 for _, ipNet := range ips {1430 encodedIPNet, err := ipAndMask(ipNet)1431 if err != nil {1432 return nil, err1433 }1434 b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {1435 b.AddASN1(cryptobyte_asn1.Tag(7).ContextSpecific(), func(b *cryptobyte.Builder) {1436 b.AddBytes(encodedIPNet)1437 })1438 })1439 }14401441 for _, email := range emails {1442 if err = isIA5String(email); err != nil {1443 return nil, err1444 }14451446 b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {1447 b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific(), func(b *cryptobyte.Builder) {1448 b.AddBytes([]byte(email))1449 })1450 })1451 }14521453 for _, uriDomain := range uriDomains {1454 if err = isIA5String(uriDomain); err != nil {1455 return nil, err1456 }14571458 b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {1459 b.AddASN1(cryptobyte_asn1.Tag(6).ContextSpecific(), func(b *cryptobyte.Builder) {1460 b.AddBytes([]byte(uriDomain))1461 })1462 })1463 }14641465 return b.Bytes()1466 }14671468 permitted, err := serialiseConstraints(template.PermittedDNSDomains, template.PermittedIPRanges, template.PermittedEmailAddresses, template.PermittedURIDomains)1469 if err != nil {1470 return nil, err1471 }14721473 excluded, err := serialiseConstraints(template.ExcludedDNSDomains, template.ExcludedIPRanges, template.ExcludedEmailAddresses, template.ExcludedURIDomains)1474 if err != nil {1475 return nil, err1476 }14771478 var b cryptobyte.Builder1479 b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) {1480 if len(permitted) > 0 {1481 b.AddASN1(cryptobyte_asn1.Tag(0).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {1482 b.AddBytes(permitted)1483 })1484 }14851486 if len(excluded) > 0 {1487 b.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific().Constructed(), func(b *cryptobyte.Builder) {1488 b.AddBytes(excluded)1489 })1490 }1491 })14921493 ret[n].Value, err = b.Bytes()1494 if err != nil {1495 return nil, err1496 }1497 n++1498 }14991500 if len(template.CRLDistributionPoints) > 0 &&1501 !oidInExtensions(oidExtensionCRLDistributionPoints, template.ExtraExtensions) {1502 ret[n].Id = oidExtensionCRLDistributionPoints15031504 var crlDp []distributionPoint1505 for _, name := range template.CRLDistributionPoints {1506 dp := distributionPoint{1507 DistributionPoint: distributionPointName{1508 FullName: []asn1.RawValue{1509 {Tag: 6, Class: 2, Bytes: []byte(name)},1510 },1511 },1512 }1513 crlDp = append(crlDp, dp)1514 }15151516 ret[n].Value, err = asn1.Marshal(crlDp)1517 if err != nil {1518 return1519 }1520 n++1521 }15221523 // Adding another extension here? Remember to update the maximum number1524 // of elements in the make() at the top of the function and the list of1525 // template fields used in CreateCertificate documentation.15261527 return append(ret[:n], template.ExtraExtensions...), nil1528}15291530func marshalKeyUsage(ku KeyUsage) (pkix.Extension, error) {1531 ext := pkix.Extension{Id: oidExtensionKeyUsage, Critical: true}15321533 var a [2]byte1534 a[0] = reverseBitsInAByte(byte(ku))1535 a[1] = reverseBitsInAByte(byte(ku >> 8))15361537 l := 11538 if a[1] != 0 {1539 l = 21540 }15411542 bitString := a[:l]1543 var err error1544 ext.Value, err = asn1.Marshal(asn1.BitString{Bytes: bitString, BitLength: asn1BitLength(bitString)})1545 return ext, err1546}15471548func marshalExtKeyUsage(extUsages []ExtKeyUsage, unknownUsages []asn1.ObjectIdentifier) (pkix.Extension, error) {1549 ext := pkix.Extension{Id: oidExtensionExtendedKeyUsage}15501551 oids := make([]asn1.ObjectIdentifier, len(extUsages)+len(unknownUsages))1552 for i, u := range extUsages {1553 if oid, ok := oidFromExtKeyUsage(u); ok {1554 oids[i] = oid1555 } else {1556 return ext, errors.New("x509: unknown extended key usage")1557 }1558 }15591560 copy(oids[len(extUsages):], unknownUsages)15611562 var err error1563 ext.Value, err = asn1.Marshal(oids)1564 return ext, err1565}15661567func marshalBasicConstraints(isCA bool, maxPathLen int, maxPathLenZero bool) (pkix.Extension, error) {1568 ext := pkix.Extension{Id: oidExtensionBasicConstraints, Critical: true}1569 // Leaving MaxPathLen as zero indicates that no maximum path1570 // length is desired, unless MaxPathLenZero is set. A value of1571 // -1 causes encoding/asn1 to omit the value as desired.1572 if maxPathLen == 0 && !maxPathLenZero {1573 maxPathLen = -11574 }1575 var err error1576 ext.Value, err = asn1.Marshal(basicConstraints{isCA, maxPathLen})1577 return ext, err1578}15791580func marshalCertificatePolicies(policies []OID, policyIdentifiers []asn1.ObjectIdentifier) (pkix.Extension, error) {1581 ext := pkix.Extension{Id: oidExtensionCertificatePolicies}15821583 b := cryptobyte.NewBuilder(make([]byte, 0, 128))1584 b.AddASN1(cryptobyte_asn1.SEQUENCE, func(child *cryptobyte.Builder) {1585 if x509usepolicies.Value() != "0" {1586 x509usepolicies.IncNonDefault()1587 for _, v := range policies {1588 child.AddASN1(cryptobyte_asn1.SEQUENCE, func(child *cryptobyte.Builder) {1589 child.AddASN1(cryptobyte_asn1.OBJECT_IDENTIFIER, func(child *cryptobyte.Builder) {1590 if len(v.der) == 0 {1591 child.SetError(errors.New("invalid policy object identifier"))1592 return1593 }1594 child.AddBytes(v.der)1595 })1596 })1597 }1598 } else {1599 for _, v := range policyIdentifiers {1600 child.AddASN1(cryptobyte_asn1.SEQUENCE, func(child *cryptobyte.Builder) {1601 child.AddASN1ObjectIdentifier(v)1602 })1603 }1604 }1605 })16061607 var err error1608 ext.Value, err = b.Bytes()1609 return ext, err1610}16111612func buildCSRExtensions(template *CertificateRequest) ([]pkix.Extension, error) {1613 var ret []pkix.Extension16141615 if (len(template.DNSNames) > 0 || len(template.EmailAddresses) > 0 || len(template.IPAddresses) > 0 || len(template.URIs) > 0) &&1616 !oidInExtensions(oidExtensionSubjectAltName, template.ExtraExtensions) {1617 sanBytes, err := marshalSANs(template.DNSNames, template.EmailAddresses, template.IPAddresses, template.URIs)1618 if err != nil {1619 return nil, err1620 }16211622 ret = append(ret, pkix.Extension{1623 Id: oidExtensionSubjectAltName,1624 Value: sanBytes,1625 })1626 }16271628 return append(ret, template.ExtraExtensions...), nil1629}16301631func subjectBytes(cert *Certificate) ([]byte, error) {1632 if len(cert.RawSubject) > 0 {1633 return cert.RawSubject, nil1634 }16351636 return asn1.Marshal(cert.Subject.ToRDNSequence())1637}16381639// signingParamsForKey returns the signature algorithm and its Algorithm1640// Identifier to use for signing, based on the key type. If sigAlgo is not zero1641// then it overrides the default.1642func signingParamsForKey(key crypto.Signer, sigAlgo SignatureAlgorithm) (SignatureAlgorithm, pkix.AlgorithmIdentifier, error) {1643 var ai pkix.AlgorithmIdentifier1644 var pubType PublicKeyAlgorithm1645 var defaultAlgo SignatureAlgorithm16461647 switch pub := key.Public().(type) {1648 case *rsa.PublicKey:1649 pubType = RSA1650 defaultAlgo = SHA256WithRSA16511652 case *ecdsa.PublicKey:1653 pubType = ECDSA1654 switch pub.Curve {1655 case elliptic.P224(), elliptic.P256():1656 defaultAlgo = ECDSAWithSHA2561657 case elliptic.P384():1658 defaultAlgo = ECDSAWithSHA3841659 case elliptic.P521():1660 defaultAlgo = ECDSAWithSHA5121661 default:1662 return 0, ai, errors.New("x509: unsupported elliptic curve")1663 }16641665 case ed25519.PublicKey:1666 pubType = Ed255191667 defaultAlgo = PureEd2551916681669 case *mldsa.PublicKey:1670 pubType = MLDSA1671 switch pub.Parameters() {1672 case mldsa.MLDSA44():1673 defaultAlgo = MLDSA441674 case mldsa.MLDSA65():1675 defaultAlgo = MLDSA651676 case mldsa.MLDSA87():1677 defaultAlgo = MLDSA871678 default:1679 return 0, ai, fmt.Errorf("x509: unsupported ML-DSA parameters: %s", pub.Parameters())1680 }16811682 default:1683 return 0, ai, errors.New("x509: only RSA, ECDSA, ML-DSA and Ed25519 keys supported")1684 }16851686 if sigAlgo == 0 {1687 sigAlgo = defaultAlgo1688 }16891690 for _, details := range signatureAlgorithmDetails {1691 if details.algo == sigAlgo {1692 if details.pubKeyAlgo != pubType {1693 return 0, ai, errors.New("x509: requested SignatureAlgorithm does not match private key type")1694 }1695 if pubType == MLDSA && sigAlgo != defaultAlgo {1696 return 0, ai, errors.New("x509: requested SignatureAlgorithm does not match ML-DSA parameters")1697 }1698 if details.hash == crypto.MD5 {1699 return 0, ai, errors.New("x509: signing with MD5 is not supported")1700 }17011702 return sigAlgo, pkix.AlgorithmIdentifier{1703 Algorithm: details.oid,1704 Parameters: details.params,1705 }, nil1706 }1707 }17081709 return 0, ai, errors.New("x509: unknown SignatureAlgorithm")1710}17111712func signTBS(tbs []byte, key crypto.Signer, sigAlg SignatureAlgorithm, rand io.Reader) ([]byte, error) {1713 hashFunc := sigAlg.hashFunc()17141715 var signerOpts crypto.SignerOpts = hashFunc1716 if sigAlg.isRSAPSS() {1717 signerOpts = &rsa.PSSOptions{1718 SaltLength: rsa.PSSSaltLengthEqualsHash,1719 Hash: hashFunc,1720 }1721 }17221723 signature, err := crypto.SignMessage(key, rand, tbs, signerOpts)1724 if err != nil {1725 return nil, err1726 }17271728 // Check the signature to ensure the crypto.Signer behaved correctly.1729 if err := checkSignature(sigAlg, tbs, signature, key.Public(), true); err != nil {1730 return nil, fmt.Errorf("x509: signature returned by signer is invalid: %w", err)1731 }17321733 return signature, nil1734}17351736// emptyASN1Subject is the ASN.1 DER encoding of an empty Subject, which is1737// just an empty SEQUENCE.1738var emptyASN1Subject = []byte{0x30, 0}17391740// CreateCertificate creates a new X.509 v3 certificate based on a template.1741// The following members of template are currently used:1742//1743// - AuthorityKeyId1744// - BasicConstraintsValid1745// - CRLDistributionPoints1746// - DNSNames1747// - EmailAddresses1748// - ExcludedDNSDomains1749// - ExcludedEmailAddresses1750// - ExcludedIPRanges1751// - ExcludedURIDomains1752// - ExtKeyUsage1753// - ExtraExtensions1754// - IPAddresses1755// - IsCA1756// - IssuingCertificateURL1757// - KeyUsage1758// - MaxPathLen1759// - MaxPathLenZero1760// - NotAfter1761// - NotBefore1762// - OCSPServer1763// - PermittedDNSDomains1764// - PermittedDNSDomainsCritical1765// - PermittedEmailAddresses1766// - PermittedIPRanges1767// - PermittedURIDomains1768// - PolicyIdentifiers (see note below)1769// - Policies (see note below)1770// - SerialNumber1771// - SignatureAlgorithm1772// - Subject1773// - SubjectKeyId1774// - URIs1775// - UnknownExtKeyUsage1776//1777// The certificate is signed by parent. If parent is equal to template then the1778// certificate is self-signed. The parameter pub is the public key of the1779// certificate to be generated and priv is the private key of the signer.1780//1781// The returned slice is the certificate in DER encoding.1782//1783// The currently supported key types are *rsa.PublicKey, *ecdsa.PublicKey,1784// ed25519.PublicKey, and *mldsa.PublicKey. pub must be a supported key type,1785// and priv must be a crypto.Signer or crypto.MessageSigner with a supported1786// public key.1787//1788// The AuthorityKeyId will be taken from the SubjectKeyId of parent, if any,1789// unless the resulting certificate is self-signed. Otherwise the value from1790// template will be used.1791//1792// If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId1793// will be generated from the hash of the public key.1794//1795// If template.SerialNumber is nil, a serial number will be generated which1796// conforms to RFC 5280, Section 4.1.2.2 using entropy from rand.1797//1798// The PolicyIdentifier and Policies fields can both be used to marshal certificate1799// policy OIDs. By default, only the Policies is marshaled, but if the1800// GODEBUG setting "x509usepolicies" has the value "0", the PolicyIdentifiers field will1801// be marshaled instead of the Policies field. This changed in Go 1.24. The Policies field can1802// be used to marshal policy OIDs which have components that are larger than 311803// bits.1804//1805// IP addresses in IPAddresses which are in their IPv4-mapped IPv6 form will always be encoded1806// in their IPv4 form.1807func CreateCertificate(rand io.Reader, template, parent *Certificate, pub, priv any) ([]byte, error) {1808 key, ok := priv.(crypto.Signer)1809 if !ok {1810 return nil, errors.New("x509: certificate private key does not implement crypto.Signer")1811 }18121813 serialNumber := template.SerialNumber1814 if serialNumber == nil {1815 // Generate a serial number following RFC 5280, Section 4.1.2.2 if one1816 // is not provided. The serial number must be positive and at most 201817 // octets *when encoded*.1818 serialBytes := make([]byte, 20)1819 if _, err := io.ReadFull(rand, serialBytes); err != nil {1820 return nil, err1821 }1822 // If the top bit is set, the serial will be padded with a leading zero1823 // byte during encoding, so that it's not interpreted as a negative1824 // integer. This padding would make the serial 21 octets so we clear the1825 // top bit to ensure the correct length in all cases.1826 serialBytes[0] &= 0b0111_11111827 serialNumber = new(big.Int).SetBytes(serialBytes)1828 }18291830 // RFC 5280 Section 4.1.2.2: serial number must be positive1831 //1832 // We _should_ also restrict serials to <= 20 octets, but it turns out a lot of people1833 // get this wrong, in part because the encoding can itself alter the length of the1834 // serial. For now we accept these non-conformant serials.1835 if serialNumber.Sign() == -1 {1836 return nil, errors.New("x509: serial number must be positive")1837 }18381839 if template.BasicConstraintsValid && template.MaxPathLen < -1 {1840 return nil, errors.New("x509: invalid MaxPathLen, must be greater or equal to -1")1841 }18421843 if template.BasicConstraintsValid && !template.IsCA && template.MaxPathLen != -1 && (template.MaxPathLen != 0 || template.MaxPathLenZero) {1844 return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen")1845 }18461847 signatureAlgorithm, algorithmIdentifier, err := signingParamsForKey(key, template.SignatureAlgorithm)1848 if err != nil {1849 return nil, err1850 }18511852 publicKeyBytes, publicKeyAlgorithm, err := marshalPublicKey(pub)1853 if err != nil {1854 return nil, err1855 }1856 if getPublicKeyAlgorithmFromOID(publicKeyAlgorithm.Algorithm) == UnknownPublicKeyAlgorithm {1857 return nil, fmt.Errorf("x509: unsupported public key type: %T", pub)1858 }18591860 asn1Issuer, err := subjectBytes(parent)1861 if err != nil {1862 return nil, err1863 }18641865 asn1Subject, err := subjectBytes(template)1866 if err != nil {1867 return nil, err1868 }18691870 authorityKeyId := template.AuthorityKeyId1871 if !bytes.Equal(asn1Issuer, asn1Subject) && len(parent.SubjectKeyId) > 0 {1872 authorityKeyId = parent.SubjectKeyId1873 }18741875 subjectKeyId := template.SubjectKeyId1876 if len(subjectKeyId) == 0 && template.IsCA {1877 if x509sha256skid.Value() == "0" {1878 x509sha256skid.IncNonDefault()1879 // SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2:1880 // (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the1881 // value of the BIT STRING subjectPublicKey (excluding the tag,1882 // length, and number of unused bits).1883 h := sha1.Sum(publicKeyBytes)1884 subjectKeyId = h[:]1885 } else {1886 // SubjectKeyId generated using method 1 in RFC 7093, Section 2:1887 // 1) The keyIdentifier is composed of the leftmost 160-bits of the1888 // SHA-256 hash of the value of the BIT STRING subjectPublicKey1889 // (excluding the tag, length, and number of unused bits).1890 h := sha256.Sum256(publicKeyBytes)1891 subjectKeyId = h[:20]1892 }1893 }18941895 // Check that the signer's public key matches the private key, if available.1896 type privateKey interface {1897 Equal(crypto.PublicKey) bool1898 }1899 if privPub, ok := key.Public().(privateKey); !ok {1900 return nil, errors.New("x509: internal error: supported public key does not implement Equal")1901 } else if parent.PublicKey != nil && !privPub.Equal(parent.PublicKey) {1902 return nil, errors.New("x509: provided PrivateKey doesn't match parent's PublicKey")1903 }19041905 extensions, err := buildCertExtensions(template, bytes.Equal(asn1Subject, emptyASN1Subject), authorityKeyId, subjectKeyId)1906 if err != nil {1907 return nil, err1908 }19091910 encodedPublicKey := asn1.BitString{BitLength: len(publicKeyBytes) * 8, Bytes: publicKeyBytes}1911 c := tbsCertificate{1912 Version: 2,1913 SerialNumber: serialNumber,1914 SignatureAlgorithm: algorithmIdentifier,1915 Issuer: asn1.RawValue{FullBytes: asn1Issuer},1916 Validity: validity{template.NotBefore.UTC(), template.NotAfter.UTC()},1917 Subject: asn1.RawValue{FullBytes: asn1Subject},1918 PublicKey: publicKeyInfo{nil, publicKeyAlgorithm, encodedPublicKey},1919 Extensions: extensions,1920 }19211922 tbsCertContents, err := asn1.Marshal(c)1923 if err != nil {1924 return nil, err1925 }1926 c.Raw = tbsCertContents19271928 signature, err := signTBS(tbsCertContents, key, signatureAlgorithm, rand)1929 if err != nil {1930 return nil, err1931 }19321933 return asn1.Marshal(certificate{1934 TBSCertificate: c,1935 SignatureAlgorithm: algorithmIdentifier,1936 SignatureValue: asn1.BitString{Bytes: signature, BitLength: len(signature) * 8},1937 })1938}19391940var x509sha256skid = godebug.New("x509sha256skid")19411942// pemCRLPrefix is the magic string that indicates that we have a PEM encoded1943// CRL.1944var pemCRLPrefix = []byte("-----BEGIN X509 CRL")19451946// pemType is the type of a PEM encoded CRL.1947var pemType = "X509 CRL"19481949// ParseCRL parses a CRL from the given bytes. It's often the case that PEM1950// encoded CRLs will appear where they should be DER encoded, so this function1951// will transparently handle PEM encoding as long as there isn't any leading1952// garbage.1953//1954// Deprecated: Use [ParseRevocationList] instead.1955func ParseCRL(crlBytes []byte) (*pkix.CertificateList, error) {1956 if bytes.HasPrefix(crlBytes, pemCRLPrefix) {1957 block, _ := pem.Decode(crlBytes)1958 if block != nil && block.Type == pemType {1959 crlBytes = block.Bytes1960 }1961 }1962 return ParseDERCRL(crlBytes)1963}19641965// ParseDERCRL parses a DER encoded CRL from the given bytes.1966//1967// Deprecated: Use [ParseRevocationList] instead.1968func ParseDERCRL(derBytes []byte) (*pkix.CertificateList, error) {1969 certList := new(pkix.CertificateList)1970 if rest, err := asn1.Unmarshal(derBytes, certList); err != nil {1971 return nil, err1972 } else if len(rest) != 0 {1973 return nil, errors.New("x509: trailing data after CRL")1974 }1975 return certList, nil1976}19771978// CreateCRL returns a DER encoded CRL, signed by this Certificate, that1979// contains the given list of revoked certificates.1980//1981// Deprecated: this method does not generate an RFC 5280 conformant X.509 v2 CRL.1982// To generate a standards compliant CRL, use [CreateRevocationList] instead.1983func (c *Certificate) CreateCRL(rand io.Reader, priv any, revokedCerts []pkix.RevokedCertificate, now, expiry time.Time) (crlBytes []byte, err error) {1984 key, ok := priv.(crypto.Signer)1985 if !ok {1986 return nil, errors.New("x509: certificate private key does not implement crypto.Signer")1987 }19881989 signatureAlgorithm, algorithmIdentifier, err := signingParamsForKey(key, 0)1990 if err != nil {1991 return nil, err1992 }19931994 // Force revocation times to UTC per RFC 5280.1995 revokedCertsUTC := make([]pkix.RevokedCertificate, len(revokedCerts))1996 for i, rc := range revokedCerts {1997 rc.RevocationTime = rc.RevocationTime.UTC()1998 revokedCertsUTC[i] = rc1999 }
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.