src/crypto/x509/x509.go GO 2,722 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 2,722.
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, &params); 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	}

Code quality findings 34

Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Ensure errors are handled or logged
warning correctness unhandled-error
if err != nil {
Type switch without default case; unhandled types will silently do nothing. Add a default case for safety
info correctness unchecked-type-switch
switch pub := pub.(type) {
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte(name)})
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte(email)})
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeIP, Class: 2, Bytes: ip})
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uriStr)})
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
rawValues = append(rawValues, asn1.RawValue{Tag: nameTypeURI, Class: 2, Bytes: []byte(uriStr)})
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
aiaValues = append(aiaValues, authorityInfoAccess{
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
aiaValues = append(aiaValues, authorityInfoAccess{
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)},
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
b.AddBytes([]byte(name))
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
b.AddBytes([]byte(email))
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
b.AddBytes([]byte(uriDomain))
String to byte slice conversion inside loop allocates a new slice each iteration; convert once before the loop
info correctness string-to-byte-in-loop
{Tag: 6, Class: 2, Bytes: []byte(name)},
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
crlDp = append(crlDp, dp)
Range over slice copies each element by value; use index or pointer receiver for large structs to avoid copies
info performance copy-large-struct
for i, u := range extUsages {
Deeply nested control structures reduce readability; consider extracting to functions or using early returns
info maintainability deep-nesting
if x509usepolicies.Value() != "0" {
Deeply nested control structures reduce readability; consider extracting to functions or using early returns
info maintainability deep-nesting
for _, v := range policies {
Deeply nested control structures reduce readability; consider extracting to functions or using early returns
info maintainability deep-nesting
if len(v.der) == 0 {
Type switch without default case; unhandled types will silently do nothing. Add a default case for safety
info correctness unchecked-type-switch
switch pub := key.Public().(type) {
Range over slice copies each element by value; use index or pointer receiver for large structs to avoid copies
info performance copy-large-struct
for i, rc := range revokedCerts {
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
attributes = append(attributes, attr)
Map created without size hint before being populated in a loop; provide capacity hint to reduce allocations
info performance map-without-size-hint
requestedExts := make(map[string]bool)
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
ret = append(ret, extensions...)
Map created without size hint before being populated in a loop; provide capacity hint to reduce allocations
info performance map-without-size-hint
specifiedExtensions := make(map[string]bool)
Range over slice copies each element by value; use index or pointer receiver for large structs to avoid copies
info performance copy-large-struct
for i, rc := range template.RevokedCertificates {
Range over slice copies each element by value; use index or pointer receiver for large structs to avoid copies
info performance copy-large-struct
for i, rce := range template.RevokedCertificateEntries {
Multiple appends without pre-allocation; use make() with capacity when size is known
info performance append-without-prealloc
exts = append(exts, ext)

Security findings 2

Weak cryptographic hash (MD5/SHA1); use SHA-256 or stronger for security-sensitive contexts
security weak-crypto
"crypto/sha1"
Weak cryptographic hash (MD5/SHA1); use SHA-256 or stronger for security-sensitive contexts
security weak-crypto
_ "crypto/sha1"

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.