Hello, I want to create a self-signed X.509 certificate through the following PKCS #11 implementation: https://pkg.go.dev/github.com/miekg/[email protected]/p11.
privateKeyObject, err = t.session.FindObject(privateKeyTemplate)
if err != nil {
return nil, err
}
certTemplate := &x509.Certificate{
SerialNumber: big.NewInt(2022),
Subject: pkix.Name{
CommonName: "test",
},
SignatureAlgorithm: x509.SHA512WithRSA,
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(1, 0, 0),
}
signer, err = NewSigner(p11.PrivateKey(privateKeyObject))
if err != nil {
return nil, err
}
cert, err = x509.CreateCertificate(rand.Reader, certTemplate, certTemplate, signer.PublicKey, signer)
if err != nil {
return nil, err
}
Of course I had to implement the crypto.Signer interface because RSA key pair is stored in an HSM.
type Signer struct {
PrivateKey p11.PrivateKey
PublicKey *rsa.PublicKey
}
func (s Signer) Public() crypto.PublicKey {
return s.PublicKey
}
func (s Signer) Sign(_ io.Reader, digest []byte, _ crypto.SignerOpts) ([]byte, error) {
return s.PrivateKey.Sign(pkcs11.Mechanism{Mechanism: pkcs11.CKM_SHA512_RSA_PKCS}, digest)
}
func NewSigner(privateKey p11.PrivateKey) (*Signer, error) {
var (
modulus, publicExponent []byte
err error
)
modulus, err = p11.Object(privateKey).Attribute(pkcs11.CKA_MODULUS)
if err != nil {
return nil, err
}
publicExponent, err = p11.Object(privateKey).Attribute(pkcs11.CKA_PUBLIC_EXPONENT)
if err != nil {
return nil, err
}
publicKey := &rsa.PublicKey{
N: new(big.Int).SetBytes(modulus),
E: int(big.NewInt(0).SetBytes(publicExponent).Uint64()),
}
return &Signer{PrivateKey: privateKey, PublicKey: publicKey}, nil
}