mirror of https://github.com/k3s-io/k3s
Merge pull request #41431 from jcbsmpsn/split-make-csr
Automatic merge from submit-queue (batch tested with PRs 38101, 41431, 39606, 41569, 41509) Split MakeCSR for new signature.pull/6/head
commit
dfd4e6ba0b
|
@ -28,36 +28,48 @@ import (
|
|||
// MakeCSR generates a PEM-encoded CSR using the supplied private key, subject, and SANs.
|
||||
// All key types that are implemented via crypto.Signer are supported (This includes *rsa.PrivateKey and *ecdsa.PrivateKey.)
|
||||
func MakeCSR(privateKey interface{}, subject *pkix.Name, dnsSANs []string, ipSANs []net.IP) (csr []byte, err error) {
|
||||
// Customize the signature for RSA keys, depending on the key size
|
||||
var sigType x509.SignatureAlgorithm
|
||||
if privateKey, ok := privateKey.(*rsa.PrivateKey); ok {
|
||||
keySize := privateKey.N.BitLen()
|
||||
switch {
|
||||
case keySize >= 4096:
|
||||
sigType = x509.SHA512WithRSA
|
||||
case keySize >= 3072:
|
||||
sigType = x509.SHA384WithRSA
|
||||
default:
|
||||
sigType = x509.SHA256WithRSA
|
||||
}
|
||||
}
|
||||
|
||||
template := &x509.CertificateRequest{
|
||||
Subject: *subject,
|
||||
SignatureAlgorithm: sigType,
|
||||
DNSNames: dnsSANs,
|
||||
IPAddresses: ipSANs,
|
||||
Subject: *subject,
|
||||
DNSNames: dnsSANs,
|
||||
IPAddresses: ipSANs,
|
||||
}
|
||||
|
||||
csr, err = x509.CreateCertificateRequest(cryptorand.Reader, template, privateKey)
|
||||
return MakeCSRFromTemplate(privateKey, template)
|
||||
}
|
||||
|
||||
// MakeCSRFromTemplate generates a PEM-encoded CSR using the supplied private
|
||||
// key and certificate request as a template. All key types that are
|
||||
// implemented via crypto.Signer are supported (This includes *rsa.PrivateKey
|
||||
// and *ecdsa.PrivateKey.)
|
||||
func MakeCSRFromTemplate(privateKey interface{}, template *x509.CertificateRequest) ([]byte, error) {
|
||||
t := *template
|
||||
t.SignatureAlgorithm = sigType(privateKey)
|
||||
|
||||
csrDER, err := x509.CreateCertificateRequest(cryptorand.Reader, &t, privateKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
csrPemBlock := &pem.Block{
|
||||
Type: "CERTIFICATE REQUEST",
|
||||
Bytes: csr,
|
||||
Bytes: csrDER,
|
||||
}
|
||||
|
||||
return pem.EncodeToMemory(csrPemBlock), nil
|
||||
}
|
||||
|
||||
func sigType(privateKey interface{}) x509.SignatureAlgorithm {
|
||||
// Customize the signature for RSA keys, depending on the key size
|
||||
if privateKey, ok := privateKey.(*rsa.PrivateKey); ok {
|
||||
keySize := privateKey.N.BitLen()
|
||||
switch {
|
||||
case keySize >= 4096:
|
||||
return x509.SHA512WithRSA
|
||||
case keySize >= 3072:
|
||||
return x509.SHA384WithRSA
|
||||
default:
|
||||
return x509.SHA256WithRSA
|
||||
}
|
||||
}
|
||||
return x509.UnknownSignatureAlgorithm
|
||||
}
|
||||
|
|
|
@ -17,7 +17,9 @@ limitations under the License.
|
|||
package cert
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"testing"
|
||||
|
@ -39,8 +41,35 @@ func TestMakeCSR(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = MakeCSR(key, subject, dnsSANs, ipSANs)
|
||||
csrPEM, err := MakeCSR(key, subject, dnsSANs, ipSANs)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
csrBlock, rest := pem.Decode(csrPEM)
|
||||
if csrBlock == nil {
|
||||
t.Error("Unable to decode MakeCSR result.")
|
||||
}
|
||||
if len(rest) != 0 {
|
||||
t.Error("Found more than one PEM encoded block in the result.")
|
||||
}
|
||||
if csrBlock.Type != "CERTIFICATE REQUEST" {
|
||||
t.Errorf("Found block type %q, wanted 'CERTIFICATE REQUEST'", csrBlock.Type)
|
||||
}
|
||||
csr, err := x509.ParseCertificateRequest(csrBlock.Bytes)
|
||||
if err != nil {
|
||||
t.Errorf("Found %v parsing MakeCSR result as a CertificateRequest.", err)
|
||||
}
|
||||
if csr.Subject.CommonName != subject.CommonName {
|
||||
t.Errorf("Wanted %v, got %v", subject, csr.Subject)
|
||||
}
|
||||
if len(csr.DNSNames) != 1 {
|
||||
t.Errorf("Wanted 1 DNS name in the result, got %d", len(csr.DNSNames))
|
||||
} else if csr.DNSNames[0] != dnsSANs[0] {
|
||||
t.Errorf("Wanted %v, got %v", dnsSANs[0], csr.DNSNames[0])
|
||||
}
|
||||
if len(csr.IPAddresses) != 1 {
|
||||
t.Errorf("Wanted 1 IP address in the result, got %d", len(csr.IPAddresses))
|
||||
} else if csr.IPAddresses[0].String() != ipSANs[0].String() {
|
||||
t.Errorf("Wanted %v, got %v", ipSANs[0], csr.IPAddresses[0])
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue