Packages
hackney
2.0.0
4.7.2
4.7.1
4.7.0
4.6.1
4.6.0
4.5.2
4.5.1
4.5.0
4.4.5
4.4.3
4.4.2
4.4.1
4.4.0
4.3.0
4.2.3
4.2.2
4.2.1
4.2.0
4.1.0
4.0.3
4.0.2
4.0.1
4.0.0
3.2.1
3.2.0
3.1.2
3.1.1
3.1.0
3.0.3
3.0.2
3.0.1
3.0.0
retired
2.0.1
2.0.0
2.0.0-beta.1
1.25.0
1.24.1
1.24.0
1.23.0
1.22.0
1.21.0
1.20.1
1.20.0
1.19.1
1.19.0
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.0
1.15.2
1.15.1
1.15.0
1.14.3
1.14.2
1.14.0
1.13.0
1.12.1
1.12.0
1.11.0
1.10.1
1.10.0
1.9.0
1.8.6
1.8.5
1.8.4
1.8.3
1.8.2
1.8.0
1.7.1
1.7.0
1.6.6
retired
1.6.5
1.6.4
retired
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.10
1.4.8
1.4.7
1.4.6
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.3.2
1.3.1
1.3.0
1.2.0
1.1.0
1.0.6
1.0.5
1.0.2
1.0.1
0.15.2
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.13.1
Simple HTTP client with HTTP/1.1, HTTP/2, and HTTP/3 support
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
c_src/boringssl/crypto/x509/test/make_policy_certs.go
// Copyright 2020 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//go:build ignore
// make_policy_certs.go generates certificates for testing policy handling.
package main
import (
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"flag"
"math/big"
"os"
"time"
"golang.org/x/crypto/cryptobyte"
cbasn1 "golang.org/x/crypto/cryptobyte/asn1"
)
var resetFlag = flag.Bool("reset", false, "if set, regenerates certificates that already exist")
var (
// https://davidben.net/oid
testOID1 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 1})
testOID2 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 2})
testOID3 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 3})
testOID4 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 4})
testOID5 = asn1.ObjectIdentifier([]int{1, 2, 840, 113554, 4, 1, 72585, 2, 5})
// https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.4
certificatePoliciesOID = asn1.ObjectIdentifier([]int{2, 5, 29, 32})
anyPolicyOID = asn1.ObjectIdentifier([]int{2, 5, 29, 32, 0})
// https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.5
policyMappingsOID = asn1.ObjectIdentifier([]int{2, 5, 29, 33})
// https://www.rfc-editor.org/rfc/rfc5280.html#section-4.2.1.11
policyConstraintsOID = asn1.ObjectIdentifier([]int{2, 5, 29, 36})
)
var leafKey, intermediateKey, rootKey *ecdsa.PrivateKey
func init() {
leafKey = mustParseECDSAKey(leafKeyPEM)
intermediateKey = mustParseECDSAKey(intermediateKeyPEM)
rootKey = mustParseECDSAKey(rootKeyPEM)
}
type templateAndKey struct {
template x509.Certificate
key *ecdsa.PrivateKey
}
func mustGenerateCertificate(path string, subject, issuer *templateAndKey) {
if !*resetFlag {
// Skip if the file already exists.
_, err := os.Stat(path)
if err == nil {
return
}
if !os.IsNotExist(err) {
panic(err)
}
}
cert, err := x509.CreateCertificate(rand.Reader, &subject.template, &issuer.template, &subject.key.PublicKey, issuer.key)
if err != nil {
panic(err)
}
file, err := os.Create(path)
if err != nil {
panic(err)
}
defer file.Close()
err = pem.Encode(file, &pem.Block{Type: "CERTIFICATE", Bytes: cert})
if err != nil {
panic(err)
}
}
func main() {
flag.Parse()
notBefore, err := time.Parse(time.RFC3339, "2000-01-01T00:00:00Z")
if err != nil {
panic(err)
}
notAfter, err := time.Parse(time.RFC3339, "2100-01-01T00:00:00Z")
if err != nil {
panic(err)
}
root2 := templateAndKey{
template: x509.Certificate{
SerialNumber: new(big.Int).SetInt64(1),
Subject: pkix.Name{CommonName: "Policy Root 2"},
NotBefore: notBefore,
NotAfter: notAfter,
BasicConstraintsValid: true,
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageCertSign,
SignatureAlgorithm: x509.ECDSAWithSHA256,
},
key: rootKey,
}
root := templateAndKey{
template: x509.Certificate{
SerialNumber: new(big.Int).SetInt64(1),
Subject: pkix.Name{CommonName: "Policy Root"},
NotBefore: notBefore,
NotAfter: notAfter,
BasicConstraintsValid: true,
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageCertSign,
SignatureAlgorithm: x509.ECDSAWithSHA256,
},
key: rootKey,
}
intermediate := templateAndKey{
template: x509.Certificate{
SerialNumber: new(big.Int).SetInt64(2),
Subject: pkix.Name{CommonName: "Policy Intermediate"},
NotBefore: notBefore,
NotAfter: notAfter,
BasicConstraintsValid: true,
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageCertSign,
SignatureAlgorithm: x509.ECDSAWithSHA256,
PolicyIdentifiers: []asn1.ObjectIdentifier{testOID1, testOID2},
},
key: intermediateKey,
}
leaf := templateAndKey{
template: x509.Certificate{
SerialNumber: new(big.Int).SetInt64(3),
Subject: pkix.Name{CommonName: "www.example.com"},
NotBefore: notBefore,
NotAfter: notAfter,
BasicConstraintsValid: true,
IsCA: false,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageCertSign,
SignatureAlgorithm: x509.ECDSAWithSHA256,
DNSNames: []string{"www.example.com"},
PolicyIdentifiers: []asn1.ObjectIdentifier{testOID1, testOID2},
},
key: leafKey,
}
// Generate a valid certificate chain from the templates.
mustGenerateCertificate("policy_root.pem", &root, &root)
mustGenerateCertificate("policy_intermediate.pem", &intermediate, &root)
mustGenerateCertificate("policy_leaf.pem", &leaf, &intermediate)
// root2 is used for tests that need a longer chain, using a Root/Root2
// cross-sign as one of the certificates.
mustGenerateCertificate("policy_root2.pem", &root2, &root2)
// Introduce syntax errors in the leaf and intermediate.
leafInvalid := leaf
leafInvalid.template.PolicyIdentifiers = nil
leafInvalid.template.ExtraExtensions = []pkix.Extension{{Id: certificatePoliciesOID, Value: []byte("INVALID")}}
mustGenerateCertificate("policy_leaf_invalid.pem", &leafInvalid, &root)
intermediateInvalid := intermediate
intermediateInvalid.template.PolicyIdentifiers = nil
intermediateInvalid.template.ExtraExtensions = []pkix.Extension{{Id: certificatePoliciesOID, Value: []byte("INVALID")}}
mustGenerateCertificate("policy_intermediate_invalid.pem", &intermediateInvalid, &root)
// Duplicates are not allowed in certificatePolicies.
leafDuplicate := leaf
leafDuplicate.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID2}
mustGenerateCertificate("policy_leaf_duplicate.pem", &leafDuplicate, &root)
intermediateDuplicate := intermediate
intermediateDuplicate.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID2}
mustGenerateCertificate("policy_intermediate_duplicate.pem", &intermediateDuplicate, &root)
// Various policy constraints with requireExplicitPolicy values.
b := cryptobyte.NewBuilder(nil)
b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) {
seq.AddASN1Int64WithTag(0, cbasn1.Tag(0).ContextSpecific())
})
requireExplicitPolicy0 := b.BytesOrPanic()
b = cryptobyte.NewBuilder(nil)
b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) {
seq.AddASN1Int64WithTag(1, cbasn1.Tag(0).ContextSpecific())
})
requireExplicitPolicy1 := b.BytesOrPanic()
b = cryptobyte.NewBuilder(nil)
b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) {
seq.AddASN1Int64WithTag(2, cbasn1.Tag(0).ContextSpecific())
})
requireExplicitPolicy2 := b.BytesOrPanic()
// A version of the intermediate that sets requireExplicitPolicy, skipping
// zero certificates.
intermediateRequire := intermediate
intermediateRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy0}}
mustGenerateCertificate("policy_intermediate_require.pem", &intermediateRequire, &root)
// Same as above, but there are no policies on the intermediate.
intermediateRequire.template.PolicyIdentifiers = nil
mustGenerateCertificate("policy_intermediate_require_no_policies.pem", &intermediateRequire, &root)
// Same as above, but the policy list has duplicates.
intermediateRequire.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID2}
mustGenerateCertificate("policy_intermediate_require_duplicate.pem", &intermediateRequire, &root)
// Corresponding certificates that instead assert the anyPolicy OID.
intermediateAny := intermediate
intermediateAny.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID}
mustGenerateCertificate("policy_intermediate_any.pem", &intermediateAny, &root)
// Other requireExplicitPolicy values, on the leaf and intermediate.
intermediateRequire = intermediate
intermediateRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy1}}
mustGenerateCertificate("policy_intermediate_require1.pem", &intermediateRequire, &root)
intermediateRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy2}}
mustGenerateCertificate("policy_intermediate_require2.pem", &intermediateRequire, &root)
leafRequire := leaf
leafRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy0}}
mustGenerateCertificate("policy_leaf_require.pem", &leafRequire, &intermediate)
leafRequire.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: requireExplicitPolicy1}}
mustGenerateCertificate("policy_leaf_require1.pem", &leafRequire, &intermediate)
leafAny := leaf
leafAny.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID}
mustGenerateCertificate("policy_leaf_any.pem", &leafAny, &intermediate)
// An intermediate which maps OID1 to (OID2, OID3), and which asserts the
// input OIDs either all at once, or as anyPolicy.
b = cryptobyte.NewBuilder(nil)
b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) {
// Map OID3 to (OID1, OID2).
seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) {
mapping.AddASN1ObjectIdentifier(testOID3)
mapping.AddASN1ObjectIdentifier(testOID1)
})
seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) {
mapping.AddASN1ObjectIdentifier(testOID3)
mapping.AddASN1ObjectIdentifier(testOID2)
})
// Map all pairs of OID4 and OID5 to each other.
seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) {
mapping.AddASN1ObjectIdentifier(testOID4)
mapping.AddASN1ObjectIdentifier(testOID4)
})
seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) {
mapping.AddASN1ObjectIdentifier(testOID4)
mapping.AddASN1ObjectIdentifier(testOID5)
})
seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) {
mapping.AddASN1ObjectIdentifier(testOID5)
mapping.AddASN1ObjectIdentifier(testOID4)
})
seq.AddASN1(cbasn1.SEQUENCE, func(mapping *cryptobyte.Builder) {
mapping.AddASN1ObjectIdentifier(testOID5)
mapping.AddASN1ObjectIdentifier(testOID5)
})
})
intermediateMapped := intermediate
intermediateMapped.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1, testOID2, testOID3, testOID4, testOID5}
intermediateMapped.template.ExtraExtensions = []pkix.Extension{{Id: policyMappingsOID, Value: b.BytesOrPanic()}}
mustGenerateCertificate("policy_intermediate_mapped.pem", &intermediateMapped, &root)
intermediateMapped.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID}
mustGenerateCertificate("policy_intermediate_mapped_any.pem", &intermediateMapped, &root)
intermediateMapped.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID3}
mustGenerateCertificate("policy_intermediate_mapped_oid3.pem", &intermediateMapped, &root)
// Leaves which assert more specific OIDs, to test intermediate_mapped.
leafSingle := leaf
leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID1}
mustGenerateCertificate("policy_leaf_oid1.pem", &leafSingle, &intermediate)
leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID2}
mustGenerateCertificate("policy_leaf_oid2.pem", &leafSingle, &intermediate)
leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID3}
mustGenerateCertificate("policy_leaf_oid3.pem", &leafSingle, &intermediate)
leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID4}
mustGenerateCertificate("policy_leaf_oid4.pem", &leafSingle, &intermediate)
leafSingle.template.PolicyIdentifiers = []asn1.ObjectIdentifier{testOID5}
mustGenerateCertificate("policy_leaf_oid5.pem", &leafSingle, &intermediate)
leafNone := leaf
leafNone.template.PolicyIdentifiers = nil
mustGenerateCertificate("policy_leaf_none.pem", &leafNone, &intermediate)
// Make version of Root, signed by Root 2, with policy mapping inhibited.
// This can be combined with intermediateMapped to test the combination.
b = cryptobyte.NewBuilder(nil)
b.AddASN1(cbasn1.SEQUENCE, func(seq *cryptobyte.Builder) {
seq.AddASN1Int64WithTag(0, cbasn1.Tag(1).ContextSpecific())
})
inhibitPolicyMapping0 := b.BytesOrPanic()
inhibitMapping := root
inhibitMapping.template.PolicyIdentifiers = []asn1.ObjectIdentifier{anyPolicyOID}
inhibitMapping.template.ExtraExtensions = []pkix.Extension{{Id: policyConstraintsOID, Value: inhibitPolicyMapping0}}
mustGenerateCertificate("policy_root_cross_inhibit_mapping.pem", &inhibitMapping, &root2)
}
const leafKeyPEM = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgoPUXNXuH9mgiS/nk
024SYxryxMa3CyGJldiHymLxSquhRANCAASRKti8VW2Rkma+Kt9jQkMNitlCs0l5
w8u3SSwm7HZREvmcBCJBjVIREacRqI0umhzR2V5NLzBBP9yPD/A+Ch5X
-----END PRIVATE KEY-----`
const intermediateKeyPEM = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgWHKCKgY058ahE3t6
vpxVQgzlycgCVMogwjK0y3XMNfWhRANCAATiOnyojN4xS5C8gJ/PHL5cOEsMbsoE
Y6KT9xRQSh8lEL4d1Vb36kqUgkpqedEImo0Og4Owk6VWVVR/m4Lk+yUw
-----END PRIVATE KEY-----`
const rootKeyPEM = `-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgBwND/eHytW0I417J
Hr+qcPlp5N1jM3ACXys57bPujg+hRANCAAQmdqXYl1GvY7y3jcTTK6MVXIQr44Tq
ChRYI6IeV9tIB6jIsOY+Qol1bk8x/7A5FGOnUWFVLEAPEPSJwPndjolt
-----END PRIVATE KEY-----`
func mustParseECDSAKey(in string) *ecdsa.PrivateKey {
keyBlock, _ := pem.Decode([]byte(in))
if keyBlock == nil || keyBlock.Type != "PRIVATE KEY" {
panic("could not decode private key")
}
key, err := x509.ParsePKCS8PrivateKey(keyBlock.Bytes)
if err != nil {
panic(err)
}
return key.(*ecdsa.PrivateKey)
}