blob: eec602de3ab8aac8219a6b279dec82fd388fbb94 [file] [log] [blame]
// Copyright 2025 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_unusual_tbs.go refreshes the signatures on the unusual_tbs_*.pem
// certificates.
package main
import (
"crypto"
"crypto/rand"
_ "crypto/sha256"
"crypto/x509"
"encoding/pem"
"fmt"
"os"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
)
func updateSignature(path string, key crypto.Signer, opts crypto.SignerOpts) error {
inp, err := os.ReadFile(path)
if err != nil {
return err
}
block, _ := pem.Decode(inp)
if block == nil || block.Type != "CERTIFICATE" {
return fmt.Errorf("%q did not contain a PEM CERTIFICATE block", path)
}
s := cryptobyte.String(block.Bytes)
var cert, tbsCert, sigAlg cryptobyte.String
if !s.ReadASN1(&cert, asn1.SEQUENCE) ||
!cert.ReadASN1Element(&tbsCert, asn1.SEQUENCE) ||
!cert.ReadASN1Element(&sigAlg, asn1.SEQUENCE) {
return fmt.Errorf("could not parse certificate in %q", path)
}
h := opts.HashFunc().New()
h.Write(tbsCert)
digest := h.Sum(nil)
signature, err := key.Sign(rand.Reader, digest, opts)
if err != nil {
return err
}
b := cryptobyte.NewBuilder(nil)
b.AddASN1(asn1.SEQUENCE, func(child *cryptobyte.Builder) {
child.AddBytes(tbsCert)
child.AddBytes(sigAlg)
child.AddASN1BitString(signature)
})
newCert, err := b.Bytes()
if err != nil {
return err
}
newPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: newCert})
return os.WriteFile(path, newPEM, 0644)
}
func loadPEMPrivateKey(path string) (crypto.Signer, error) {
inp, err := os.ReadFile(path)
if err != nil {
return nil, err
}
block, _ := pem.Decode(inp)
if block == nil || block.Type != "PRIVATE KEY" {
return nil, fmt.Errorf("%q did not contain a PEM PRIVATE KEY block", path)
}
key, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return nil, err
}
signer, ok := key.(crypto.Signer)
if !ok {
return nil, fmt.Errorf("key in %q was not a signing key", path)
}
return signer, nil
}
func main() {
key, err := loadPEMPrivateKey("unusual_tbs_key.pem")
if err != nil {
fmt.Fprintf(os.Stderr, "Error loading private key: %s\n", err)
os.Exit(1)
}
paths := []string{
"unusual_tbs_empty_extension_not_omitted.pem",
"unusual_tbs_null_sigalg_param.pem",
"unusual_tbs_uid_both.pem",
"unusual_tbs_uid_issuer.pem",
"unusual_tbs_uid_subject.pem",
"unusual_tbs_wrong_attribute_order.pem",
"unusual_tbs_v1_not_omitted.pem",
}
for _, path := range paths {
if err := updateSignature(path, key, crypto.SHA256); err != nil {
fmt.Fprintf(os.Stderr, "Error signing %q: %s\n", path, err)
os.Exit(1)
}
}
}