Documentation
¶
Overview ¶
Package csr provides utilities for creating, parsing, and validating Certificate Signing Requests (CSRs) as defined by RFC 2986.
This package supports:
- CSR generation with various key types (RSA, ECDSA)
- CSR parsing and validation
- Request and key-request types shared with the authority package
- Extension handling for certificate requests
- Key request generation for automated certificate enrollment
The package integrates with the cryptoprov package to support hardware-backed private keys and various cryptographic providers.
Index ¶
- Constants
- func ApplySAN(template *x509.Certificate, names []string) error
- func DecodeCDP(val []byte) ([]string, error)
- func DefaultSigAlgo(priv crypto.Signer) x509.SignatureAlgorithm
- func EncodeCDP(cdp []string) (*pkix.Extension, error)
- func EncodeCDPFull(cdp []string, issuer asn1.RawValue) (*pkix.Extension, error)
- func FindAttr(attrs []pkix.AttributeTypeAndValue, id asn1.ObjectIdentifier) *pkix.AttributeTypeAndValue
- func Parse(csrBytes []byte) (*x509.Certificate, error)
- func ParsePEM(csrPEM []byte) (*x509.Certificate, error)
- func PopulateName(raSubject *X509Subject, csrSubject pkix.Name) pkix.Name
- func SetSAN(template *x509.Certificate, names []string)deprecated
- func SigAlgo(algo string, size int) x509.SignatureAlgorithm
- type AllowedFields
- type BasicConstraints
- type CertificatePolicy
- type CertificatePolicyQualifier
- type CertificateRequest
- type DistributionPoint
- type DistributionPointName
- type Duration
- type GeneralName
- type KeyPurpose
- type KeyRequest
- type KeyRequestGen
- type OID
- type Provider
- func (c *Provider) CreateRequestAndExportKey(req *CertificateRequest) (csrPEM, key []byte, keyID string, pub crypto.PublicKey, err error)
- func (c *Provider) GenerateKeyAndRequest(req *CertificateRequest) (csrPEM []byte, priv crypto.PrivateKey, keyID string, err error)
- func (c *Provider) NewKeyRequest(label, algo string, keySize int, purpose KeyPurpose) *KeyRequest
- func (c *Provider) NewSigningCertificateRequest(keyLabel, algo string, keySize int, CN string, names []X509Name, san []string) *CertificateRequest
- func (c *Provider) SignRequest(priv crypto.PrivateKey, req *CertificateRequest) (csrPEM []byte, err error)
- type SAN
- type SignRequest
- type SignatureAlgorithmer
- type Signer
- type X509Extension
- type X509Name
- type X509Subject
Constants ¶
const ( // CurveP256 specifies curve P-256 for ECDSA CurveP256 = 256 // CurveP384 specifies curve P-384 for ECDSA CurveP384 = 384 // CurveP521 specifies curve P-521 for ECDSA CurveP521 = 521 )
const ( // UserNoticeQualifierType defines id-qt-unotice UserNoticeQualifierType = "id-qt-unotice" // CpsQualifierType defines id-qt-cps CpsQualifierType = "id-qt-cps" // OneYear duration OneYear = Duration(8760 * time.Hour) )
Variables ¶
This section is empty.
Functions ¶
func ApplySAN ¶ added in v1.0.310
func ApplySAN(template *x509.Certificate, names []string) error
ApplySAN replaces the subject alternative names of template with names parsed by ParseSAN: DNSNames, EmailAddresses, IPAddresses and URIs are replaced (a type with no names becomes nil), and every raw SAN extension is removed from ExtraExtensions, keeping the order of the others. A nil names leaves template unchanged, so the names of a parsed CSR survive; a non-nil empty slice clears them. A nil template is an error. On error template is unchanged.
func DefaultSigAlgo ¶
func DefaultSigAlgo(priv crypto.Signer) x509.SignatureAlgorithm
DefaultSigAlgo returns the X.509 signature algorithm for priv: the one a SignatureAlgorithmer advertises, else one chosen by key type and size. RSA keys of 2048 and 3072 bits use SHA-256 and keys of 4096 bits or more SHA-512 (NIST SP 800-57 rates 3072-bit RSA at 128 bits, matching SHA-256, and GCP KMS signs 3072-bit keys only with SHA-256, XPKI-114); ECDSA P-256, P-384 and P-521 use SHA-256, SHA-384 and SHA-512. SHA-1 is never returned; other key types give x509.UnknownSignatureAlgorithm.
func EncodeCDPFull ¶ added in v0.13.0
EncodeCDPFull returns CRLDP
func FindAttr ¶ added in v0.3.0
func FindAttr(attrs []pkix.AttributeTypeAndValue, id asn1.ObjectIdentifier) *pkix.AttributeTypeAndValue
FindAttr returns attribute
func Parse ¶
func Parse(csrBytes []byte) (*x509.Certificate, error)
Parse takes an incoming certificate request and builds a certificate template from it.
func ParsePEM ¶
func ParsePEM(csrPEM []byte) (*x509.Certificate, error)
ParsePEM takes an incoming certificate request and builds a certificate template from it.
func PopulateName ¶
func PopulateName(raSubject *X509Subject, csrSubject pkix.Name) pkix.Name
PopulateName has functionality similar to Name, except it fills the fields of the resulting pkix.Name with req's if the subject's corresponding fields are empty
func SetSAN
deprecated
func SetSAN(template *x509.Certificate, names []string)
SetSAN is ApplySAN without an error: a name ParseSAN rejects is skipped with an error log and the valid names are applied. A nil names leaves template unchanged; a non-nil empty slice clears the names.
Deprecated: use ApplySAN, which reports the invalid names.
func SigAlgo ¶
func SigAlgo(algo string, size int) x509.SignatureAlgorithm
SigAlgo returns the signature algorithm for a key of algo ("RSA" or "ECDSA", case-insensitive) and size, as DefaultSigAlgo chooses it from a key: RSA 2048 and 3072 bits SHA-256 (XPKI-114), 4096 bits and above SHA-512; ECDSA by curve size. Other algorithms give x509.UnknownSignatureAlgorithm.
Types ¶
type AllowedFields ¶
type AllowedFields struct {
Subject bool `json:"subject" yaml:"subject"`
DNSNames bool `json:"dns" yaml:"dns"`
IPAddresses bool `json:"ip" yaml:"ip"`
EmailAddresses bool `json:"email" yaml:"email"`
URIs bool `json:"uri" yaml:"uri"`
}
AllowedFields provides booleans for fields in the CSR. If a AllowedFields is not present in a CertProfile, all of these fields may be copied from the CSR into the signed certificate. If a AllowedFields *is* present in a CertProfile, only those fields with a `true` value in the AllowedFields may be copied from the CSR to the signed certificate. Note that some of these fields, like Subject, can be provided or partially provided through the API. Since API clients are expected to be trusted, but CSRs are not, fields provided through the API are not subject to validation through this mechanism.
type BasicConstraints ¶
type BasicConstraints struct {
IsCA bool `asn1:"optional"`
MaxPathLen int `asn1:"optional,default:-1"`
}
BasicConstraints CSR information RFC 5280, 4.2.1.9
type CertificatePolicy ¶
type CertificatePolicy struct {
ID OID `json:"oid" yaml:"oid"`
Qualifiers []CertificatePolicyQualifier `json:"qualifiers" yaml:"qualifiers"`
}
CertificatePolicy represents the ASN.1 PolicyInformation structure from https://tools.ietf.org/html/rfc3280.html#page-106. Valid values of Type are "id-qt-unotice" and "id-qt-cps"
type CertificatePolicyQualifier ¶
type CertificatePolicyQualifier struct {
Type string `json:"type" yaml:"type"`
Value string `json:"value" yaml:"value"`
}
CertificatePolicyQualifier represents a single qualifier from an ASN.1 PolicyInformation structure.
type CertificateRequest ¶
type CertificateRequest struct {
// CommonName of the Subject
CommonName string `json:"common_name" yaml:"common_name"`
// Names of the Subject
Names []X509Name `json:"names" yaml:"names"`
// SerialNumber of the Subject
SerialNumber string `json:"serial_number,omitempty" yaml:"serial_number,omitempty"`
// SAN is Subject Alt Names
SAN []string `json:"san" yaml:"san"`
// KeyRequest for generated key
KeyRequest *KeyRequest `json:"key,omitempty" yaml:"key,omitempty"`
// Extensions for the cert
Extensions []X509Extension `json:"extensions,omitempty" yaml:"extensions,omitempty"`
}
A CertificateRequest encapsulates the API interface to the certificate request functionality.
func (*CertificateRequest) AddSAN ¶ added in v0.3.0
func (r *CertificateRequest) AddSAN(s string)
AddSAN adds a SAN value to the request
func (*CertificateRequest) Name ¶
func (r *CertificateRequest) Name() pkix.Name
Name returns the PKIX name for the request.
func (*CertificateRequest) Validate ¶
func (r *CertificateRequest) Validate() error
Validate provides the default validation logic for certificate authority certificates. The only requirement here is that the certificate have a non-empty subject field.
type DistributionPoint ¶ added in v0.5.0
type DistributionPoint struct {
DistributionPoint DistributionPointName `asn1:"optional,tag:0"`
Reason asn1.BitString `asn1:"optional,tag:1"`
CRLIssuer asn1.RawValue `asn1:"optional,tag:2"`
}
DistributionPoint defines CDP as per RFC 5280, 4.2.1.14
type DistributionPointName ¶ added in v0.5.0
type DistributionPointName struct {
FullName []asn1.RawValue `asn1:"optional,tag:0"`
RelativeName pkix.RDNSequence `asn1:"optional,tag:1"`
}
DistributionPointName is a part of DistributionPoint
type Duration ¶
Duration represents a period of time, its the same as time.Duration but supports better marshalling from json
func (Duration) MarshalJSON ¶
MarshalJSON encodes our custom Duration value as a quoted version of its underlying value's String() output this means you get a duration with a trailing units indicator, e.g. "10m0s"
func (Duration) String ¶
String returns a string formatted version of the duration in a valueUnits format, e.g. 5m0s for 5 minutes
func (Duration) TimeDuration ¶
TimeDuration returns this duration in a time.Duration type
func (*Duration) UnmarshalJSON ¶
UnmarshalJSON handles decoding our custom json serialization for Durations json values that are numbers are treated as seconds json values that are strings, can use the standard time.Duration units indicators e.g. this can decode val:100 as well as val:"10m"
type GeneralName ¶ added in v0.13.0
type GeneralName struct {
Raw asn1.RawValue
DNSName string
DirectoryName pkix.RDNSequence
EmailAddres string
IPAddres net.IP
URI *url.URL
}
GeneralName represents a General Names sequence as defined in RFC 5820 section 4.2.1.6.
GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName
GeneralName ::= CHOICE {
otherName [0] OtherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER }
OtherName ::= SEQUENCE {
type-id OBJECT IDENTIFIER,
value [0] EXPLICIT ANY DEFINED BY type-id }
EDIPartyName ::= SEQUENCE {
nameAssigner [0] DirectoryString OPTIONAL,
partyName [1] DirectoryString }
func DecodeCDPFull ¶ added in v0.13.0
func DecodeCDPFull(val []byte) ([]string, []GeneralName, error)
DecodeCDPFull returns list of CDP
type KeyPurpose ¶
type KeyPurpose int
KeyPurpose declares the purpose for keys
const ( // Undefined purpose of key Undefined KeyPurpose = 0 // SigningKey specifies the purpose of key to be used in signing/verification operations SigningKey KeyPurpose = 1 // EncryptionKey specifies the purpose of key to be used in encryption/decryption operations EncryptionKey KeyPurpose = 2 )
type KeyRequest ¶
type KeyRequest struct {
L string `json:"label" yaml:"label"`
A string `json:"algo" yaml:"algo"`
S int `json:"size" yaml:"size"`
P KeyPurpose `json:"purpose" yaml:"purpose"`
// contains filtered or unexported fields
}
KeyRequest contains the algorithm and key size for a new private key.
func NewKeyRequest ¶
func NewKeyRequest(prov cryptoprov.Provider, label, algo string, keySize int, purpose KeyPurpose) *KeyRequest
NewKeyRequest returns KeyRequest from given parameters
func (*KeyRequest) Algo ¶
func (kr *KeyRequest) Algo() string
Algo returns the requested key algorithm represented as a string.
func (*KeyRequest) Generate ¶
func (kr *KeyRequest) Generate() (crypto.PrivateKey, error)
Generate generates a key as specified in the request. Currently, only ECDSA and RSA are supported.
func (*KeyRequest) Label ¶
func (kr *KeyRequest) Label() string
Label returns the requested key label.
func (*KeyRequest) Purpose ¶
func (kr *KeyRequest) Purpose() int
Purpose returns the purpose of the key .
func (*KeyRequest) SigAlgo ¶
func (kr *KeyRequest) SigAlgo() x509.SignatureAlgorithm
SigAlgo returns an appropriate X.509 signature algorithm given the key request's type and size.
type KeyRequestGen ¶
type KeyRequestGen interface {
Algo() string
Label() string
Size() int
Generate() (crypto.PrivateKey, error)
SigAlgo() x509.SignatureAlgorithm
Purpose() int
}
KeyRequestGen contains the algorithm and key size for a new private key.
type OID ¶
type OID asn1.ObjectIdentifier
OID is the asn1's ObjectIdentifier, provide a custom JSON marshal / unmarshal.
func ParseObjectIdentifier ¶
ParseObjectIdentifier parses a dotted-decimal OID string. The whole string must be digits separated by single dots; anything else is an error.
func (OID) MarshalJSON ¶
MarshalJSON marshals an oid into a JSON string.
func (*OID) UnmarshalJSON ¶
UnmarshalJSON unmarshals a JSON string into an OID.
type Provider ¶
type Provider struct {
// contains filtered or unexported fields
}
Provider extends cryptoprov.Crypto functionality to support CSP processing and certificate signing
func NewProvider ¶
func NewProvider(provider cryptoprov.Provider) *Provider
NewProvider returns an instance of CSR provider
func (*Provider) CreateRequestAndExportKey ¶
func (c *Provider) CreateRequestAndExportKey(req *CertificateRequest) (csrPEM, key []byte, keyID string, pub crypto.PublicKey, err error)
CreateRequestAndExportKey takes a certificate request and generates a key and CSR from it.
func (*Provider) GenerateKeyAndRequest ¶
func (c *Provider) GenerateKeyAndRequest(req *CertificateRequest) (csrPEM []byte, priv crypto.PrivateKey, keyID string, err error)
GenerateKeyAndRequest takes a certificate request and generates a key and CSR from it.
func (*Provider) NewKeyRequest ¶
func (c *Provider) NewKeyRequest(label, algo string, keySize int, purpose KeyPurpose) *KeyRequest
NewKeyRequest returns KeyRequest from given parameters
func (*Provider) NewSigningCertificateRequest ¶
func (c *Provider) NewSigningCertificateRequest( keyLabel, algo string, keySize int, CN string, names []X509Name, san []string, ) *CertificateRequest
NewSigningCertificateRequest creates new request for signing certificate
func (*Provider) SignRequest ¶ added in v0.7.0
func (c *Provider) SignRequest(priv crypto.PrivateKey, req *CertificateRequest) (csrPEM []byte, err error)
SignRequest signs a certificate request with priv. req.SAN is parsed by ParseSAN, so an invalid name fails the request instead of being skipped and duplicates are dropped (XPKI-059); the signature algorithm is DefaultSigAlgo(priv).
type SAN ¶ added in v1.0.310
SAN holds subject alternative names classified by type, as ParseSAN returns them. Each list keeps the input order without duplicates; a type with no names is nil.
func ParseSAN ¶ added in v1.0.310
ParseSAN classifies, validates and deduplicates subject alternative names (XPKI-059). Each name is trimmed of surrounding whitespace and must not be empty. It is then, in this order: a URI when it contains "://" (it must parse, have a scheme and be ASCII); an IP address when net.ParseIP accepts it (an IPv4 address is kept in its 4-byte form); an email address when mail.ParseAddress accepts it (the address part is kept, and it must be ASCII); otherwise a DNS name. A DNS name with non-ASCII runes is converted to A-labels first (IDNA mapping, which also lowercases it); an ASCII name keeps its case. The ASCII form must be at most 253 characters of labels separated by dots, each label 1 to 63 letters, digits, hyphens or underscores that neither starts nor ends with a hyphen; a wildcard is allowed only as the whole first label of a name with at least two labels; a trailing dot is invalid. A single label such as "localhost" is valid.
Duplicates are dropped and the first occurrence is kept: DNS names and email addresses compare case-insensitively, IP addresses by value (so "::ffff:10.0.0.1" duplicates "10.0.0.1"), URIs by their serialized form.
Every invalid name is reported; the returned error joins them as `invalid SAN "name": reason`.
func (*SAN) Validate ¶ added in v1.0.310
Validate checks the names of s with the rules of ParseSAN and drops duplicates in place, so names that are already classified, such as the names of a parsed CSR, get the same validation as names given as strings (XPKI-059). On error s is unchanged. The returned error joins every invalid name as `invalid SAN "name": reason`.
type SignRequest ¶
type SignRequest struct {
SAN []string `json:"san" yaml:"san"`
Request string `json:"certificate_request" yaml:"certificate_request"`
Subject *X509Subject `json:"subject,omitempty" yaml:"subject,omitempty"`
Profile string `json:"profile" yaml:"profile"`
SerialNumber *big.Int `json:"serial_number,omitempty" yaml:"serial_number,omitempty"`
Extensions []X509Extension `json:"extensions,omitempty" yaml:"extensions,omitempty"`
// If provided, NotBefore will be used without modification (except
// for canonicalization) as the value of the notBefore field of the
// certificate. In particular no backdating adjustment will be made
// when NotBefore is provided. The signer rejects a NotBefore earlier
// than now minus the profile backdate.
NotBefore time.Time `json:"-" yaml:"-"`
// If provided, NotAfter will be used without modification (except
// for canonicalization and clipping to the issuer's NotAfter) as the
// value of the notAfter field of the certificate. The signer rejects a
// NotAfter that is not after NotBefore or exceeds the profile expiry.
NotAfter time.Time `json:"-" yaml:"-"`
}
SignRequest stores a signature request, which contains the SAN, the PEM-encoded CSR, optional subject information, and the signature profile.
Extensions provided in the request are copied into the certificate, as long as they are in the allowed list for the issuer's policy (an empty list allows all). Extensions requested in the CSR are copied only when explicitly allowed; key usages, SAN, basic constraints, key identifiers and OCSP no-check are always taken from the profile and permitted CSR fields instead.
func (*SignRequest) ExtensionsIDs ¶ added in v0.3.0
func (r *SignRequest) ExtensionsIDs() []string
ExtensionsIDs returns list of extension IDs in the request
func (*SignRequest) SubjectCommonName ¶ added in v0.3.0
func (r *SignRequest) SubjectCommonName() string
SubjectCommonName returns CN in the request
type SignatureAlgorithmer ¶ added in v1.0.310
type SignatureAlgorithmer interface {
SignatureAlgorithm() x509.SignatureAlgorithm
}
SignatureAlgorithmer is implemented by a crypto.Signer whose key accepts a single X.509 signature algorithm, such as a KMS key whose algorithm fixes the hash and padding. DefaultSigAlgo returns that algorithm when it is not x509.UnknownSignatureAlgorithm.
type Signer ¶
type Signer interface {
SignCertificate(req SignRequest) (cert []byte, err error)
}
Signer interface to sign CSR
type X509Extension ¶
type X509Extension struct {
ID OID `json:"id" yaml:"id"`
Critical bool `json:"critical" yaml:"critical"`
Value string `json:"value" yaml:"value"`
}
X509Extension represents a raw extension to be included in the certificate. The "value" field must be hex encoded.
func (X509Extension) GetValue ¶ added in v0.2.0
func (ext X509Extension) GetValue() ([]byte, error)
GetValue returns raw value. if prefix is hex or base64, then it's decoded, otherwise hex decoding is tried first then base64
type X509Name ¶
type X509Name struct {
Country string `json:"c" yaml:"c"`
Province string `json:"st" yaml:"st"`
Locality string `json:"l" yaml:"l"`
Organization string `json:"o" yaml:"o"`
OrganizationalUnit string `json:"ou" yaml:"ou"`
EmailAddress string `json:"email" yaml:"email"` // 1.2.840.113549.1.9.1
SerialNumber string `json:"serial_number" yaml:"serial_number"`
}
X509Name contains the SubjectInfo fields.
type X509Subject ¶
type X509Subject struct {
CommonName string `json:"common_name" yaml:"common_name"`
Names []X509Name `json:"names" yaml:"names"`
SerialNumber string `json:"serial_number" yaml:"serial_number"`
}
X509Subject contains the information that should be used to override the subject information when signing a certificate.
func (*X509Subject) Name ¶
func (s *X509Subject) Name() pkix.Name
Name returns the PKIX name for the subject.