Merge pull request #958 from smallstep/rsa-signature-algorithm

Sign certificates with the issuer signature algorithm
This commit is contained in:
Mariano Cano 2022-06-16 15:08:10 -07:00 committed by GitHub
commit f140874e42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 0 deletions

View file

@ -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/) 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 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 ## [0.20.0] - 2022-05-26
### Added ### Added
- Added Kubernetes auth method for Vault RAs. - Added Kubernetes auth method for Vault RAs.

View file

@ -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)

View file

@ -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)