forked from TrueCloudLab/certificates
Merge pull request #958 from smallstep/rsa-signature-algorithm
Sign certificates with the issuer signature algorithm
This commit is contained in:
commit
f140874e42
3 changed files with 69 additions and 0 deletions
|
@ -4,6 +4,10 @@ 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/)
|
||||
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 be signed using the same algorithm as the issuer certificate was signed with. The signature will no longer default to PKCS #1. For example, if the issuer certificate was signed using RSA-PSS with SHA-256, a new certificate will also be signed using RSA-PSS with SHA-256.
|
||||
|
||||
## [0.20.0] - 2022-05-26
|
||||
### Added
|
||||
- Added Kubernetes auth method for Vault RAs.
|
||||
|
|
|
@ -3,6 +3,7 @@ package softcas
|
|||
import (
|
||||
"context"
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"time"
|
||||
|
||||
|
@ -244,6 +245,8 @@ func createCertificate(template, parent *x509.Certificate, pub crypto.PublicKey,
|
|||
if template.SignatureAlgorithm == 0 {
|
||||
if sa, ok := signer.(apiv1.SignatureAlgorithmGetter); ok {
|
||||
template.SignatureAlgorithm = sa.SignatureAlgorithm()
|
||||
} else if _, ok := parent.PublicKey.(*rsa.PublicKey); ok {
|
||||
template.SignatureAlgorithm = parent.SignatureAlgorithm
|
||||
}
|
||||
}
|
||||
return x509util.CreateCertificate(template, parent, pub, signer)
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"context"
|
||||
"crypto"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"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) {
|
||||
mockNow(t)
|
||||
|
||||
|
|
Loading…
Reference in a new issue