489 lines
19 KiB
Go
489 lines
19 KiB
Go
// Copyright 2009 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Package x509 implements a subset of the X.509 standard.
|
|
//
|
|
// It allows parsing and generating certificates, certificate signing
|
|
// requests, certificate revocation lists, and encoded public and private keys.
|
|
// It provides a certificate verifier, complete with a chain builder.
|
|
//
|
|
// The package targets the X.509 technical profile defined by the IETF (RFC
|
|
// 2459/3280/5280), and as further restricted by the CA/Browser Forum Baseline
|
|
// Requirements. There is minimal support for features outside of these
|
|
// profiles, as the primary goal of the package is to provide compatibility
|
|
// with the publicly trusted TLS certificate ecosystem and its policies and
|
|
// constraints.
|
|
//
|
|
// On macOS and Windows, certificate verification is handled by system APIs, but
|
|
// the package aims to apply consistent validation rules across operating
|
|
// systems.
|
|
package legacyx509
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto"
|
|
"crypto/elliptic"
|
|
stdx509 "crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/asn1"
|
|
"fmt"
|
|
"strconv"
|
|
"unicode"
|
|
|
|
// Explicitly import these for their crypto.RegisterHash init side-effects.
|
|
// Keep these as blank imports, even if they're imported above.
|
|
_ "crypto/sha1"
|
|
_ "crypto/sha256"
|
|
_ "crypto/sha512"
|
|
)
|
|
|
|
type publicKeyInfo struct {
|
|
Raw asn1.RawContent
|
|
Algorithm pkix.AlgorithmIdentifier
|
|
PublicKey asn1.BitString
|
|
}
|
|
|
|
type SignatureAlgorithm int
|
|
|
|
const (
|
|
UnknownSignatureAlgorithm SignatureAlgorithm = iota
|
|
|
|
MD2WithRSA // Unsupported.
|
|
MD5WithRSA // Only supported for signing, not verification.
|
|
SHA1WithRSA // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
|
|
SHA256WithRSA
|
|
SHA384WithRSA
|
|
SHA512WithRSA
|
|
DSAWithSHA1 // Unsupported.
|
|
DSAWithSHA256 // Unsupported.
|
|
ECDSAWithSHA1 // Only supported for signing, and verification of CRLs, CSRs, and OCSP responses.
|
|
ECDSAWithSHA256
|
|
ECDSAWithSHA384
|
|
ECDSAWithSHA512
|
|
SHA256WithRSAPSS
|
|
SHA384WithRSAPSS
|
|
SHA512WithRSAPSS
|
|
PureEd25519
|
|
)
|
|
|
|
func (algo SignatureAlgorithm) String() string {
|
|
for _, details := range signatureAlgorithmDetails {
|
|
if details.algo == algo {
|
|
return details.name
|
|
}
|
|
}
|
|
return strconv.Itoa(int(algo))
|
|
}
|
|
|
|
type PublicKeyAlgorithm int
|
|
|
|
const (
|
|
UnknownPublicKeyAlgorithm PublicKeyAlgorithm = iota
|
|
RSA
|
|
DSA // Only supported for parsing.
|
|
ECDSA
|
|
Ed25519
|
|
)
|
|
|
|
var publicKeyAlgoName = [...]string{
|
|
RSA: "RSA",
|
|
DSA: "DSA",
|
|
ECDSA: "ECDSA",
|
|
Ed25519: "Ed25519",
|
|
}
|
|
|
|
func (algo PublicKeyAlgorithm) String() string {
|
|
if 0 < algo && int(algo) < len(publicKeyAlgoName) {
|
|
return publicKeyAlgoName[algo]
|
|
}
|
|
return strconv.Itoa(int(algo))
|
|
}
|
|
|
|
// OIDs for signature algorithms
|
|
//
|
|
// pkcs-1 OBJECT IDENTIFIER ::= {
|
|
// iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 1 }
|
|
//
|
|
// RFC 3279 2.2.1 RSA Signature Algorithms
|
|
//
|
|
// md5WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 4 }
|
|
//
|
|
// sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 }
|
|
//
|
|
// dsaWithSha1 OBJECT IDENTIFIER ::= {
|
|
// iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 3 }
|
|
//
|
|
// RFC 3279 2.2.3 ECDSA Signature Algorithm
|
|
//
|
|
// ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
|
|
// iso(1) member-body(2) us(840) ansi-x962(10045)
|
|
// signatures(4) ecdsa-with-SHA1(1)}
|
|
//
|
|
// RFC 4055 5 PKCS #1 Version 1.5
|
|
//
|
|
// sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 }
|
|
//
|
|
// sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 }
|
|
//
|
|
// sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 }
|
|
//
|
|
// RFC 5758 3.1 DSA Signature Algorithms
|
|
//
|
|
// dsaWithSha256 OBJECT IDENTIFIER ::= {
|
|
// joint-iso-ccitt(2) country(16) us(840) organization(1) gov(101)
|
|
// csor(3) algorithms(4) id-dsa-with-sha2(3) 2}
|
|
//
|
|
// RFC 5758 3.2 ECDSA Signature Algorithm
|
|
//
|
|
// ecdsa-with-SHA256 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
|
// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 }
|
|
//
|
|
// ecdsa-with-SHA384 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
|
// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 3 }
|
|
//
|
|
// ecdsa-with-SHA512 OBJECT IDENTIFIER ::= { iso(1) member-body(2)
|
|
// us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 4 }
|
|
//
|
|
// RFC 8410 3 Curve25519 and Curve448 Algorithm Identifiers
|
|
//
|
|
// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
|
|
var (
|
|
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 means the same as oidSignatureSHA1WithRSA
|
|
// but it's specified by ISO. Microsoft's makecert.exe has been known
|
|
// to produce certificates with this OID.
|
|
oidISOSignatureSHA1WithRSA = asn1.ObjectIdentifier{1, 3, 14, 3, 2, 29}
|
|
)
|
|
|
|
var signatureAlgorithmDetails = []struct {
|
|
algo SignatureAlgorithm
|
|
name string
|
|
oid asn1.ObjectIdentifier
|
|
params asn1.RawValue
|
|
pubKeyAlgo PublicKeyAlgorithm
|
|
hash crypto.Hash
|
|
isRSAPSS bool
|
|
}{
|
|
{MD5WithRSA, "MD5-RSA", oidSignatureMD5WithRSA, asn1.NullRawValue, RSA, crypto.MD5, false},
|
|
{SHA1WithRSA, "SHA1-RSA", oidSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},
|
|
{SHA1WithRSA, "SHA1-RSA", oidISOSignatureSHA1WithRSA, asn1.NullRawValue, RSA, crypto.SHA1, false},
|
|
{SHA256WithRSA, "SHA256-RSA", oidSignatureSHA256WithRSA, asn1.NullRawValue, RSA, crypto.SHA256, false},
|
|
{SHA384WithRSA, "SHA384-RSA", oidSignatureSHA384WithRSA, asn1.NullRawValue, RSA, crypto.SHA384, false},
|
|
{SHA512WithRSA, "SHA512-RSA", oidSignatureSHA512WithRSA, asn1.NullRawValue, RSA, crypto.SHA512, false},
|
|
{SHA256WithRSAPSS, "SHA256-RSAPSS", oidSignatureRSAPSS, pssParametersSHA256, RSA, crypto.SHA256, true},
|
|
{SHA384WithRSAPSS, "SHA384-RSAPSS", oidSignatureRSAPSS, pssParametersSHA384, RSA, crypto.SHA384, true},
|
|
{SHA512WithRSAPSS, "SHA512-RSAPSS", oidSignatureRSAPSS, pssParametersSHA512, RSA, crypto.SHA512, true},
|
|
{DSAWithSHA1, "DSA-SHA1", oidSignatureDSAWithSHA1, emptyRawValue, DSA, crypto.SHA1, false},
|
|
{DSAWithSHA256, "DSA-SHA256", oidSignatureDSAWithSHA256, emptyRawValue, DSA, crypto.SHA256, false},
|
|
{ECDSAWithSHA1, "ECDSA-SHA1", oidSignatureECDSAWithSHA1, emptyRawValue, ECDSA, crypto.SHA1, false},
|
|
{ECDSAWithSHA256, "ECDSA-SHA256", oidSignatureECDSAWithSHA256, emptyRawValue, ECDSA, crypto.SHA256, false},
|
|
{ECDSAWithSHA384, "ECDSA-SHA384", oidSignatureECDSAWithSHA384, emptyRawValue, ECDSA, crypto.SHA384, false},
|
|
{ECDSAWithSHA512, "ECDSA-SHA512", oidSignatureECDSAWithSHA512, emptyRawValue, ECDSA, crypto.SHA512, false},
|
|
{PureEd25519, "Ed25519", oidSignatureEd25519, emptyRawValue, Ed25519, crypto.Hash(0) /* no pre-hashing */, false},
|
|
}
|
|
|
|
var emptyRawValue = asn1.RawValue{}
|
|
|
|
// DER encoded RSA PSS parameters for the
|
|
// SHA256, SHA384, and SHA512 hashes as defined in RFC 3447, Appendix A.2.3.
|
|
// The parameters contain the following values:
|
|
// - hashAlgorithm contains the associated hash identifier with NULL parameters
|
|
// - maskGenAlgorithm always contains the default mgf1SHA1 identifier
|
|
// - saltLength contains the length of the associated hash
|
|
// - trailerField always contains the default trailerFieldBC value
|
|
var (
|
|
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}}
|
|
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}}
|
|
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}}
|
|
)
|
|
|
|
// pssParameters reflects the parameters in an AlgorithmIdentifier that
|
|
// specifies RSA PSS. See RFC 3447, Appendix A.2.3.
|
|
type pssParameters struct {
|
|
// The following three fields are not marked as
|
|
// optional because the default values specify SHA-1,
|
|
// which is no longer suitable for use in signatures.
|
|
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 getSignatureAlgorithmFromAI(ai pkix.AlgorithmIdentifier) stdx509.SignatureAlgorithm {
|
|
if ai.Algorithm.Equal(oidSignatureEd25519) {
|
|
// RFC 8410, Section 3
|
|
// > For all of the OIDs, the parameters MUST be absent.
|
|
if len(ai.Parameters.FullBytes) != 0 {
|
|
return stdx509.UnknownSignatureAlgorithm
|
|
}
|
|
}
|
|
|
|
if !ai.Algorithm.Equal(oidSignatureRSAPSS) {
|
|
for _, details := range signatureAlgorithmDetails {
|
|
if ai.Algorithm.Equal(details.oid) {
|
|
return stdx509.SignatureAlgorithm(details.algo)
|
|
}
|
|
}
|
|
return stdx509.UnknownSignatureAlgorithm
|
|
}
|
|
|
|
// RSA PSS is special because it encodes important parameters
|
|
// in the Parameters.
|
|
|
|
var params pssParameters
|
|
if _, err := asn1.Unmarshal(ai.Parameters.FullBytes, ¶ms); err != nil {
|
|
return stdx509.UnknownSignatureAlgorithm
|
|
}
|
|
|
|
var mgf1HashFunc pkix.AlgorithmIdentifier
|
|
if _, err := asn1.Unmarshal(params.MGF.Parameters.FullBytes, &mgf1HashFunc); err != nil {
|
|
return stdx509.UnknownSignatureAlgorithm
|
|
}
|
|
|
|
// PSS is greatly overburdened with options. This code forces them into
|
|
// three buckets by requiring that the MGF1 hash function always match the
|
|
// message hash function (as recommended in RFC 3447, Section 8.1), that the
|
|
// salt length matches the hash length, and that the trailer field has the
|
|
// default value.
|
|
if (len(params.Hash.Parameters.FullBytes) != 0 && !bytes.Equal(params.Hash.Parameters.FullBytes, asn1.NullBytes)) ||
|
|
!params.MGF.Algorithm.Equal(oidMGF1) ||
|
|
!mgf1HashFunc.Algorithm.Equal(params.Hash.Algorithm) ||
|
|
(len(mgf1HashFunc.Parameters.FullBytes) != 0 && !bytes.Equal(mgf1HashFunc.Parameters.FullBytes, asn1.NullBytes)) ||
|
|
params.TrailerField != 1 {
|
|
return stdx509.UnknownSignatureAlgorithm
|
|
}
|
|
|
|
switch {
|
|
case params.Hash.Algorithm.Equal(oidSHA256) && params.SaltLength == 32:
|
|
return stdx509.SHA256WithRSAPSS
|
|
case params.Hash.Algorithm.Equal(oidSHA384) && params.SaltLength == 48:
|
|
return stdx509.SHA384WithRSAPSS
|
|
case params.Hash.Algorithm.Equal(oidSHA512) && params.SaltLength == 64:
|
|
return stdx509.SHA512WithRSAPSS
|
|
}
|
|
|
|
return stdx509.UnknownSignatureAlgorithm
|
|
}
|
|
|
|
var (
|
|
// RFC 3279, 2.3 Public Key Algorithms
|
|
//
|
|
// pkcs-1 OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
|
|
// rsadsi(113549) pkcs(1) 1 }
|
|
//
|
|
// rsaEncryption OBJECT IDENTIFIER ::== { pkcs1-1 1 }
|
|
//
|
|
// id-dsa OBJECT IDENTIFIER ::== { iso(1) member-body(2) us(840)
|
|
// x9-57(10040) x9cm(4) 1 }
|
|
oidPublicKeyRSA = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
|
|
oidPublicKeyDSA = asn1.ObjectIdentifier{1, 2, 840, 10040, 4, 1}
|
|
// RFC 5480, 2.1.1 Unrestricted Algorithm Identifier and Parameters
|
|
//
|
|
// id-ecPublicKey OBJECT IDENTIFIER ::= {
|
|
// iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
|
|
oidPublicKeyECDSA = asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}
|
|
// RFC 8410, Section 3
|
|
//
|
|
// id-X25519 OBJECT IDENTIFIER ::= { 1 3 101 110 }
|
|
// id-Ed25519 OBJECT IDENTIFIER ::= { 1 3 101 112 }
|
|
oidPublicKeyX25519 = asn1.ObjectIdentifier{1, 3, 101, 110}
|
|
oidPublicKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
|
|
)
|
|
|
|
// getPublicKeyAlgorithmFromOID returns the exposed PublicKeyAlgorithm
|
|
// identifier for public key types supported in certificates and CSRs. Marshal
|
|
// and Parse functions may support a different set of public key types.
|
|
func getPublicKeyAlgorithmFromOID(oid asn1.ObjectIdentifier) stdx509.PublicKeyAlgorithm {
|
|
switch {
|
|
case oid.Equal(oidPublicKeyRSA):
|
|
return stdx509.RSA
|
|
case oid.Equal(oidPublicKeyDSA):
|
|
return stdx509.DSA
|
|
case oid.Equal(oidPublicKeyECDSA):
|
|
return stdx509.ECDSA
|
|
case oid.Equal(oidPublicKeyEd25519):
|
|
return stdx509.Ed25519
|
|
}
|
|
return stdx509.UnknownPublicKeyAlgorithm
|
|
}
|
|
|
|
// RFC 5480, 2.1.1.1. Named Curve
|
|
//
|
|
// secp224r1 OBJECT IDENTIFIER ::= {
|
|
// iso(1) identified-organization(3) certicom(132) curve(0) 33 }
|
|
//
|
|
// secp256r1 OBJECT IDENTIFIER ::= {
|
|
// iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
|
|
// prime(1) 7 }
|
|
//
|
|
// secp384r1 OBJECT IDENTIFIER ::= {
|
|
// iso(1) identified-organization(3) certicom(132) curve(0) 34 }
|
|
//
|
|
// secp521r1 OBJECT IDENTIFIER ::= {
|
|
// iso(1) identified-organization(3) certicom(132) curve(0) 35 }
|
|
//
|
|
// NB: secp256r1 is equivalent to prime256v1
|
|
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 namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve {
|
|
switch {
|
|
case oid.Equal(oidNamedCurveP224):
|
|
return elliptic.P224()
|
|
case oid.Equal(oidNamedCurveP256):
|
|
return elliptic.P256()
|
|
case oid.Equal(oidNamedCurveP384):
|
|
return elliptic.P384()
|
|
case oid.Equal(oidNamedCurveP521):
|
|
return elliptic.P521()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// KeyUsage represents the set of actions that are valid for a given key. It's
|
|
// a bitmap of the KeyUsage* constants.
|
|
type KeyUsage int
|
|
|
|
const (
|
|
KeyUsageDigitalSignature KeyUsage = 1 << iota
|
|
KeyUsageContentCommitment
|
|
KeyUsageKeyEncipherment
|
|
KeyUsageDataEncipherment
|
|
KeyUsageKeyAgreement
|
|
KeyUsageCertSign
|
|
KeyUsageCRLSign
|
|
KeyUsageEncipherOnly
|
|
KeyUsageDecipherOnly
|
|
)
|
|
|
|
// RFC 5280, 4.2.1.12 Extended Key Usage
|
|
//
|
|
// anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 }
|
|
//
|
|
// id-kp OBJECT IDENTIFIER ::= { id-pkix 3 }
|
|
//
|
|
// id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 }
|
|
// id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 }
|
|
// id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 }
|
|
// id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 }
|
|
// id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 }
|
|
// id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 }
|
|
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}
|
|
)
|
|
|
|
// ExtKeyUsage represents an extended set of actions that are valid for a given key.
|
|
// Each of the ExtKeyUsage* constants define a unique action.
|
|
type ExtKeyUsage int
|
|
|
|
const (
|
|
ExtKeyUsageAny ExtKeyUsage = iota
|
|
ExtKeyUsageServerAuth
|
|
ExtKeyUsageClientAuth
|
|
ExtKeyUsageCodeSigning
|
|
ExtKeyUsageEmailProtection
|
|
ExtKeyUsageIPSECEndSystem
|
|
ExtKeyUsageIPSECTunnel
|
|
ExtKeyUsageIPSECUser
|
|
ExtKeyUsageTimeStamping
|
|
ExtKeyUsageOCSPSigning
|
|
ExtKeyUsageMicrosoftServerGatedCrypto
|
|
ExtKeyUsageNetscapeServerGatedCrypto
|
|
ExtKeyUsageMicrosoftCommercialCodeSigning
|
|
ExtKeyUsageMicrosoftKernelCodeSigning
|
|
)
|
|
|
|
// extKeyUsageOIDs contains the mapping between an ExtKeyUsage and its OID.
|
|
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 extKeyUsageFromOID(oid asn1.ObjectIdentifier) (eku ExtKeyUsage, ok bool) {
|
|
for _, pair := range extKeyUsageOIDs {
|
|
if oid.Equal(pair.oid) {
|
|
return pair.extKeyUsage, true
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
const (
|
|
nameTypeEmail = 1
|
|
nameTypeDNS = 2
|
|
nameTypeURI = 6
|
|
nameTypeIP = 7
|
|
)
|
|
|
|
var (
|
|
oidExtensionAuthorityInfoAccess = []int{1, 3, 6, 1, 5, 5, 7, 1, 1}
|
|
)
|
|
|
|
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 isIA5String(s string) error {
|
|
for _, r := range s {
|
|
// Per RFC5280 "IA5String is limited to the set of ASCII characters"
|
|
if r > unicode.MaxASCII {
|
|
return fmt.Errorf("x509: %q cannot be encoded as an IA5String", s)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|