Skip to content

Commit 818cb93

Browse files
committed
add test, support creating certificates with new OID type
Change-Id: Icc7b68161dca294e6524f6efb1c690b80b48f96e
1 parent c531c36 commit 818cb93

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

src/crypto/x509/oid.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,14 @@ func newOIDFromDER(der []byte) (OID, bool) {
4343
return OID{der}, true
4444
}
4545

46+
func mustNewOIDFromInts(ints []uint64) OID {
47+
oid, err := OIDFromInts(ints)
48+
if err != nil {
49+
panic("crypto/x509: mustNewOIDFromInts: " + err.Error())
50+
}
51+
return oid
52+
}
53+
4654
// OIDFromInts creates a new OID using ints, each integer is a separate component.
4755
func OIDFromInts(oid []uint64) (OID, error) {
4856
if len(oid) < 2 || oid[0] > 2 || (oid[0] < 2 && oid[1] >= 40) {

src/crypto/x509/x509.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,7 @@ func buildCertExtensions(template *Certificate, subjectIsEmpty bool, authorityKe
11831183

11841184
if len(template.PolicyIdentifiers) > 0 &&
11851185
!oidInExtensions(oidExtensionCertificatePolicies, template.ExtraExtensions) {
1186-
ret[n], err = marshalCertificatePolicies(template.PolicyIdentifiers)
1186+
ret[n], err = marshalCertificatePolicies(template.Policies, template.PolicyIdentifiers)
11871187
if err != nil {
11881188
return nil, err
11891189
}
@@ -1368,14 +1368,27 @@ func marshalBasicConstraints(isCA bool, maxPathLen int, maxPathLenZero bool) (pk
13681368
return ext, err
13691369
}
13701370

1371-
func marshalCertificatePolicies(policyIdentifiers []asn1.ObjectIdentifier) (pkix.Extension, error) {
1371+
func marshalCertificatePolicies(policies []OID, policyIdentifiers []asn1.ObjectIdentifier) (pkix.Extension, error) {
13721372
ext := pkix.Extension{Id: oidExtensionCertificatePolicies}
1373-
policies := make([]policyInformation, len(policyIdentifiers))
1374-
for i, policy := range policyIdentifiers {
1375-
policies[i].Policy = policy
1376-
}
1373+
1374+
b := cryptobyte.NewBuilder(make([]byte, 0, 128))
1375+
b.AddASN1(cryptobyte_asn1.SEQUENCE, func(child *cryptobyte.Builder) {
1376+
for _, v := range policies {
1377+
child.AddASN1(cryptobyte_asn1.SEQUENCE, func(child *cryptobyte.Builder) {
1378+
child.AddASN1(cryptobyte_asn1.OBJECT_IDENTIFIER, func(child *cryptobyte.Builder) {
1379+
child.AddBytes(v.der)
1380+
})
1381+
})
1382+
}
1383+
for _, v := range policyIdentifiers {
1384+
child.AddASN1(cryptobyte_asn1.SEQUENCE, func(child *cryptobyte.Builder) {
1385+
child.AddASN1ObjectIdentifier(v)
1386+
})
1387+
}
1388+
})
1389+
13771390
var err error
1378-
ext.Value, err = asn1.Marshal(policies)
1391+
ext.Value, err = b.Bytes()
13791392
return ext, err
13801393
}
13811394

src/crypto/x509/x509_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ import (
2424
"fmt"
2525
"internal/testenv"
2626
"io"
27+
"math"
2728
"math/big"
2829
"net"
2930
"net/url"
3031
"os/exec"
3132
"reflect"
3233
"runtime"
34+
"slices"
3335
"strings"
3436
"testing"
3537
"time"
@@ -671,6 +673,7 @@ func TestCreateSelfSignedCertificate(t *testing.T) {
671673
URIs: []*url.URL{parseURI("https://foo.com/wibble#foo")},
672674

673675
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
676+
Policies: []OID{mustNewOIDFromInts([]uint64{1, 2, 3, math.MaxUint32, math.MaxUint64})},
674677
PermittedDNSDomains: []string{".example.com", "example.com"},
675678
ExcludedDNSDomains: []string{"bar.example.com"},
676679
PermittedIPRanges: []*net.IPNet{parseCIDR("192.168.1.1/16"), parseCIDR("1.2.3.4/8")},
@@ -3917,3 +3920,49 @@ func TestDuplicateAttributesCSR(t *testing.T) {
39173920
t.Fatal("ParseCertificateRequest should succeed when parsing CSR with duplicate attributes")
39183921
}
39193922
}
3923+
3924+
func TestCertificateOIDPolicies(t *testing.T) {
3925+
template := Certificate{
3926+
SerialNumber: big.NewInt(1),
3927+
Subject: pkix.Name{CommonName: "Cert"},
3928+
NotBefore: time.Unix(1000, 0),
3929+
NotAfter: time.Unix(100000, 0),
3930+
PolicyIdentifiers: []asn1.ObjectIdentifier{[]int{1, 2, 3}},
3931+
Policies: []OID{
3932+
mustNewOIDFromInts([]uint64{1, 2, 3, 4, 5}),
3933+
mustNewOIDFromInts([]uint64{1, 2, 3, math.MaxInt32}),
3934+
mustNewOIDFromInts([]uint64{1, 2, 3, math.MaxUint32, math.MaxUint64}),
3935+
},
3936+
}
3937+
3938+
var expectPolicyIdentifiers = []asn1.ObjectIdentifier{
3939+
[]int{1, 2, 3, 4, 5},
3940+
[]int{1, 2, 3, math.MaxInt32},
3941+
[]int{1, 2, 3},
3942+
}
3943+
3944+
var expectPolicies = []OID{
3945+
mustNewOIDFromInts([]uint64{1, 2, 3, 4, 5}),
3946+
mustNewOIDFromInts([]uint64{1, 2, 3, math.MaxInt32}),
3947+
mustNewOIDFromInts([]uint64{1, 2, 3, math.MaxUint32, math.MaxUint64}),
3948+
mustNewOIDFromInts([]uint64{1, 2, 3}),
3949+
}
3950+
3951+
certDER, err := CreateCertificate(rand.Reader, &template, &template, rsaPrivateKey.Public(), rsaPrivateKey)
3952+
if err != nil {
3953+
t.Fatalf("CreateCertificate() unexpected error: %v", err)
3954+
}
3955+
3956+
cert, err := ParseCertificate(certDER)
3957+
if err != nil {
3958+
t.Fatalf("ParseCertificate() unexpected error: %v", err)
3959+
}
3960+
3961+
if !slices.EqualFunc(cert.PolicyIdentifiers, expectPolicyIdentifiers, slices.Equal[asn1.ObjectIdentifier]) {
3962+
t.Errorf("cert.PolicyIdentifiers = %v, want: %v", cert.PolicyIdentifiers, expectPolicyIdentifiers)
3963+
}
3964+
3965+
if !slices.EqualFunc(cert.Policies, expectPolicies, func(o1, o2 OID) bool { return o1.Equal(o2) }) {
3966+
t.Errorf("cert.Policies = %v, want: %v", cert.Policies, expectPolicies)
3967+
}
3968+
}

0 commit comments

Comments
 (0)