Source File
x509.go
Belonging Package
crypto/x509
package x509
import (
_
_
_
cryptobyte_asn1
)
type pkixPublicKey struct {
Algo pkix.AlgorithmIdentifier
BitString asn1.BitString
}
func ( []byte) ( interface{}, error) {
var publicKeyInfo
if , := asn1.Unmarshal(, &); != nil {
if , := asn1.Unmarshal(, &pkcs1PublicKey{}); == nil {
return nil, errors.New("x509: failed to parse public key (use ParsePKCS1PublicKey instead for this key format)")
}
return nil,
} else if len() != 0 {
return nil, errors.New("x509: trailing data after ASN.1 of public-key")
}
:= getPublicKeyAlgorithmFromOID(.Algorithm.Algorithm)
if == UnknownPublicKeyAlgorithm {
return nil, errors.New("x509: unknown public key algorithm")
}
return parsePublicKey(, &)
}
func ( interface{}) ( []byte, pkix.AlgorithmIdentifier, error) {
switch pub := .(type) {
case *rsa.PublicKey:
, = asn1.Marshal(pkcs1PublicKey{
N: .N,
E: .E,
})
if != nil {
return nil, pkix.AlgorithmIdentifier{},
}
.Parameters = asn1.NullRawValue
case *ecdsa.PublicKey:
= elliptic.Marshal(.Curve, .X, .Y)
, := oidFromNamedCurve(.Curve)
if ! {
return nil, pkix.AlgorithmIdentifier{}, errors.New("x509: unsupported elliptic curve")
}
.Algorithm = oidPublicKeyECDSA
var []byte
, = asn1.Marshal()
if != nil {
return
}
.Parameters.FullBytes =
case ed25519.PublicKey:
=
.Algorithm = oidPublicKeyEd25519
default:
return nil, pkix.AlgorithmIdentifier{}, fmt.Errorf("x509: unsupported public key type: %T", )
}
return , , nil
}
type certificate struct {
Raw asn1.RawContent
TBSCertificate tbsCertificate
SignatureAlgorithm pkix.AlgorithmIdentifier
SignatureValue asn1.BitString
}
type tbsCertificate struct {
Raw asn1.RawContent
Version int `asn1:"optional,explicit,default:0,tag:0"`
SerialNumber *big.Int
SignatureAlgorithm pkix.AlgorithmIdentifier
Issuer asn1.RawValue
Validity validity
Subject asn1.RawValue
PublicKey publicKeyInfo
UniqueId asn1.BitString `asn1:"optional,tag:1"`
SubjectUniqueId asn1.BitString `asn1:"optional,tag:2"`
Extensions []pkix.Extension `asn1:"optional,explicit,tag:3"`
}
type dsaAlgorithmParameters struct {
P, Q, G *big.Int
}
type validity struct {
NotBefore, NotAfter time.Time
}
type publicKeyInfo struct {
Raw asn1.RawContent
Algorithm pkix.AlgorithmIdentifier
PublicKey asn1.BitString
}
type authKeyId struct {
Id []byte `asn1:"optional,tag:0"`
}
type SignatureAlgorithm int
const (
UnknownSignatureAlgorithm SignatureAlgorithm = iota
MD2WithRSA // Unsupported.
MD5WithRSA // Only supported for signing, not verification.
SHA1WithRSA
SHA256WithRSA
SHA384WithRSA
SHA512WithRSA
DSAWithSHA1 // Unsupported.
DSAWithSHA256 // Unsupported.
ECDSAWithSHA1
ECDSAWithSHA256
ECDSAWithSHA384
ECDSAWithSHA512
SHA256WithRSAPSS
SHA384WithRSAPSS
SHA512WithRSAPSS
PureEd25519
)
func ( SignatureAlgorithm) () bool {
switch {
case SHA256WithRSAPSS, SHA384WithRSAPSS, SHA512WithRSAPSS:
return true
default:
return false
}
}
func ( SignatureAlgorithm) () string {
for , := range signatureAlgorithmDetails {
if .algo == {
return .name
}
}
return strconv.Itoa(int())
}
type PublicKeyAlgorithm int
const (
UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
RSA
DSA // Unsupported.
ECDSA
Ed25519
)
var publicKeyAlgoName = [...]string{
RSA: "RSA",
DSA: "DSA",
ECDSA: "ECDSA",
Ed25519: "Ed25519",
}
func ( PublicKeyAlgorithm) () string {
if 0 < && int() < len(publicKeyAlgoName) {
return publicKeyAlgoName[]
}
return strconv.Itoa(int())
}
var (
oidSignatureMD2WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 2}
oidSignatureMD5WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 4}
oidSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}
oidSignatureSHA256WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 11}
oidSignatureSHA384WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 12}
oidSignatureSHA512WithRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 13}
oidSignatureRSAPSS = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 10}
oidSignatureDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 3}
oidSignatureDSAWithSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 3, 2}
oidSignatureECDSAWithSHA1 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 1}
oidSignatureECDSAWithSHA256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 2}
oidSignatureECDSAWithSHA384 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 3}
oidSignatureECDSAWithSHA512 = asn1.ObjectIdentifier{1, 2, 840, 10045, 4, 3, 4}
oidSignatureEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
oidSHA256 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 1}
oidSHA384 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 2}
oidSHA512 = asn1.ObjectIdentifier{2, 16, 840, 1, 101, 3, 4, 2, 3}
oidMGF1 = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 8}
oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
)
var signatureAlgorithmDetails = []struct {
algo SignatureAlgorithm
name string
oid asn1.ObjectIdentifier
pubKeyAlgo PublicKeyAlgorithm
hash crypto.Hash
}{
{MD2WithRSA, "MD2-RSA", oidSignatureMD2WithRSA, RSA, crypto.Hash(0) /* no value for MD2 */},
{MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, RSA, crypto.MD5},
{SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, RSA, crypto.SHA1},
{SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, RSA, crypto.SHA1},
{SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, RSA, crypto.SHA256},
{SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, RSA, crypto.SHA384},
{SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, RSA, crypto.SHA512},
{SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA256},
{SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA384},
{SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, RSA, crypto.SHA512},
{DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, DSA, crypto.SHA1},
{DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, DSA, crypto.SHA256},
{ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, ECDSA, crypto.SHA1},
{ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, ECDSA, crypto.SHA256},
{ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, ECDSA, crypto.SHA384},
{ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, ECDSA, crypto.SHA512},
{PureEd25519, "Ed25519", oidSignatureEd25519, Ed25519, crypto.Hash(0) /* no pre-hashing */},
}
var hashToPSSParameters = map[crypto.Hash]asn1.RawValue{
crypto.SHA256: 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}},
crypto.SHA384: 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}},
crypto.SHA512: 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}},
}
Hash pkix.AlgorithmIdentifier `asn1:"explicit,tag:0"`
MGF pkix.AlgorithmIdentifier `asn1:"explicit,tag:1"`
SaltLength int `asn1:"explicit,tag:2"`
TrailerField int `asn1:"optional,explicit,tag:3,default:1"`
}
func ( pkix.AlgorithmIdentifier) SignatureAlgorithm {
if len(.Parameters.FullBytes) != 0 {
return UnknownSignatureAlgorithm
}
}
if !.Algorithm.Equal(oidSignatureRSAPSS) {
for , := range signatureAlgorithmDetails {
if .Algorithm.Equal(.oid) {
return .algo
}
}
return UnknownSignatureAlgorithm
}
var pssParameters
if , := asn1.Unmarshal(.Parameters.FullBytes, &); != nil {
return UnknownSignatureAlgorithm
}
var pkix.AlgorithmIdentifier
if , := asn1.Unmarshal(.MGF.Parameters.FullBytes, &); != nil {
return UnknownSignatureAlgorithm
}
if (len(.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(.Hash.Parameters.FullBytes, asn1.NullBytes)) ||
!.MGF.Algorithm.Equal(oidMGF1) ||
!.Algorithm.Equal(.Hash.Algorithm) ||
(len(.Parameters.FullBytes) != 0 && !bytes.Equal(.Parameters.FullBytes, asn1.NullBytes)) ||
.TrailerField != 1 {
return UnknownSignatureAlgorithm
}
switch {
case .Hash.Algorithm.Equal(oidSHA256) && .SaltLength == 32:
return SHA256WithRSAPSS
case .Hash.Algorithm.Equal(oidSHA384) && .SaltLength == 48:
return SHA384WithRSAPSS
case .Hash.Algorithm.Equal(oidSHA512) && .SaltLength == 64:
return SHA512WithRSAPSS
}
return UnknownSignatureAlgorithm
}
var (
oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
oidPublicKeyEd25519 = oidSignatureEd25519
)
func ( asn1.ObjectIdentifier) PublicKeyAlgorithm {
switch {
case .Equal(oidPublicKeyRSA):
return RSA
case .Equal(oidPublicKeyDSA):
return DSA
case .Equal(oidPublicKeyECDSA):
return ECDSA
case .Equal(oidPublicKeyEd25519):
return Ed25519
}
return UnknownPublicKeyAlgorithm
}
var (
oidNamedCurveP224 = asn1.ObjectIdentifier{1, 3, 132, 0, 33}
oidNamedCurveP256 = asn1.ObjectIdentifier{1, 2, 840, 10045, 3, 1, 7}
oidNamedCurveP384 = asn1.ObjectIdentifier{1, 3, 132, 0, 34}
oidNamedCurveP521 = asn1.ObjectIdentifier{1, 3, 132, 0, 35}
)
func ( asn1.ObjectIdentifier) elliptic.Curve {
switch {
case .Equal(oidNamedCurveP224):
return elliptic.P224()
case .Equal(oidNamedCurveP256):
return elliptic.P256()
case .Equal(oidNamedCurveP384):
return elliptic.P384()
case .Equal(oidNamedCurveP521):
return elliptic.P521()
}
return nil
}
func ( elliptic.Curve) (asn1.ObjectIdentifier, bool) {
switch {
case elliptic.P224():
return oidNamedCurveP224, true
case elliptic.P256():
return oidNamedCurveP256, true
case elliptic.P384():
return oidNamedCurveP384, true
case elliptic.P521():
return oidNamedCurveP521, true
}
return nil, false
}
var (
oidExtKeyUsageAny = asn1.ObjectIdentifier{2, 5, 29, 37, 0}
oidExtKeyUsageServerAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 1}
oidExtKeyUsageClientAuth = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 2}
oidExtKeyUsageCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 3}
oidExtKeyUsageEmailProtection = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 4}
oidExtKeyUsageIPSECEndSystem = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 5}
oidExtKeyUsageIPSECTunnel = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 6}
oidExtKeyUsageIPSECUser = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 7}
oidExtKeyUsageTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8}
oidExtKeyUsageOCSPSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 9}
oidExtKeyUsageMicrosoftServerGatedCrypto = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 10, 3, 3}
oidExtKeyUsageNetscapeServerGatedCrypto = asn1.ObjectIdentifier{2, 16, 840, 1, 113730, 4, 1}
oidExtKeyUsageMicrosoftCommercialCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 2, 1, 22}
oidExtKeyUsageMicrosoftKernelCodeSigning = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 311, 61, 1, 1}
)
type ExtKeyUsage int
const (
ExtKeyUsageAny ExtKeyUsage = iota
ExtKeyUsageServerAuth
ExtKeyUsageClientAuth
ExtKeyUsageCodeSigning
ExtKeyUsageEmailProtection
ExtKeyUsageIPSECEndSystem
ExtKeyUsageIPSECTunnel
ExtKeyUsageIPSECUser
ExtKeyUsageTimeStamping
ExtKeyUsageOCSPSigning
ExtKeyUsageMicrosoftServerGatedCrypto
ExtKeyUsageNetscapeServerGatedCrypto
ExtKeyUsageMicrosoftCommercialCodeSigning
ExtKeyUsageMicrosoftKernelCodeSigning
)
var extKeyUsageOIDs = []struct {
extKeyUsage ExtKeyUsage
oid asn1.ObjectIdentifier
}{
{ExtKeyUsageAny, oidExtKeyUsageAny},
{ExtKeyUsageServerAuth, oidExtKeyUsageServerAuth},
{ExtKeyUsageClientAuth, oidExtKeyUsageClientAuth},
{ExtKeyUsageCodeSigning, oidExtKeyUsageCodeSigning},
{ExtKeyUsageEmailProtection, oidExtKeyUsageEmailProtection},
{ExtKeyUsageIPSECEndSystem, oidExtKeyUsageIPSECEndSystem},
{ExtKeyUsageIPSECTunnel, oidExtKeyUsageIPSECTunnel},
{ExtKeyUsageIPSECUser, oidExtKeyUsageIPSECUser},
{ExtKeyUsageTimeStamping, oidExtKeyUsageTimeStamping},
{ExtKeyUsageOCSPSigning, oidExtKeyUsageOCSPSigning},
{ExtKeyUsageMicrosoftServerGatedCrypto, oidExtKeyUsageMicrosoftServerGatedCrypto},
{ExtKeyUsageNetscapeServerGatedCrypto, oidExtKeyUsageNetscapeServerGatedCrypto},
{ExtKeyUsageMicrosoftCommercialCodeSigning, oidExtKeyUsageMicrosoftCommercialCodeSigning},
{ExtKeyUsageMicrosoftKernelCodeSigning, oidExtKeyUsageMicrosoftKernelCodeSigning},
}
func ( asn1.ObjectIdentifier) ( ExtKeyUsage, bool) {
for , := range extKeyUsageOIDs {
if .Equal(.oid) {
return .extKeyUsage, true
}
}
return
}
func ( ExtKeyUsage) ( asn1.ObjectIdentifier, bool) {
for , := range extKeyUsageOIDs {
if == .extKeyUsage {
return .oid, true
}
}
return
}
type Certificate struct {
Raw []byte // Complete ASN.1 DER content (certificate, signature algorithm and signature).
RawTBSCertificate []byte // Certificate part of raw ASN.1 DER content.
RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
RawSubject []byte // DER encoded Subject
RawIssuer []byte // DER encoded Issuer
Signature []byte
SignatureAlgorithm SignatureAlgorithm
PublicKeyAlgorithm PublicKeyAlgorithm
PublicKey interface{}
Version int
SerialNumber *big.Int
Issuer pkix.Name
Subject pkix.Name
NotBefore, NotAfter time.Time // Validity bounds.
KeyUsage KeyUsage
UnhandledCriticalExtensions []asn1.ObjectIdentifier
ExtKeyUsage []ExtKeyUsage // Sequence of extended key usages.
UnknownExtKeyUsage []asn1.ObjectIdentifier // Encountered extended key usages unknown to this package.
DNSNames []string
EmailAddresses []string
IPAddresses []net.IP
URIs []*url.URL
PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
PermittedDNSDomains []string
ExcludedDNSDomains []string
PermittedIPRanges []*net.IPNet
ExcludedIPRanges []*net.IPNet
PermittedEmailAddresses []string
ExcludedEmailAddresses []string
PermittedURIDomains []string
ExcludedURIDomains []string
var ErrUnsupportedAlgorithm = errors.New("x509: cannot verify signature: algorithm unimplemented")
type InsecureAlgorithmError SignatureAlgorithm
func ( InsecureAlgorithmError) () string {
return fmt.Sprintf("x509: cannot verify signature: insecure algorithm %v", SignatureAlgorithm())
}
type ConstraintViolationError struct{}
func (ConstraintViolationError) () string {
return "x509: invalid signature: parent certificate cannot sign this kind of certificate"
}
func ( *Certificate) ( *Certificate) bool {
if == nil || == nil {
return ==
}
return bytes.Equal(.Raw, .Raw)
}
func ( *Certificate) () bool {
return oidInExtensions(oidExtensionSubjectAltName, .Extensions)
}
if .Version == 3 && !.BasicConstraintsValid ||
.BasicConstraintsValid && !.IsCA {
return ConstraintViolationError{}
}
if .KeyUsage != 0 && .KeyUsage&KeyUsageCertSign == 0 {
return ConstraintViolationError{}
}
if .PublicKeyAlgorithm == UnknownPublicKeyAlgorithm {
return ErrUnsupportedAlgorithm
}
return .CheckSignature(.SignatureAlgorithm, .RawTBSCertificate, .Signature)
}
func ( *Certificate) ( SignatureAlgorithm, , []byte) error {
return checkSignature(, , , .PublicKey)
}
func ( *Certificate) () bool {
return oidInExtensions(oidExtensionNameConstraints, .Extensions)
}
func ( *Certificate) () []byte {
for , := range .Extensions {
if .Id.Equal(oidExtensionSubjectAltName) {
return .Value
}
}
return nil
}
func ( PublicKeyAlgorithm, interface{}) error {
return fmt.Errorf("x509: signature algorithm specifies an %s public key, but have public key of type %T", .String(), )
}
func ( SignatureAlgorithm, , []byte, crypto.PublicKey) ( error) {
var crypto.Hash
var PublicKeyAlgorithm
for , := range signatureAlgorithmDetails {
if .algo == {
= .hash
= .pubKeyAlgo
}
}
switch {
case crypto.Hash(0):
if != Ed25519 {
return ErrUnsupportedAlgorithm
}
case crypto.MD5:
return InsecureAlgorithmError()
default:
if !.Available() {
return ErrUnsupportedAlgorithm
}
:= .New()
.Write()
= .Sum(nil)
}
switch pub := .(type) {
case *rsa.PublicKey:
if != RSA {
return signaturePublicKeyAlgoMismatchError(, )
}
if .isRSAPSS() {
return rsa.VerifyPSS(, , , , &rsa.PSSOptions{SaltLength: rsa.PSSSaltLengthEqualsHash})
} else {
return rsa.VerifyPKCS1v15(, , , )
}
case *ecdsa.PublicKey:
if != ECDSA {
return signaturePublicKeyAlgoMismatchError(, )
}
if !ecdsa.VerifyASN1(, , ) {
return errors.New("x509: ECDSA verification failure")
}
return
case ed25519.PublicKey:
if != Ed25519 {
return signaturePublicKeyAlgoMismatchError(, )
}
if !ed25519.Verify(, , ) {
return errors.New("x509: Ed25519 verification failure")
}
return
}
return ErrUnsupportedAlgorithm
}
func ( *Certificate) ( *pkix.CertificateList) error {
:= getSignatureAlgorithmFromAI(.SignatureAlgorithm)
return .CheckSignature(, .TBSCertList.Raw, .SignatureValue.RightAlign())
}
type UnhandledCriticalExtension struct{}
func ( UnhandledCriticalExtension) () string {
return "x509: unhandled critical extension"
}
type basicConstraints struct {
IsCA bool `asn1:"optional"`
MaxPathLen int `asn1:"optional,default:-1"`
}
type policyInformation struct {
}
const (
nameTypeEmail = 1
nameTypeDNS = 2
nameTypeURI = 6
nameTypeIP = 7
)
type authorityInfoAccess struct {
Method asn1.ObjectIdentifier
Location asn1.RawValue
}
type distributionPoint struct {
DistributionPoint distributionPointName `asn1:"optional,tag:0"`
Reason asn1.BitString `asn1:"optional,tag:1"`
CRLIssuer asn1.RawValue `asn1:"optional,tag:2"`
}
type distributionPointName struct {
FullName []asn1.RawValue `asn1:"optional,tag:0"`
RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
}
func ( PublicKeyAlgorithm, *publicKeyInfo) (interface{}, error) {
:= .PublicKey.RightAlign()
switch {
if !bytes.Equal(.Algorithm.Parameters.FullBytes, asn1.NullBytes) {
return nil, errors.New("x509: RSA key missing NULL parameters")
}
:= new(pkcs1PublicKey)
, := asn1.Unmarshal(, )
if != nil {
return nil,
}
if len() != 0 {
return nil, errors.New("x509: trailing data after RSA public key")
}
if .N.Sign() <= 0 {
return nil, errors.New("x509: RSA modulus is not a positive number")
}
if .E <= 0 {
return nil, errors.New("x509: RSA public exponent is not a positive number")
}
:= &rsa.PublicKey{
E: .E,
N: .N,
}
return , nil
case DSA:
var *big.Int
, := asn1.Unmarshal(, &)
if != nil {
return nil,
}
if len() != 0 {
return nil, errors.New("x509: trailing data after DSA public key")
}
:= .Algorithm.Parameters.FullBytes
:= new(dsaAlgorithmParameters)
, = asn1.Unmarshal(, )
if != nil {
return nil,
}
if len() != 0 {
return nil, errors.New("x509: trailing data after DSA parameters")
}
if .Sign() <= 0 || .P.Sign() <= 0 || .Q.Sign() <= 0 || .G.Sign() <= 0 {
return nil, errors.New("x509: zero or negative DSA parameter")
}
:= &dsa.PublicKey{
Parameters: dsa.Parameters{
P: .P,
Q: .Q,
G: .G,
},
Y: ,
}
return , nil
case ECDSA:
:= .Algorithm.Parameters.FullBytes
:= new(asn1.ObjectIdentifier)
, := asn1.Unmarshal(, )
if != nil {
return nil, errors.New("x509: failed to parse ECDSA parameters as named curve")
}
if len() != 0 {
return nil, errors.New("x509: trailing data after ECDSA parameters")
}
:= namedCurveFromOID(*)
if == nil {
return nil, errors.New("x509: unsupported elliptic curve")
}
, := elliptic.Unmarshal(, )
if == nil {
return nil, errors.New("x509: failed to unmarshal elliptic curve point")
}
:= &ecdsa.PublicKey{
Curve: ,
X: ,
Y: ,
}
return , nil
if len(.Algorithm.Parameters.FullBytes) != 0 {
return nil, errors.New("x509: Ed25519 key encoded with illegal parameters")
}
if len() != ed25519.PublicKeySize {
return nil, errors.New("x509: wrong Ed25519 public key size")
}
:= make([]byte, ed25519.PublicKeySize)
copy(, )
return ed25519.PublicKey(), nil
default:
return nil, nil
}
}
var asn1.RawValue
, := asn1.Unmarshal(, &)
if != nil {
return
} else if len() != 0 {
return errors.New("x509: trailing data after X.509 extension")
}
if !.IsCompound || .Tag != 16 || .Class != 0 {
return asn1.StructuralError{Msg: "bad SAN sequence"}
}
= .Bytes
for len() > 0 {
var asn1.RawValue
, = asn1.Unmarshal(, &)
if != nil {
return
}
if := (.Tag, .Bytes); != nil {
return
}
}
return nil
}
func ( []byte) (, []string, []net.IP, []*url.URL, error) {
= forEachSAN(, func( int, []byte) error {
switch {
case nameTypeEmail:
:= string()
if := isIA5String(); != nil {
return errors.New("x509: SAN rfc822Name is malformed")
}
= append(, )
case nameTypeDNS:
:= string()
if := isIA5String(); != nil {
return errors.New("x509: SAN dNSName is malformed")
}
= append(, string())
case nameTypeURI:
:= string()
if := isIA5String(); != nil {
return errors.New("x509: SAN uniformResourceIdentifier is malformed")
}
, := url.Parse()
if != nil {
return fmt.Errorf("x509: cannot parse URI %q: %s", , )
}
if len(.Host) > 0 {
if , := domainToReverseLabels(.Host); ! {
return fmt.Errorf("x509: cannot parse URI %q: invalid domain", )
}
}
= append(, )
case nameTypeIP:
switch len() {
case net.IPv4len, net.IPv6len:
= append(, )
default:
return errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len()))
}
}
return nil
})
return
}
:= cryptobyte.String(.Value)
var , , cryptobyte.String
var , bool
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) ||
!.Empty() ||
!.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(0).ContextSpecific().Constructed()) ||
!.ReadOptionalASN1(&, &, cryptobyte_asn1.Tag(1).ContextSpecific().Constructed()) ||
!.Empty() {
return false, errors.New("x509: invalid NameConstraints extension")
}
return false, errors.New("x509: empty name constraints extension")
}
:= func( cryptobyte.String) ( []string, []*net.IPNet, , []string, error) {
for !.Empty() {
var , cryptobyte.String
var cryptobyte_asn1.Tag
if !.ReadASN1(&, cryptobyte_asn1.SEQUENCE) ||
!.ReadAnyASN1(&, &) {
return nil, nil, nil, nil, fmt.Errorf("x509: invalid NameConstraints extension")
}
var (
= cryptobyte_asn1.Tag(2).ContextSpecific()
= cryptobyte_asn1.Tag(1).ContextSpecific()
= cryptobyte_asn1.Tag(7).ContextSpecific()
= cryptobyte_asn1.Tag(6).ContextSpecific()
)
switch {
case :
:= string()
if := isIA5String(); != nil {
return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error())
}
:=
= [1:]
}
if , := domainToReverseLabels(); ! {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", )
}
= append(, )
case :
:= len()
var , []byte
switch {
case 8:
= [:4]
= [4:]
case 32:
= [:16]
= [16:]
default:
return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained value of length %d", )
}
if !isValidIPMask() {
return nil, nil, nil, nil, fmt.Errorf("x509: IP constraint contained invalid mask %x", )
}
= append(, &net.IPNet{IP: net.IP(), Mask: net.IPMask()})
case :
:= string()
if := isIA5String(); != nil {
return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error())
}
:=
if len() > 0 && [0] == '.' {
= [1:]
}
if , := domainToReverseLabels(); ! {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", )
}
}
= append(, )
case :
:= string()
if := isIA5String(); != nil {
return nil, nil, nil, nil, errors.New("x509: invalid constraint value: " + .Error())
}
if net.ParseIP() != nil {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q: cannot be IP address", )
}
:=
= [1:]
}
if , := domainToReverseLabels(); ! {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", )
}
= append(, )
default:
= true
}
}
return , , , , nil
}
if .PermittedDNSDomains, .PermittedIPRanges, .PermittedEmailAddresses, .PermittedURIDomains, = (); != nil {
return false,
}
if .ExcludedDNSDomains, .ExcludedIPRanges, .ExcludedEmailAddresses, .ExcludedURIDomains, = (); != nil {
return false,
}
.PermittedDNSDomainsCritical = .Critical
return , nil
}
func ( *certificate) (*Certificate, error) {
:= new(Certificate)
.Raw = .Raw
.RawTBSCertificate = .TBSCertificate.Raw
.RawSubjectPublicKeyInfo = .TBSCertificate.PublicKey.Raw
.RawSubject = .TBSCertificate.Subject.FullBytes
.RawIssuer = .TBSCertificate.Issuer.FullBytes
.Signature = .SignatureValue.RightAlign()
.SignatureAlgorithm =
getSignatureAlgorithmFromAI(.TBSCertificate.SignatureAlgorithm)
.PublicKeyAlgorithm =
getPublicKeyAlgorithmFromOID(.TBSCertificate.PublicKey.Algorithm.Algorithm)
var error
.PublicKey, = parsePublicKey(.PublicKeyAlgorithm, &.TBSCertificate.PublicKey)
if != nil {
return nil,
}
.Version = .TBSCertificate.Version + 1
.SerialNumber = .TBSCertificate.SerialNumber
var , pkix.RDNSequence
if , := asn1.Unmarshal(.TBSCertificate.Subject.FullBytes, &); != nil {
return nil,
} else if len() != 0 {
return nil, errors.New("x509: trailing data after X.509 subject")
}
if , := asn1.Unmarshal(.TBSCertificate.Issuer.FullBytes, &); != nil {
return nil,
} else if len() != 0 {
return nil, errors.New("x509: trailing data after X.509 issuer")
}
.Issuer.FillFromRDNSequence(&)
.Subject.FillFromRDNSequence(&)
.NotBefore = .TBSCertificate.Validity.NotBefore
.NotAfter = .TBSCertificate.Validity.NotAfter
for , := range .TBSCertificate.Extensions {
.Extensions = append(.Extensions, )
:= false
if len(.Id) == 4 && .Id[0] == 2 && .Id[1] == 5 && .Id[2] == 29 {
switch .Id[3] {
case 15:
.KeyUsage, = parseKeyUsageExtension(.Value)
if != nil {
return nil,
}
case 19:
.IsCA, .MaxPathLen, = parseBasicConstraintsExtension(.Value)
if != nil {
return nil,
}
.BasicConstraintsValid = true
.MaxPathLenZero = .MaxPathLen == 0
case 17:
.DNSNames, .EmailAddresses, .IPAddresses, .URIs, = parseSANExtension(.Value)
if != nil {
return nil,
}
= true
}
case 30:
, = parseNameConstraintsExtension(, )
if != nil {
return nil,
}
if len(.DistributionPoint.FullName) == 0 {
continue
}
for , := range .DistributionPoint.FullName {
if .Tag == 6 {
.CRLDistributionPoints = append(.CRLDistributionPoints, string(.Bytes))
}
}
}
var authKeyId
if , := asn1.Unmarshal(.Value, &); != nil {
return nil,
} else if len() != 0 {
return nil, errors.New("x509: trailing data after X.509 authority key-id")
}
.AuthorityKeyId = .Id
case 37:
.ExtKeyUsage, .UnknownExtKeyUsage, = parseExtKeyUsageExtension(.Value)
if != nil {
return nil,
}
case 14:
.SubjectKeyId, = parseSubjectKeyIdExtension(.Value)
if != nil {
return nil,
}
case 32:
.PolicyIdentifiers, = parseCertificatePoliciesExtension(.Value)
if != nil {
return nil,
}
= true
}
if .Location.Tag != 6 {
continue
}
if .Method.Equal(oidAuthorityInfoAccessOcsp) {
.OCSPServer = append(.OCSPServer, string(.Location.Bytes))
} else if .Method.Equal(oidAuthorityInfoAccessIssuers) {
.IssuingCertificateURL = append(.IssuingCertificateURL, string(.Location.Bytes))
}
}
= true
}
if .Critical && {
.UnhandledCriticalExtensions = append(.UnhandledCriticalExtensions, .Id)
}
}
return , nil
}
return .IsCA, .MaxPathLen, nil
}
func ( []byte) ([]ExtKeyUsage, []asn1.ObjectIdentifier, error) {
var []asn1.ObjectIdentifier
if , := asn1.Unmarshal(, &); != nil {
return nil, nil,
} else if len() != 0 {
return nil, nil, errors.New("x509: trailing data after X.509 ExtendedKeyUsage")
}
var []ExtKeyUsage
var []asn1.ObjectIdentifier
for , := range {
if , := extKeyUsageFromOID(); {
= append(, )
} else {
= append(, )
}
}
return , , nil
}
func ( []byte) ([]byte, error) {
var []byte
if , := asn1.Unmarshal(, &); != nil {
return nil,
} else if len() != 0 {
return nil, errors.New("x509: trailing data after X.509 key-id")
}
return , nil
}
func ( []byte) ([]asn1.ObjectIdentifier, error) {
var []policyInformation
if , := asn1.Unmarshal(, &); != nil {
return nil,
} else if len() != 0 {
return nil, errors.New("x509: trailing data after X.509 certificate policies")
}
:= make([]asn1.ObjectIdentifier, len())
for , := range {
[] = .Policy
}
return , nil
}
func ( []byte) (*Certificate, error) {
var certificate
, := asn1.Unmarshal(, &)
if != nil {
return nil,
}
if len() > 0 {
return nil, asn1.SyntaxError{Msg: "trailing data"}
}
return parseCertificate(&)
}
func ( []byte) ([]*Certificate, error) {
var []*certificate
for len() > 0 {
:= new(certificate)
var error
, = asn1.Unmarshal(, )
if != nil {
return nil,
}
= append(, )
}
:= make([]*Certificate, len())
for , := range {
, := parseCertificate()
if != nil {
return nil,
}
[] =
}
return , nil
}
func ( byte) byte {
:= >>4 | <<4
:= >>2&0x33 | <<2&0xcc
:= >>1&0x55 | <<1&0xaa
return
}
func ( []byte) int {
:= len() * 8
for := range {
:= [len()--1]
for := uint(0); < 8; ++ {
if (>>)&1 == 1 {
return
}
--
}
}
return 0
}
var (
oidExtensionSubjectKeyId = []int{2, 5, 29, 14}
oidExtensionKeyUsage = []int{2, 5, 29, 15}
oidExtensionExtendedKeyUsage = []int{2, 5, 29, 37}
oidExtensionAuthorityKeyId = []int{2, 5, 29, 35}
oidExtensionBasicConstraints = []int{2, 5, 29, 19}
oidExtensionSubjectAltName = []int{2, 5, 29, 17}
oidExtensionCertificatePolicies = []int{2, 5, 29, 32}
oidExtensionNameConstraints = []int{2, 5, 29, 30}
oidExtensionCRLDistributionPoints = []int{2, 5, 29, 31}
oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
oidExtensionCRLNumber = []int{2, 5, 29, 20}
)
var (
oidAuthorityInfoAccessOcsp = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1}
oidAuthorityInfoAccessIssuers = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 2}
)
func (, []string, []net.IP, []*url.URL) ( []byte, error) {
var []asn1.RawValue
for , := range {
if := isIA5String(); != nil {
return nil,
}
= append(, asn1.RawValue{Tag: nameTypeDNS, Class: 2, Bytes: []byte()})
}
for , := range {
if := isIA5String(); != nil {
return nil,
}
= append(, asn1.RawValue{Tag: nameTypeEmail, Class: 2, Bytes: []byte()})
}
if > unicode.MaxASCII {
return fmt.Errorf("x509: %q cannot be encoded as an IA5String", )
}
}
return nil
}
func ( *Certificate, bool, []byte, []byte) ( []pkix.Extension, error) {
= make([]pkix.Extension, 10 /* maximum number of elements. */)
:= 0
if .KeyUsage != 0 &&
!oidInExtensions(oidExtensionKeyUsage, .ExtraExtensions) {
[], = marshalKeyUsage(.KeyUsage)
if != nil {
return nil,
}
++
}
if (len(.ExtKeyUsage) > 0 || len(.UnknownExtKeyUsage) > 0) &&
!oidInExtensions(oidExtensionExtendedKeyUsage, .ExtraExtensions) {
[], = marshalExtKeyUsage(.ExtKeyUsage, .UnknownExtKeyUsage)
if != nil {
return nil,
}
++
}
if .BasicConstraintsValid && !oidInExtensions(oidExtensionBasicConstraints, .ExtraExtensions) {
[], = marshalBasicConstraints(.IsCA, .MaxPathLen, .MaxPathLenZero)
if != nil {
return nil,
}
++
}
if len() > 0 && !oidInExtensions(oidExtensionSubjectKeyId, .ExtraExtensions) {
[].Id = oidExtensionSubjectKeyId
[].Value, = asn1.Marshal()
if != nil {
return
}
++
}
if len() > 0 && !oidInExtensions(oidExtensionAuthorityKeyId, .ExtraExtensions) {
[].Id = oidExtensionAuthorityKeyId
[].Value, = asn1.Marshal(authKeyId{})
if != nil {
return
}
++
}
if (len(.OCSPServer) > 0 || len(.IssuingCertificateURL) > 0) &&
!oidInExtensions(oidExtensionAuthorityInfoAccess, .ExtraExtensions) {
[].Id = oidExtensionAuthorityInfoAccess
var []authorityInfoAccess
for , := range .OCSPServer {
= append(, authorityInfoAccess{
Method: oidAuthorityInfoAccessOcsp,
Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte()},
})
}
for , := range .IssuingCertificateURL {
= append(, authorityInfoAccess{
Method: oidAuthorityInfoAccessIssuers,
Location: asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte()},
})
}
[].Value, = asn1.Marshal()
if != nil {
return
}
++
}
if (len(.DNSNames) > 0 || len(.EmailAddresses) > 0 || len(.IPAddresses) > 0 || len(.URIs) > 0) &&
!oidInExtensions(oidExtensionSubjectAltName, .ExtraExtensions) {
[].Critical =
[].Value, = marshalSANs(.DNSNames, .EmailAddresses, .IPAddresses, .URIs)
if != nil {
return
}
++
}
if len(.PolicyIdentifiers) > 0 &&
!oidInExtensions(oidExtensionCertificatePolicies, .ExtraExtensions) {
[], = marshalCertificatePolicies(.PolicyIdentifiers)
if != nil {
return nil,
}
++
}
if (len(.PermittedDNSDomains) > 0 || len(.ExcludedDNSDomains) > 0 ||
len(.PermittedIPRanges) > 0 || len(.ExcludedIPRanges) > 0 ||
len(.PermittedEmailAddresses) > 0 || len(.ExcludedEmailAddresses) > 0 ||
len(.PermittedURIDomains) > 0 || len(.ExcludedURIDomains) > 0) &&
!oidInExtensions(oidExtensionNameConstraints, .ExtraExtensions) {
[].Id = oidExtensionNameConstraints
[].Critical = .PermittedDNSDomainsCritical
:= func( *net.IPNet) []byte {
:= .IP.Mask(.Mask)
:= make([]byte, 0, len()+len(.Mask))
= append(, ...)
= append(, .Mask...)
return
}
:= func( []string, []*net.IPNet, []string, []string) ( []byte, error) {
var cryptobyte.Builder
for , := range {
if = isIA5String(); != nil {
return nil,
}
.AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) {
.AddASN1(cryptobyte_asn1.Tag(2).ContextSpecific(), func( *cryptobyte.Builder) {
.AddBytes([]byte())
})
})
}
for , := range {
.AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) {
.AddASN1(cryptobyte_asn1.Tag(7).ContextSpecific(), func( *cryptobyte.Builder) {
.AddBytes(())
})
})
}
for , := range {
if = isIA5String(); != nil {
return nil,
}
.AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) {
.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific(), func( *cryptobyte.Builder) {
.AddBytes([]byte())
})
})
}
for , := range {
if = isIA5String(); != nil {
return nil,
}
.AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) {
.AddASN1(cryptobyte_asn1.Tag(6).ContextSpecific(), func( *cryptobyte.Builder) {
.AddBytes([]byte())
})
})
}
return .Bytes()
}
, := (.PermittedDNSDomains, .PermittedIPRanges, .PermittedEmailAddresses, .PermittedURIDomains)
if != nil {
return nil,
}
, := (.ExcludedDNSDomains, .ExcludedIPRanges, .ExcludedEmailAddresses, .ExcludedURIDomains)
if != nil {
return nil,
}
var cryptobyte.Builder
.AddASN1(cryptobyte_asn1.SEQUENCE, func( *cryptobyte.Builder) {
if len() > 0 {
.AddASN1(cryptobyte_asn1.Tag(0).ContextSpecific().Constructed(), func( *cryptobyte.Builder) {
.AddBytes()
})
}
if len() > 0 {
.AddASN1(cryptobyte_asn1.Tag(1).ContextSpecific().Constructed(), func( *cryptobyte.Builder) {
.AddBytes()
})
}
})
[].Value, = .Bytes()
if != nil {
return nil,
}
++
}
if len(.CRLDistributionPoints) > 0 &&
!oidInExtensions(oidExtensionCRLDistributionPoints, .ExtraExtensions) {
[].Id = oidExtensionCRLDistributionPoints
var []distributionPoint
for , := range .CRLDistributionPoints {
:= distributionPoint{
DistributionPoint: distributionPointName{
FullName: []asn1.RawValue{
{Tag: 6, Class: 2, Bytes: []byte()},
},
},
}
= append(, )
}
[].Value, = asn1.Marshal()
if != nil {
return
}
++
}
return append([:], .ExtraExtensions...), nil
}
func ( KeyUsage) (pkix.Extension, error) {
:= pkix.Extension{Id: oidExtensionKeyUsage, Critical: true}
var [2]byte
[0] = reverseBitsInAByte(byte())
[1] = reverseBitsInAByte(byte( >> 8))
:= 1
if [1] != 0 {
= 2
}
:= [:]
var error
.Value, = asn1.Marshal(asn1.BitString{Bytes: , BitLength: asn1BitLength()})
if != nil {
return ,
}
return , nil
}
func ( []ExtKeyUsage, []asn1.ObjectIdentifier) (pkix.Extension, error) {
:= pkix.Extension{Id: oidExtensionExtendedKeyUsage}
:= make([]asn1.ObjectIdentifier, len()+len())
for , := range {
if , := oidFromExtKeyUsage(); {
[] =
} else {
return , errors.New("x509: unknown extended key usage")
}
}
copy([len():], )
var error
.Value, = asn1.Marshal()
if != nil {
return ,
}
return , nil
}
func ( bool, int, bool) (pkix.Extension, error) {
if == 0 && ! {
= -1
}
var error
.Value, = asn1.Marshal(basicConstraints{, })
if != nil {
return , nil
}
return , nil
}
func ( []asn1.ObjectIdentifier) (pkix.Extension, error) {
:= pkix.Extension{Id: oidExtensionCertificatePolicies}
:= make([]policyInformation, len())
for , := range {
[].Policy =
}
var error
.Value, = asn1.Marshal()
if != nil {
return ,
}
return , nil
}
func ( *CertificateRequest) ([]pkix.Extension, error) {
var []pkix.Extension
if (len(.DNSNames) > 0 || len(.EmailAddresses) > 0 || len(.IPAddresses) > 0 || len(.URIs) > 0) &&
!oidInExtensions(oidExtensionSubjectAltName, .ExtraExtensions) {
, := marshalSANs(.DNSNames, .EmailAddresses, .IPAddresses, .URIs)
if != nil {
return nil,
}
= append(, pkix.Extension{
Id: oidExtensionSubjectAltName,
Value: ,
})
}
return append(, .ExtraExtensions...), nil
}
func ( *Certificate) ([]byte, error) {
if len(.RawSubject) > 0 {
return .RawSubject, nil
}
return asn1.Marshal(.Subject.ToRDNSequence())
}
func ( interface{}, SignatureAlgorithm) ( crypto.Hash, pkix.AlgorithmIdentifier, error) {
var PublicKeyAlgorithm
switch pub := .(type) {
case *rsa.PublicKey:
= RSA
= crypto.SHA256
.Algorithm = oidSignatureSHA256WithRSA
.Parameters = asn1.NullRawValue
case *ecdsa.PublicKey:
= ECDSA
switch .Curve {
case elliptic.P224(), elliptic.P256():
= crypto.SHA256
.Algorithm = oidSignatureECDSAWithSHA256
case elliptic.P384():
= crypto.SHA384
.Algorithm = oidSignatureECDSAWithSHA384
case elliptic.P521():
= crypto.SHA512
.Algorithm = oidSignatureECDSAWithSHA512
default:
= errors.New("x509: unknown elliptic curve")
}
case ed25519.PublicKey:
= Ed25519
.Algorithm = oidSignatureEd25519
default:
= errors.New("x509: only RSA, ECDSA and Ed25519 keys supported")
}
if != nil {
return
}
if == 0 {
return
}
:= false
for , := range signatureAlgorithmDetails {
if .algo == {
if .pubKeyAlgo != {
= errors.New("x509: requested SignatureAlgorithm does not match private key type")
return
}
.Algorithm, = .oid, .hash
if == 0 && != Ed25519 {
= errors.New("x509: cannot sign with hash function requested")
return
}
if .isRSAPSS() {
.Parameters = hashToPSSParameters[]
}
= true
break
}
}
if ! {
= errors.New("x509: unknown SignatureAlgorithm")
}
return
}
var emptyASN1Subject = []byte{0x30, 0}
func ( io.Reader, , *Certificate, , interface{}) ( []byte, error) {
, := .(crypto.Signer)
if ! {
return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
}
if .SerialNumber == nil {
return nil, errors.New("x509: no SerialNumber given")
}
if .BasicConstraintsValid && !.IsCA && .MaxPathLen != -1 && (.MaxPathLen != 0 || .MaxPathLenZero) {
return nil, errors.New("x509: only CAs are allowed to specify MaxPathLen")
}
, , := signingParamsForPublicKey(.Public(), .SignatureAlgorithm)
if != nil {
return nil,
}
, , := marshalPublicKey()
if != nil {
return nil,
}
, := subjectBytes()
if != nil {
return
}
, := subjectBytes()
if != nil {
return
}
:= .AuthorityKeyId
if !bytes.Equal(, ) && len(.SubjectKeyId) > 0 {
= .SubjectKeyId
}
:= .SubjectKeyId
:= sha1.Sum()
= [:]
}
, := buildCertExtensions(, bytes.Equal(, emptyASN1Subject), , )
if != nil {
return
}
:= asn1.BitString{BitLength: len() * 8, Bytes: }
:= tbsCertificate{
Version: 2,
SerialNumber: .SerialNumber,
SignatureAlgorithm: ,
Issuer: asn1.RawValue{FullBytes: },
Validity: validity{.NotBefore.UTC(), .NotAfter.UTC()},
Subject: asn1.RawValue{FullBytes: },
PublicKey: publicKeyInfo{nil, , },
Extensions: ,
}
, := asn1.Marshal()
if != nil {
return
}
.Raw =
:=
if != 0 {
:= .New()
.Write()
= .Sum(nil)
}
var crypto.SignerOpts =
if .SignatureAlgorithm != 0 && .SignatureAlgorithm.isRSAPSS() {
= &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
Hash: ,
}
}
var []byte
, = .Sign(, , )
if != nil {
return
}
, := asn1.Marshal(certificate{
nil,
,
,
asn1.BitString{Bytes: , BitLength: len() * 8},
})
if != nil {
return nil,
}
if := getSignatureAlgorithmFromAI(); != MD5WithRSA {
if := checkSignature(, .Raw, , .Public()); != nil {
return nil, fmt.Errorf("x509: signature over certificate returned by signer is invalid: %w", )
}
}
return , nil
}
var pemCRLPrefix = []byte("-----BEGIN X509 CRL")
var pemType = "X509 CRL"
func ( []byte) (*pkix.CertificateList, error) {
if bytes.HasPrefix(, pemCRLPrefix) {
, := pem.Decode()
if != nil && .Type == pemType {
= .Bytes
}
}
return ParseDERCRL()
}
:= make([]pkix.RevokedCertificate, len())
for , := range {
.RevocationTime = .RevocationTime.UTC()
[] =
}
:= pkix.TBSCertificateList{
Version: 1,
Signature: ,
Issuer: .Subject.ToRDNSequence(),
ThisUpdate: .UTC(),
NextUpdate: .UTC(),
RevokedCertificates: ,
}
if len(.SubjectKeyId) > 0 {
var pkix.Extension
.Id = oidExtensionAuthorityKeyId
.Value, = asn1.Marshal(authKeyId{Id: .SubjectKeyId})
if != nil {
return
}
.Extensions = append(.Extensions, )
}
, := asn1.Marshal()
if != nil {
return
}
:=
if != 0 {
:= .New()
.Write()
= .Sum(nil)
}
var []byte
, = .Sign(, , )
if != nil {
return
}
return asn1.Marshal(pkix.CertificateList{
TBSCertList: ,
SignatureAlgorithm: ,
SignatureValue: asn1.BitString{Bytes: , BitLength: len() * 8},
})
}
type CertificateRequest struct {
Raw []byte // Complete ASN.1 DER content (CSR, signature algorithm and signature).
RawTBSCertificateRequest []byte // Certificate request info part of raw ASN.1 DER content.
RawSubjectPublicKeyInfo []byte // DER encoded SubjectPublicKeyInfo.
RawSubject []byte // DER encoded Subject.
Version int
Signature []byte
SignatureAlgorithm SignatureAlgorithm
PublicKeyAlgorithm PublicKeyAlgorithm
PublicKey interface{}
Subject pkix.Name
DNSNames []string
EmailAddresses []string
IPAddresses []net.IP
URIs []*url.URL
}
type tbsCertificateRequest struct {
Raw asn1.RawContent
Version int
Subject asn1.RawValue
PublicKey publicKeyInfo
RawAttributes []asn1.RawValue `asn1:"tag:0"`
}
type certificateRequest struct {
Raw asn1.RawContent
TBSCSR tbsCertificateRequest
SignatureAlgorithm pkix.AlgorithmIdentifier
SignatureValue asn1.BitString
}
var oidExtensionRequest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 14}
func ( []asn1.RawValue) []pkix.AttributeTypeAndValueSET {
var []pkix.AttributeTypeAndValueSET
for , := range {
var pkix.AttributeTypeAndValueSET
func ( io.Reader, *CertificateRequest, interface{}) ( []byte, error) {
, := .(crypto.Signer)
if ! {
return nil, errors.New("x509: certificate private key does not implement crypto.Signer")
}
var crypto.Hash
var pkix.AlgorithmIdentifier
, , = signingParamsForPublicKey(.Public(), .SignatureAlgorithm)
if != nil {
return nil,
}
var []byte
var pkix.AlgorithmIdentifier
, , = marshalPublicKey(.Public())
if != nil {
return nil,
}
, := buildCSRExtensions()
if != nil {
return nil,
}
:= make([]pkix.AttributeTypeAndValueSET, 0, len(.Attributes))
for , := range .Attributes {
:= make([][]pkix.AttributeTypeAndValue, len(.Value))
copy(, .Value)
= append(, pkix.AttributeTypeAndValueSET{
Type: .Type,
Value: ,
})
}
:= false
for , := range {
if !.Type.Equal(oidExtensionRequest) || len(.Value) == 0 {
continue
}
continue
}
if len() > 0 && ! {
:= struct {
asn1.ObjectIdentifier
[][]pkix.Extension `asn1:"set"`
}{
: oidExtensionRequest,
: [][]pkix.Extension{},
}
, := asn1.Marshal()
if != nil {
return nil, errors.New("x509: failed to serialise extensions attribute: " + .Error())
}
var asn1.RawValue
if , := asn1.Unmarshal(, &); != nil {
return nil,
}
= append(, )
}
:= .RawSubject
if len() == 0 {
, = asn1.Marshal(.Subject.ToRDNSequence())
if != nil {
return nil,
}
}
:= tbsCertificateRequest{
Version: 0, // PKCS #10, RFC 2986
Subject: asn1.RawValue{FullBytes: },
PublicKey: publicKeyInfo{
Algorithm: ,
PublicKey: asn1.BitString{
Bytes: ,
BitLength: len() * 8,
},
},
RawAttributes: ,
}
, := asn1.Marshal()
if != nil {
return
}
.Raw =
:=
if != 0 {
:= .New()
.Write()
= .Sum(nil)
}
var []byte
, = .Sign(, , )
if != nil {
return
}
return asn1.Marshal(certificateRequest{
TBSCSR: ,
SignatureAlgorithm: ,
SignatureValue: asn1.BitString{
Bytes: ,
BitLength: len() * 8,
},
})
}
func ( []byte) (*CertificateRequest, error) {
var certificateRequest
, := asn1.Unmarshal(, &)
if != nil {
return nil,
} else if len() != 0 {
return nil, asn1.SyntaxError{Msg: "trailing data"}
}
return parseCertificateRequest(&)
}
func ( *certificateRequest) (*CertificateRequest, error) {
:= &CertificateRequest{
Raw: .Raw,
RawTBSCertificateRequest: .TBSCSR.Raw,
RawSubjectPublicKeyInfo: .TBSCSR.PublicKey.Raw,
RawSubject: .TBSCSR.Subject.FullBytes,
Signature: .SignatureValue.RightAlign(),
SignatureAlgorithm: getSignatureAlgorithmFromAI(.SignatureAlgorithm),
PublicKeyAlgorithm: getPublicKeyAlgorithmFromOID(.TBSCSR.PublicKey.Algorithm.Algorithm),
Version: .TBSCSR.Version,
Attributes: parseRawAttributes(.TBSCSR.RawAttributes),
}
var error
.PublicKey, = parsePublicKey(.PublicKeyAlgorithm, &.TBSCSR.PublicKey)
if != nil {
return nil,
}
var pkix.RDNSequence
if , := asn1.Unmarshal(.TBSCSR.Subject.FullBytes, &); != nil {
return nil,
} else if len() != 0 {
return nil, errors.New("x509: trailing data after X.509 Subject")
}
.Subject.FillFromRDNSequence(&)
if .Extensions, = parseCSRExtensions(.TBSCSR.RawAttributes); != nil {
return nil,
}
for , := range .Extensions {
switch {
case .Id.Equal(oidExtensionSubjectAltName):
.DNSNames, .EmailAddresses, .IPAddresses, .URIs, = parseSANExtension(.Value)
if != nil {
return nil,
}
}
}
return , nil
}
func ( *CertificateRequest) () error {
return checkSignature(.SignatureAlgorithm, .RawTBSCertificateRequest, .Signature, .PublicKey)
}
func ( io.Reader, *RevocationList, *Certificate, crypto.Signer) ([]byte, error) {
if == nil {
return nil, errors.New("x509: template can not be nil")
}
if == nil {
return nil, errors.New("x509: issuer can not be nil")
}
if (.KeyUsage & KeyUsageCRLSign) == 0 {
return nil, errors.New("x509: issuer must have the crlSign key usage bit set")
}
if len(.SubjectKeyId) == 0 {
return nil, errors.New("x509: issuer certificate doesn't contain a subject key identifier")
}
if .NextUpdate.Before(.ThisUpdate) {
return nil, errors.New("x509: template.ThisUpdate is after template.NextUpdate")
}
if .Number == nil {
return nil, errors.New("x509: template contains nil Number field")
}
, , := signingParamsForPublicKey(.Public(), .SignatureAlgorithm)
if != nil {
return nil,
}
:= make([]pkix.RevokedCertificate, len(.RevokedCertificates))
for , := range .RevokedCertificates {
.RevocationTime = .RevocationTime.UTC()
[] =
}
, := asn1.Marshal(authKeyId{Id: .SubjectKeyId})
if != nil {
return nil,
}
, := asn1.Marshal(.Number)
if != nil {
return nil,
}
:= pkix.TBSCertificateList{
Version: 1, // v2
Signature: ,
Issuer: .Subject.ToRDNSequence(),
ThisUpdate: .ThisUpdate.UTC(),
NextUpdate: .NextUpdate.UTC(),
Extensions: []pkix.Extension{
{
Id: oidExtensionAuthorityKeyId,
Value: ,
},
{
Id: oidExtensionCRLNumber,
Value: ,
},
},
}
if len() > 0 {
.RevokedCertificates =
}
if len(.ExtraExtensions) > 0 {
.Extensions = append(.Extensions, .ExtraExtensions...)
}
, := asn1.Marshal()
if != nil {
return nil,
}
:=
if != 0 {
:= .New()
.Write()
= .Sum(nil)
}
var crypto.SignerOpts =
if .SignatureAlgorithm.isRSAPSS() {
= &rsa.PSSOptions{
SaltLength: rsa.PSSSaltLengthEqualsHash,
Hash: ,
}
}
, := .Sign(, , )
if != nil {
return nil,
}
return asn1.Marshal(pkix.CertificateList{
TBSCertList: ,
SignatureAlgorithm: ,
SignatureValue: asn1.BitString{Bytes: , BitLength: len() * 8},
})
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |