mirror of
https://github.com/golang/go
synced 2024-09-05 16:04:50 +00:00
crypto/x509: Added RFC 5280, section 4.2.1.14 to parseCertificate and buildExtensions
Support for CRL Distribution Points R=golang-dev, agl, bradfitz CC=golang-dev https://golang.org/cl/10258043
This commit is contained in:
parent
944a260501
commit
4bd79e742a
|
@ -472,6 +472,9 @@ type Certificate struct {
|
|||
PermittedDNSDomainsCritical bool // if true then the name constraints are marked critical.
|
||||
PermittedDNSDomains []string
|
||||
|
||||
// CRL Distribution Points
|
||||
CRLDistributionPoints []string
|
||||
|
||||
PolicyIdentifiers []asn1.ObjectIdentifier
|
||||
}
|
||||
|
||||
|
@ -659,6 +662,18 @@ type generalSubtree struct {
|
|||
Name string `asn1:"tag:2,optional,ia5"`
|
||||
}
|
||||
|
||||
// RFC 5280, 4.2.1.14
|
||||
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 parsePublicKey(algo PublicKeyAlgorithm, keyData *publicKeyInfo) (interface{}, error) {
|
||||
asn1Data := keyData.PublicKey.RightAlign()
|
||||
switch algo {
|
||||
|
@ -896,6 +911,39 @@ func parseCertificate(in *certificate) (*Certificate, error) {
|
|||
}
|
||||
continue
|
||||
|
||||
case 31:
|
||||
// RFC 5280, 4.2.1.14
|
||||
|
||||
// CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint
|
||||
//
|
||||
// DistributionPoint ::= SEQUENCE {
|
||||
// distributionPoint [0] DistributionPointName OPTIONAL,
|
||||
// reasons [1] ReasonFlags OPTIONAL,
|
||||
// cRLIssuer [2] GeneralNames OPTIONAL }
|
||||
//
|
||||
// DistributionPointName ::= CHOICE {
|
||||
// fullName [0] GeneralNames,
|
||||
// nameRelativeToCRLIssuer [1] RelativeDistinguishedName }
|
||||
|
||||
var cdp []distributionPoint
|
||||
_, err := asn1.Unmarshal(e.Value, &cdp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, dp := range cdp {
|
||||
var n asn1.RawValue
|
||||
_, err = asn1.Unmarshal(dp.DistributionPoint.FullName.Bytes, &n)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if n.Tag == 6 {
|
||||
out.CRLDistributionPoints = append(out.CRLDistributionPoints, string(n.Bytes))
|
||||
}
|
||||
}
|
||||
continue
|
||||
|
||||
case 35:
|
||||
// RFC 5280, 4.2.1.1
|
||||
var a authKeyId
|
||||
|
@ -1011,18 +1059,19 @@ func reverseBitsInAByte(in byte) byte {
|
|||
}
|
||||
|
||||
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}
|
||||
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}
|
||||
)
|
||||
|
||||
func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) {
|
||||
ret = make([]pkix.Extension, 8 /* maximum number of elements. */)
|
||||
ret = make([]pkix.Extension, 9 /* maximum number of elements. */)
|
||||
n := 0
|
||||
|
||||
if template.KeyUsage != 0 {
|
||||
|
@ -1147,6 +1196,28 @@ func buildExtensions(template *Certificate) (ret []pkix.Extension, err error) {
|
|||
n++
|
||||
}
|
||||
|
||||
if len(template.CRLDistributionPoints) > 0 {
|
||||
ret[n].Id = oidExtensionCRLDistributionPoints
|
||||
|
||||
var crlDp []distributionPoint
|
||||
for _, name := range template.CRLDistributionPoints {
|
||||
rawFullName, _ := asn1.Marshal(asn1.RawValue{Tag: 6, Class: 2, Bytes: []byte(name)})
|
||||
|
||||
dp := distributionPoint{
|
||||
DistributionPoint: distributionPointName{
|
||||
FullName: asn1.RawValue{Tag: 0, Class: 2, Bytes: rawFullName},
|
||||
},
|
||||
}
|
||||
crlDp = append(crlDp, dp)
|
||||
}
|
||||
|
||||
ret[n].Value, err = asn1.Marshal(crlDp)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n++
|
||||
}
|
||||
|
||||
// Adding another extension here? Remember to update the maximum number
|
||||
// of elements in the make() at the top of the function.
|
||||
|
||||
|
|
|
@ -336,6 +336,8 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
|
|||
|
||||
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
|
||||
PermittedDNSDomains: []string{".example.com", "example.com"},
|
||||
|
||||
CRLDistributionPoints: []string{"http://crl1.example.com/ca1.crl", "http://crl2.example.com/ca1.crl"},
|
||||
}
|
||||
|
||||
derBytes, err := CreateCertificate(random, &template, &template, test.pub, test.priv)
|
||||
|
@ -386,6 +388,10 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
|
|||
t.Errorf("%s: SAN IPs differ from template. Got %v, want %v", test.name, cert.IPAddresses, template.IPAddresses)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(cert.CRLDistributionPoints, template.CRLDistributionPoints) {
|
||||
t.Errorf("%s: CRL distribution points differ from template. Got %v, want %v", test.name, cert.CRLDistributionPoints, template.CRLDistributionPoints)
|
||||
}
|
||||
|
||||
if test.checkSig {
|
||||
err = cert.CheckSignatureFrom(cert)
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in a new issue