forked from TrueCloudLab/certificates
Sign certificates with the issuer signature algorithm
An RSA key can sign another certificates using the RSA PKCS#1 and the RSA-PSS scheme, this change will keep the signature algorithm used in the issuer in the signed certificates instead of using PKCS#1 by default.
This commit is contained in:
parent
34d141e4d5
commit
31af1efa48
3 changed files with 72 additions and 0 deletions
|
@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
### Changed
|
||||||
|
- Certificates signed by an issuer using an RSA key will use the same algorithm
|
||||||
|
and not default to PKCS #1. For example, if the issuer certificate uses
|
||||||
|
x509.SHA256WithRSAPSS, the signed certificate will also be signed using
|
||||||
|
x509.SHA256WithRSAPSS.
|
||||||
|
|
||||||
## [0.20.0] - 2022-05-26
|
## [0.20.0] - 2022-05-26
|
||||||
### Added
|
### Added
|
||||||
- Added Kubernetes auth method for Vault RAs.
|
- Added Kubernetes auth method for Vault RAs.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package softcas
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto"
|
"crypto"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -244,6 +245,8 @@ func createCertificate(template, parent *x509.Certificate, pub crypto.PublicKey,
|
||||||
if template.SignatureAlgorithm == 0 {
|
if template.SignatureAlgorithm == 0 {
|
||||||
if sa, ok := signer.(apiv1.SignatureAlgorithmGetter); ok {
|
if sa, ok := signer.(apiv1.SignatureAlgorithmGetter); ok {
|
||||||
template.SignatureAlgorithm = sa.SignatureAlgorithm()
|
template.SignatureAlgorithm = sa.SignatureAlgorithm()
|
||||||
|
} else if _, ok := parent.PublicKey.(*rsa.PublicKey); ok {
|
||||||
|
template.SignatureAlgorithm = parent.SignatureAlgorithm
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return x509util.CreateCertificate(template, parent, pub, signer)
|
return x509util.CreateCertificate(template, parent, pub, signer)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto"
|
"crypto"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"crypto/x509/pkix"
|
"crypto/x509/pkix"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -350,6 +351,67 @@ func TestSoftCAS_CreateCertificate(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSoftCAS_CreateCertificate_pss(t *testing.T) {
|
||||||
|
signer, err := rsa.GenerateKey(rand.Reader, 2048)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
template := &x509.Certificate{
|
||||||
|
Subject: pkix.Name{CommonName: "Test Root CA"},
|
||||||
|
KeyUsage: x509.KeyUsageCRLSign | x509.KeyUsageCertSign,
|
||||||
|
PublicKey: signer.Public(),
|
||||||
|
BasicConstraintsValid: true,
|
||||||
|
IsCA: true,
|
||||||
|
MaxPathLen: 0,
|
||||||
|
SerialNumber: big.NewInt(1234),
|
||||||
|
SignatureAlgorithm: x509.SHA256WithRSAPSS,
|
||||||
|
NotBefore: now,
|
||||||
|
NotAfter: now.Add(24 * time.Hour),
|
||||||
|
}
|
||||||
|
|
||||||
|
iss, err := x509util.CreateCertificate(template, template, signer.Public(), signer)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if iss.SignatureAlgorithm != x509.SHA256WithRSAPSS {
|
||||||
|
t.Errorf("Certificate.SignatureAlgorithm = %v, want %v", iss.SignatureAlgorithm, x509.SHA256WithRSAPSS)
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &SoftCAS{
|
||||||
|
CertificateChain: []*x509.Certificate{iss},
|
||||||
|
Signer: signer,
|
||||||
|
}
|
||||||
|
cert, err := c.CreateCertificate(&apiv1.CreateCertificateRequest{
|
||||||
|
Template: &x509.Certificate{
|
||||||
|
Subject: pkix.Name{CommonName: "test.smallstep.com"},
|
||||||
|
DNSNames: []string{"test.smallstep.com"},
|
||||||
|
KeyUsage: x509.KeyUsageDigitalSignature,
|
||||||
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
|
||||||
|
PublicKey: testSigner.Public(),
|
||||||
|
SerialNumber: big.NewInt(1234),
|
||||||
|
},
|
||||||
|
Lifetime: time.Hour, Backdate: time.Minute,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("SoftCAS.CreateCertificate() error = %v", err)
|
||||||
|
}
|
||||||
|
if cert.Certificate.SignatureAlgorithm != x509.SHA256WithRSAPSS {
|
||||||
|
t.Errorf("Certificate.SignatureAlgorithm = %v, want %v", iss.SignatureAlgorithm, x509.SHA256WithRSAPSS)
|
||||||
|
}
|
||||||
|
|
||||||
|
pool := x509.NewCertPool()
|
||||||
|
pool.AddCert(iss)
|
||||||
|
if _, err = cert.Certificate.Verify(x509.VerifyOptions{
|
||||||
|
CurrentTime: time.Now(),
|
||||||
|
Roots: pool,
|
||||||
|
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
|
||||||
|
}); err != nil {
|
||||||
|
t.Errorf("Certificate.Verify() error = %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestSoftCAS_RenewCertificate(t *testing.T) {
|
func TestSoftCAS_RenewCertificate(t *testing.T) {
|
||||||
mockNow(t)
|
mockNow(t)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue