Use remote signer in CA testing
This commit is contained in:
parent
b5d67c733a
commit
34da176328
|
@ -7,10 +7,16 @@ package ca
|
|||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/asn1"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
apisign "github.com/cloudflare/cfssl/api/sign"
|
||||
"github.com/cloudflare/cfssl/auth"
|
||||
"github.com/cloudflare/cfssl/config"
|
||||
"github.com/cloudflare/cfssl/signer/local"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
|
||||
|
@ -108,24 +114,109 @@ var CA_CERT_PEM = "-----BEGIN CERTIFICATE-----\n" +
|
|||
// * Random public key
|
||||
// * CN = example.com
|
||||
// * DNSNames = example.com, www.example.com
|
||||
var CSR_HEX = "308202953082017d0201003016311430120603" +
|
||||
"550403130b6578616d706c652e636f6d30820122300d06092a864886f70d0101010500038201" +
|
||||
"0f003082010a0282010100baaf16e891828470cad87b849a73356f65e20ad3699fd5583a7200" +
|
||||
"e924512d9eeb1dbe16441ad7bd804fa2e5726a06f0af5279012fe6354a5677259f5591984aa9" +
|
||||
"99b8ea3ea10fbd5ecfa30e5f563b41c419374decfc98ea62c611046ad011c326470a2426f46d" +
|
||||
"be6cc44fae3b247e19710810585f9f3ad7f64b2f305aebb72e2829866f89b20b03a300b7ff5f" +
|
||||
"4e6204f41420d9fa731252692cee8e616636723abe8a7053fd86e2673190fa8b618ada5bc735" +
|
||||
"ba57a145af86904a8f55a288d4d6ba9e501530f23f197f5b623443193fc92b7f87d6abbf740d" +
|
||||
"9fc92800c7e0e1484d5eec6ffae1007c139c1ec19d67e749743fe8d8396fe190cfbcf2f90e05" +
|
||||
"230203010001a03a303806092a864886f70d01090e312b302930270603551d110420301e820b" +
|
||||
"6578616d706c652e636f6d820f7777772e6578616d706c652e636f6d300d06092a864886f70d" +
|
||||
"01010b05000382010100514c622dc866b31c86777a26e9b2911618ce5b188591f08007b42772" +
|
||||
"3497b733676a7d493c434fc819b8089869442fd299aa99ff7f7b9df881843727f0c8b89ca62a" +
|
||||
"f8a12b38c963e9210148c4e1c0fc964aef2605f88ed777e6497d2e43e9a9713835d1ae96260c" +
|
||||
"ca826c34c7ae52c77f5d8468643ee1936eadf04e1ebf8bbbb68b0ec7d0ef694432451292e4a3" +
|
||||
"1989fd8339c07e01e04b6dd3834872b828d3f5b2b4dadda0596396e15fbdf446998066a74873" +
|
||||
"2baf53f3f7ebb849e83cf734753c35ab454d1b62e1741a6514c5c575c0c805b4d668fcf71746" +
|
||||
"ef32017613a52d6b807e2977f4fbc0a88b2e263347c4d9e35435333cf4f8288be53df41228ec"
|
||||
var CN_AND_SAN_CSR_HEX = "308202a130820189020100301a311830160603550403130f6e6f742d6578" +
|
||||
"616d706c652e636f6d30820122300d06092a864886f70d01010105000382" +
|
||||
"010f003082010a0282010100e56ccbe37003c150202e6f543f9eb1d0e590" +
|
||||
"76ac7f1f62654fa82fe131a23c66bd53a2f62ff7852015c84a394e36836d" +
|
||||
"2018eba278e0740c85c4c6102787400c2ef069b4a72e6eb8ad8d1da5d76b" +
|
||||
"f3e70dafc126578ed28cf40030e7fe5b5307ef630254726c639561b5445d" +
|
||||
"372847bdb02576aa3622a688158c6af09d3938dbeba4d670cec4325be73a" +
|
||||
"fa52a0a04dcba2f335f1e85020704db94ca125dce70b3209294c6c46ed4b" +
|
||||
"48b95d8d51ae2d2fd227116023a48ca7381e35fd302ad2999df625a4b5ee" +
|
||||
"82a0d0fefa88ac6a62b01674de75637ef83328202cda9930947d932000b0" +
|
||||
"e53b82e099ab60fec9c8b6d4eccdee508b6ebca7e6ca3f752046c8350203" +
|
||||
"010001a042304006092a864886f70d01090e31333031302f0603551d1104" +
|
||||
"283026820f6e6f742d6578616d706c652e636f6d82137777772e6e6f742d" +
|
||||
"6578616d706c652e636f6d300d06092a864886f70d01010b050003820101" +
|
||||
"008c4bf2ab4dfd28d768697eecc5be889a6275287c7dd24f9232ffad5675" +
|
||||
"de708c9cc911545d0e84f61b6584c5e237915bbf231d6518e7e228be2e65" +
|
||||
"b4d50bd9729ce9e6aee00482e014de4edd4b9a4f9a7777b8943ef3512dbf" +
|
||||
"940ac561c25b34ded9db1074136b978a65943ab1259608fb8109e008eac6" +
|
||||
"23d7b29b2f1fad3a8e358aa070ead688016d9efed6da43412b136903de07" +
|
||||
"137462d3f9203a344d84d7eb336999004e7e9972d5176001e2792f206e6c" +
|
||||
"7c70b86d312459f21751d29ea53b41f9d02a229f9d7615b2a7ac83e849d0" +
|
||||
"d0d9f8a08f8d7ba23295e77c95bc060c9227bfec0afb8c898e33c89903d7" +
|
||||
"bbde4cf059dcc3e6c4ae4eef207c499d62"
|
||||
|
||||
// CSR generated by Go:
|
||||
// * Random public key
|
||||
// * CN = not-example.com
|
||||
// * DNSNames = [none]
|
||||
var NO_SAN_CSR_HEX = "3082025f30820147020100301a311830160603550403130f6e6f742d6578" +
|
||||
"616d706c652e636f6d30820122300d06092a864886f70d01010105000382" +
|
||||
"010f003082010a0282010100aa6e56ff24906f93b855e7871dc8411a3cf7" +
|
||||
"678d9563627e8ca37ab17dfe814ef7f828d6aa92b717f0da9df56990b953" +
|
||||
"989d5afc3f2dddacd2b504b89782b49e55a04a64a4370d8ab1b2688f2596" +
|
||||
"98132e5ce536f812ef5eb13824a922bbb89e30d6f2cace77462b9e65264a" +
|
||||
"32320a7b348f9903b16640bc8c1c5f1208c6b456fd85bfa96ee9b7642c68" +
|
||||
"3ab05b142d249525a730b230b39f2ba8d6f253263b5c3948b1a3d8a3467f" +
|
||||
"7cfcdd1fdd6bff7828fda12784fd277be8c680fcdf2cc4676acff5df759f" +
|
||||
"f4bc712ee1a560157233cbf6bb4bcb91dd1c5d2824b42f4913e4715c1ba4" +
|
||||
"001fde0d90c274bfa81a79e4a0d00a7ddcbfdd8de4183b497487a20d0203" +
|
||||
"010001a000300d06092a864886f70d01010b050003820101000ead204cfd" +
|
||||
"45d307dd49de6937d7e2d8abf17490a49a8cee5250ef7799ef53229f8cfc" +
|
||||
"735b9f65d789f898945f3d5536a09932e241050bd5473c47a4ac2493707f" +
|
||||
"1142bf9a06d047384ad463463acb3744d435b4cff8c8b0f9673e8700e13b" +
|
||||
"6bc99a486823fa85f7707e1bb8430e62541715ab6cb3fae3efb8356042a5" +
|
||||
"c9f493dd08eff690570cce65cffc4fe354aa40957dc16a37a833aa968f62" +
|
||||
"693d5059d53f6a96a159195d3fb7b558d462de63d945d4e3680d2b1f2c98" +
|
||||
"33c3bfd92a9235de3d345a431ee5a675e0e18308bd2729413acd84432da4" +
|
||||
"2410e1b87ae70227dd9a98e49ee6aeea9eaff67f968691918201e94697f2" +
|
||||
"da010d6f939cea40c26038"
|
||||
|
||||
// CSR generated by Go:
|
||||
// * Random public key
|
||||
// * C = US
|
||||
// * CN = [none]
|
||||
// * DNSNames = not-example.com
|
||||
var NO_CN_CSR_HEX = "3082027f30820167020100300d310b300906035504061302555330820122" +
|
||||
"300d06092a864886f70d01010105000382010f003082010a0282010100d8" +
|
||||
"b3c11610ce17614f6d78de3f079db430e479c38978da8cd625b7c70dd445" +
|
||||
"57fd99b9831693e6b9b09fb7c74a82058a1f1a4e1e087f04f93aa73bc35a" +
|
||||
"688440205a6f5fd56ff478c5554b14c3b2a1a0b5eed1aef7189ad848e117" +
|
||||
"04b1eb6c29b47ada40a5719a38ce2f2869896bf5405c2bafd4c7dfb99c0e" +
|
||||
"9f26f80145e16b73bbacf67aedcd3b7ce57bb5b67cf692aec7956d23c236" +
|
||||
"2336c2408b65469630dccca3ca006f28e36ca8c95dda84b6586f29c8de63" +
|
||||
"661c09b58253e386a74707394cbba4de165f2745a65b717b9fd4b8b84c09" +
|
||||
"85583b5c17d3e88bbf71c88eeeccb5d552d61cde7835ec83d6ec9b41114a" +
|
||||
"0583f8eeae8a536cb3ca5786c22ab30203010001a02d302b06092a864886" +
|
||||
"f70d01090e311e301c301a0603551d1104133011820f6e6f742d6578616d" +
|
||||
"706c652e636f6d300d06092a864886f70d01010b05000382010100430239" +
|
||||
"8db6b64b94d93399db32335232967ca6a748048483db8cb2b387871f758c" +
|
||||
"6f7bf1593624b142127847cd2a511897bbadd8ad038468fb309fa2161031" +
|
||||
"949b9ba24931b0d363ad2f8dae56a4c908ba748d41c664aa129dcb1a6f88" +
|
||||
"0b90502cd244d9abd8dd5e78f763730660655a350f1c25af95cf1f89dda9" +
|
||||
"076f4e6b84b6da9a98ed87f538624e4338fa0ff1a404e763dd6800694a21" +
|
||||
"d28595927606308aefa1ac7e8f5600b05e33c0a7b25d3a9f5032c7c25264" +
|
||||
"026c039733b179315254af4f25e90a1d00facd69313b36fdc66a5818fb49" +
|
||||
"a0d90e0745d66a82d337289c9968b3ec4a4826c530c758cacecc18e06366" +
|
||||
"dd8962c451c3ce22c2aed33726"
|
||||
|
||||
// CSR generated by Go:
|
||||
// * Random public key
|
||||
// * C = US
|
||||
// * CN = [none]
|
||||
// * DNSNames = [none]
|
||||
var NO_NAME_CSR_HEX = "308202523082013a020100300d310b300906035504061302555330820122" +
|
||||
"300d06092a864886f70d01010105000382010f003082010a0282010100bc" +
|
||||
"fae49f68f02c42500b2faf251628ee19e8ef048a35fef311c9c419c80606" +
|
||||
"ab37340ad6e25cf4cc63c0283994b4ba705d86950ad5298094e0b9684647" +
|
||||
"8d67abc695741317b4ff8da9fd33120342559cfdaf9109ac403f0d0bf9ff" +
|
||||
"54dd79fa2256b218a9bdb17c608167c7fcad4cf839733c7eab9589fe6137" +
|
||||
"e99bb24c24b7eb74e19f51ffee4ea62c4ab756f099ff5197c5032f60edff" +
|
||||
"36022b8a99d35aeb706854fa9a31ea8a362a2251f08b93023b32e1df771a" +
|
||||
"970f08a30ced656950b8ef71600d65d6995a0b92903b179c05a76f702a08" +
|
||||
"0b41402c308d8ab57f14b5516b89fe317e38e13d7adad7f7025743610881" +
|
||||
"9fb60268f0773b08b62ac8c8c84f2d0203010001a000300d06092a864886" +
|
||||
"f70d01010b050003820101001eda9ce8253e8b933348851acd38ab63cd64" +
|
||||
"f833d7ffc711f1b6e6a37a7deb7ad44b5589d90533ed61dfd48cab2775e2" +
|
||||
"a19c41f5cb69faa9dde856606822a3bf798381836214154c17bc037f23ad" +
|
||||
"67c84d876855c0aea871dc55bd14b2cd267e49b734bc7a38c29c334611bf" +
|
||||
"ec7efdc56a1512e25fd12ca99a5809b1b6a808caf6a8baefff7fb2bda454" +
|
||||
"5c226849674900ce7a1f90287ab31be80a4e2b6d64765b9d973628e60299" +
|
||||
"6423edd74e7a58005bd520d4173f0c30d935de530477480d7725d9758f9a" +
|
||||
"58c004d9e1e55af59ea517dfbd2bccca58216d8130b9f77c90328b2aa54b" +
|
||||
"1778a629b584f2bc059489a236131de9b444adca90218c31a499a485"
|
||||
|
||||
func TestIssueCertificate(t *testing.T) {
|
||||
// Decode pre-generated values
|
||||
|
@ -135,44 +226,92 @@ func TestIssueCertificate(t *testing.T) {
|
|||
caCertPEM, _ := pem.Decode([]byte(CA_CERT_PEM))
|
||||
caCert, _ := x509.ParseCertificate(caCertPEM.Bytes)
|
||||
|
||||
csrDER, _ := hex.DecodeString(CSR_HEX)
|
||||
csr, _ := x509.ParseCertificateRequest(csrDER)
|
||||
// Uncomment to create a CFSSL local signer
|
||||
|
||||
// Create a CFSSL local signer
|
||||
signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, nil)
|
||||
// CFSSL config
|
||||
hostPort := "localhost:9000"
|
||||
authKey := "79999d86250c367a2b517a1ae7d409c1"
|
||||
profileName := "ee"
|
||||
|
||||
// Create an SA
|
||||
sa, err := sa.NewSQLStorageAuthority("sqlite3", ":memory:")
|
||||
test.AssertNotError(t, err, "Failed to create SA")
|
||||
sa.InitTables()
|
||||
|
||||
// Create an online CFSSL instance
|
||||
// This is designed to mimic what LE plans to do
|
||||
authHandler, err := auth.New(authKey, nil)
|
||||
test.AssertNotError(t, err, "Failed to create authentication handler")
|
||||
policy := &config.Signing{
|
||||
Profiles: map[string]*config.SigningProfile{
|
||||
profileName: &config.SigningProfile{
|
||||
Usage: []string{"server auth"},
|
||||
CA: false,
|
||||
IssuerURL: []string{"http://not-example.com/issuer-url"},
|
||||
OCSP: "http://not-example.com/ocsp",
|
||||
CRL: "http://not-example.com/crl",
|
||||
|
||||
Policies: []asn1.ObjectIdentifier{
|
||||
asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1},
|
||||
},
|
||||
Expiry: 8760 * time.Hour,
|
||||
Backdate: time.Hour,
|
||||
Provider: authHandler,
|
||||
},
|
||||
},
|
||||
Default: &config.SigningProfile{
|
||||
Expiry: time.Hour,
|
||||
},
|
||||
}
|
||||
signer, err := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, policy)
|
||||
test.AssertNotError(t, err, "Failed to create signer")
|
||||
signHandler, err := apisign.NewAuthHandlerFromSigner(signer)
|
||||
test.AssertNotError(t, err, "Failed to create signing API endpoint")
|
||||
http.Handle("/api/v1/cfssl/authsign", signHandler)
|
||||
// This goroutine should get killed when main() return
|
||||
go (func() { http.ListenAndServe(hostPort, nil) })()
|
||||
|
||||
// Create a CA
|
||||
// Uncomment to test with a remote signer
|
||||
ca, err := NewCertificateAuthorityImpl(hostPort, authKey, profileName)
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
ca.SA = sa
|
||||
|
||||
/*
|
||||
// Uncomment to test with a remote signer
|
||||
ca, err := NewCertificateAuthorityImpl("localhost:9000", "79999d86250c367a2b517a1ae7d409c1", "ee")
|
||||
test.AssertNotError(t, err, "Failed to create CA")
|
||||
ca.SA = sa
|
||||
// Uncomment to test with a local signer
|
||||
signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, nil)
|
||||
ca := CertificateAuthorityImpl{
|
||||
Signer: signer,
|
||||
SA: sa,
|
||||
}
|
||||
*/
|
||||
ca := CertificateAuthorityImpl{
|
||||
Signer: signer,
|
||||
SA: sa,
|
||||
|
||||
csrs := []string{CN_AND_SAN_CSR_HEX, NO_SAN_CSR_HEX, NO_CN_CSR_HEX}
|
||||
for _, csrHEX := range csrs {
|
||||
csrDER, _ := hex.DecodeString(csrHEX)
|
||||
csr, _ := x509.ParseCertificateRequest(csrDER)
|
||||
|
||||
// Sign CSR
|
||||
certObj, err := ca.IssueCertificate(*csr)
|
||||
test.AssertNotError(t, err, "Failed to sign certificate")
|
||||
|
||||
// Verify cert contents
|
||||
cert, err := x509.ParseCertificate(certObj.DER)
|
||||
test.AssertNotError(t, err, "Certificate failed to parse")
|
||||
|
||||
test.AssertEquals(t, cert.Subject.CommonName, "not-example.com")
|
||||
|
||||
if len(cert.DNSNames) == 0 || cert.DNSNames[0] != "not-example.com" {
|
||||
// NB: This does not check for www.not-example.com in the 'both' case
|
||||
t.Errorf("Improper list of domain names %v", cert.DNSNames)
|
||||
}
|
||||
|
||||
if len(cert.Subject.Country) > 0 {
|
||||
t.Errorf("Subject contained unauthorized values")
|
||||
}
|
||||
|
||||
// Verify that the cert got stored in the DB
|
||||
_, err = sa.GetCertificate(certObj.ID)
|
||||
test.AssertNotError(t, err, "Certificate not found in database")
|
||||
}
|
||||
|
||||
// Sign CSR
|
||||
certObj, err := ca.IssueCertificate(*csr)
|
||||
test.AssertNotError(t, err, "Failed to sign certificate")
|
||||
|
||||
// Verify cert contents
|
||||
cert, err := x509.ParseCertificate(certObj.DER)
|
||||
test.AssertNotError(t, err, "Certificate failed to parse")
|
||||
|
||||
test.AssertEquals(t, cert.Subject.CommonName, "example.com")
|
||||
|
||||
if len(cert.DNSNames) != 2 || cert.DNSNames[0] != "example.com" || cert.DNSNames[1] != "www.example.com" {
|
||||
t.Errorf("Improper list of domain names %v", cert.DNSNames)
|
||||
}
|
||||
|
||||
// Verify that the cert got stored in the DB
|
||||
_, err = sa.GetCertificate(certObj.ID)
|
||||
test.AssertNotError(t, err, "Certificate not found in database")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue