func main() { app := cmd.NewAppShell("boulder-ra", "Handles service orchestration") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { // Validate PA config and set defaults if needed cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration") c.PA.SetDefaultChallengesIfEmpty() go cmd.DebugServer(c.RA.DebugAddr) paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist, c.PA.Challenges) cmd.FailOnError(err, "Couldn't create PA") rateLimitPolicies, err := cmd.LoadRateLimitPolicies(c.RA.RateLimitPoliciesFilename) cmd.FailOnError(err, "Couldn't load rate limit policies file") go cmd.ProfileCmd("RA", stats) amqpConf := c.RA.AMQP vac, err := rpc.NewValidationAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Unable to create SA client") var dc *ra.DomainCheck if c.RA.UseIsSafeDomain { dc = &ra.DomainCheck{VA: vac} } rai := ra.NewRegistrationAuthorityImpl(clock.Default(), auditlogger, stats, dc, rateLimitPolicies, c.RA.MaxContactsPerRegistration) rai.PA = pa raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse RA DNS timeout") if !c.Common.DNSAllowLoopbackAddresses { rai.DNSResolver = core.NewDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) } else { rai.DNSResolver = core.NewTestDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) } rai.VA = vac rai.CA = cac rai.SA = sac ras, err := rpc.NewAmqpRPCServer(amqpConf, c.RA.MaxConcurrentRPCServerRequests, stats) cmd.FailOnError(err, "Unable to create RA RPC server") rpc.NewRegistrationAuthorityServer(ras, rai) err = ras.Start(amqpConf) cmd.FailOnError(err, "Unable to run RA RPC server") } app.Run() }
// NewRegistrationAuthorityImpl constructs a new RA object. func NewRegistrationAuthorityImpl() RegistrationAuthorityImpl { logger := blog.GetAuditLogger() logger.Notice("Registration Authority Starting") ra := RegistrationAuthorityImpl{log: logger} ra.PA = policy.NewPolicyAuthorityImpl() return ra }
func main() { app := cmd.NewAppShell("boulder-ca", "Handles issuance operations") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.CA.DebugAddr) dbMap, err := sa.NewDbMap(c.CA.DBConnect) cmd.FailOnError(err, "Couldn't connect to CA database") cadb, err := ca.NewCertificateAuthorityDatabaseImpl(dbMap) cmd.FailOnError(err, "Failed to create CA database") paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist) cmd.FailOnError(err, "Couldn't create PA") cai, err := ca.NewCertificateAuthorityImpl(cadb, c.CA, clock.Default(), c.Common.IssuerCert) cmd.FailOnError(err, "Failed to create CA impl") cai.MaxKeySize = c.Common.MaxKeySize cai.PA = pa go cmd.ProfileCmd("CA", stats) connectionHandler := func(srv *rpc.AmqpRPCServer) { saRPC, err := rpc.NewAmqpRPCClient("CA->SA", c.AMQP.SA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Failed to create SA client") cai.SA = &sac } cas, err := rpc.NewAmqpRPCServer(c.AMQP.CA.Server, connectionHandler) cmd.FailOnError(err, "Unable to create CA RPC server") rpc.NewCertificateAuthorityServer(cas, cai) auditlogger.Info(app.VersionString()) err = cas.Start(c) cmd.FailOnError(err, "Unable to run CA RPC server") } app.Run() }
func newChecker(dbMap *gorp.DbMap) certChecker { c := certChecker{ pa: policy.NewPolicyAuthorityImpl(), dbMap: dbMap, certs: make(chan core.Certificate, batchSize), clock: clock.Default(), } c.issuedReport.Entries = make(map[string]reportEntry) return c }
func main() { app := cmd.NewAppShell("boulder-ca", "Handles issuance operations") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { // Validate PA config and set defaults if needed cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.CA.DebugAddr) dbURL, err := c.PA.DBConfig.URL() cmd.FailOnError(err, "Couldn't load DB URL") paDbMap, err := sa.NewDbMap(dbURL) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist, c.PA.Challenges) cmd.FailOnError(err, "Couldn't create PA") priv, err := loadPrivateKey(c.CA.Key) cmd.FailOnError(err, "Couldn't load private key") issuer, err := core.LoadCert(c.Common.IssuerCert) cmd.FailOnError(err, "Couldn't load issuer cert") cai, err := ca.NewCertificateAuthorityImpl( c.CA, clock.Default(), stats, issuer, priv, c.KeyPolicy()) cmd.FailOnError(err, "Failed to create CA impl") cai.PA = pa go cmd.ProfileCmd("CA", stats) amqpConf := c.CA.AMQP cai.SA, err = rpc.NewStorageAuthorityClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Failed to create SA client") cai.Publisher, err = rpc.NewPublisherClient(clientName, amqpConf, stats) cmd.FailOnError(err, "Failed to create Publisher client") cas, err := rpc.NewAmqpRPCServer(amqpConf, c.CA.MaxConcurrentRPCServerRequests, stats) cmd.FailOnError(err, "Unable to create CA RPC server") rpc.NewCertificateAuthorityServer(cas, cai) err = cas.Start(amqpConf) cmd.FailOnError(err, "Unable to run CA RPC server") } app.Run() }
func newChecker(saDbMap *gorp.DbMap, paDbMap *gorp.DbMap, clk clock.Clock, enforceWhitelist bool) certChecker { pa, err := policy.NewPolicyAuthorityImpl(paDbMap, enforceWhitelist) cmd.FailOnError(err, "Failed to create PA") c := certChecker{ pa: pa, dbMap: saDbMap, certs: make(chan core.Certificate, batchSize), clock: clk, } c.issuedReport.Entries = make(map[string]reportEntry) return c }
func main() { app := cmd.NewAppShell("boulder-ca", "Handles issuance operations") app.Action = func(c cmd.Config, stats statsd.Statter, auditlogger *blog.AuditLogger) { // Validate PA config and set defaults if needed cmd.FailOnError(c.PA.CheckChallenges(), "Invalid PA configuration") c.PA.SetDefaultChallengesIfEmpty() // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.CA.DebugAddr) paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist, c.PA.Challenges) cmd.FailOnError(err, "Couldn't create PA") cai, err := ca.NewCertificateAuthorityImpl(c.CA, clock.Default(), stats, c.Common.IssuerCert) cmd.FailOnError(err, "Failed to create CA impl") cai.PA = pa go cmd.ProfileCmd("CA", stats) saRPC, err := rpc.NewAmqpRPCClient("CA->SA", c.AMQP.SA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Failed to create SA client") pubRPC, err := rpc.NewAmqpRPCClient("CA->Publisher", c.AMQP.Publisher.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") pubc, err := rpc.NewPublisherClient(pubRPC) cmd.FailOnError(err, "Failed to create Publisher client") cai.Publisher = &pubc cai.SA = &sac cas, err := rpc.NewAmqpRPCServer(c.AMQP.CA.Server, c.CA.MaxConcurrentRPCServerRequests, c) cmd.FailOnError(err, "Unable to create CA RPC server") rpc.NewCertificateAuthorityServer(cas, cai) err = cas.Start(c) cmd.FailOnError(err, "Unable to run CA RPC server") } app.Run() }
func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationAuthority, *sa.SQLStorageAuthority, core.RegistrationAuthority) { err := json.Unmarshal(AccountKeyJSON, &AccountKey) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey) test.AssertNotError(t, err, "Failed to unmarshal private JWK") sa, err := sa.NewSQLStorageAuthority("sqlite3", ":memory:") test.AssertNotError(t, err, "Failed to create SA") sa.InitTables() va := &DummyValidationAuthority{} // PEM files in certificate-authority_test.go caKeyPEM, _ := pem.Decode([]byte(CA_KEY_PEM)) caKey, _ := x509.ParsePKCS1PrivateKey(caKeyPEM.Bytes) caCertPEM, _ := pem.Decode([]byte(CA_CERT_PEM)) caCert, _ := x509.ParseCertificate(caCertPEM.Bytes) signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, nil) pa := policy.NewPolicyAuthorityImpl() cadb := &MockCADatabase{} ca := ca.CertificateAuthorityImpl{Signer: signer, SA: sa, PA: pa, DB: cadb, ValidityPeriod: time.Hour * 8760, NotAfter: time.Now().Add(time.Hour * 8761)} csrDER, _ := hex.DecodeString(CSR_HEX) ExampleCSR, _ = x509.ParseCertificateRequest(csrDER) // This registration implicitly gets ID = 1 sa.NewRegistration(core.Registration{Key: AccountKey}) ra := NewRegistrationAuthorityImpl() ra.SA = sa ra.VA = va ra.CA = &ca ra.PA = pa return &ca, va, sa, &ra }
func main() { app := cmd.NewAppShell("boulder-ra", "Handles service orchestration") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.RA.DebugAddr) paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist) cmd.FailOnError(err, "Couldn't create PA") rai := ra.NewRegistrationAuthorityImpl(clock.Default(), auditlogger) rai.AuthzBase = c.Common.BaseURL + wfe.AuthzPath rai.MaxKeySize = c.Common.MaxKeySize rai.PA = pa raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse RA DNS timeout") rai.DNSResolver = core.NewDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) go cmd.ProfileCmd("RA", stats) connectionHandler := func(srv *rpc.AmqpRPCServer) { vaRPC, err := rpc.NewAmqpRPCClient("RA->VA", c.AMQP.VA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") caRPC, err := rpc.NewAmqpRPCClient("RA->CA", c.AMQP.CA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") saRPC, err := rpc.NewAmqpRPCClient("RA->SA", c.AMQP.SA.Server, srv.Channel) cmd.FailOnError(err, "Unable to create RPC client") vac, err := rpc.NewValidationAuthorityClient(vaRPC) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(caRPC) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Unable to create SA client") rai.VA = &vac rai.CA = &cac rai.SA = &sac } ras, err := rpc.NewAmqpRPCServer(c.AMQP.RA.Server, connectionHandler) cmd.FailOnError(err, "Unable to create RA RPC server") rpc.NewRegistrationAuthorityServer(ras, &rai) auditlogger.Info(app.VersionString()) err = ras.Start(c) cmd.FailOnError(err, "Unable to run RA RPC server") } app.Run() }
func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, clock.FakeClock, func()) { err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey) test.AssertNotError(t, err, "Failed to unmarshal private JWK") err = json.Unmarshal(ShortKeyJSON, &ShortKey) test.AssertNotError(t, err, "Failed to unmarshal JWK") fc := clock.NewFake() dbMap, err := sa.NewDbMap(vars.DBConnSA) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } ssa, err := sa.NewSQLStorageAuthority(dbMap, fc) if err != nil { t.Fatalf("Failed to create SA: %s", err) } saDBCleanUp := test.ResetSATestDatabase(t) va := &DummyValidationAuthority{} // PEM files in certificate-authority_test.go caKeyPEM, _ := pem.Decode([]byte(CAkeyPEM)) caKey, _ := x509.ParsePKCS1PrivateKey(caKeyPEM.Bytes) caCertPEM, _ := pem.Decode([]byte(CAcertPEM)) caCert, _ := x509.ParseCertificate(caCertPEM.Bytes) basicPolicy := &cfsslConfig.Signing{ Default: &cfsslConfig.SigningProfile{ Usage: []string{"server auth", "client auth"}, Expiry: 1 * time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKey: true, PublicKeyAlgorithm: true, SignatureAlgorithm: true, DNSNames: true, }, }, } signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, basicPolicy) ocspSigner, _ := ocsp.NewSigner(caCert, caCert, caKey, time.Hour) paDbMap, err := sa.NewDbMap(vars.DBConnPolicy) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } policyDBCleanUp := test.ResetPolicyTestDatabase(t) pa, err := policy.NewPolicyAuthorityImpl(paDbMap, false, SupportedChallenges) test.AssertNotError(t, err, "Couldn't create PA") ca := ca.CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, SA: ssa, PA: pa, ValidityPeriod: time.Hour * 2190, NotAfter: time.Now().Add(time.Hour * 8761), Clk: fc, Publisher: &mocks.Publisher{}, } cleanUp := func() { saDBCleanUp() policyDBCleanUp() } csrDER, _ := hex.DecodeString(CSRhex) ExampleCSR, _ = x509.ParseCertificateRequest(csrDER) Registration, _ = ssa.NewRegistration(core.Registration{ Key: AccountKeyA, InitialIP: net.ParseIP("3.2.3.3"), }) stats, _ := statsd.NewNoopClient() ra := NewRegistrationAuthorityImpl(fc, blog.GetAuditLogger(), stats, &DomainCheck{va}, cmd.RateLimitConfig{ TotalCertificates: cmd.RateLimitPolicy{ Threshold: 100, Window: cmd.ConfigDuration{Duration: 24 * 90 * time.Hour}, }, }, 1) ra.SA = ssa ra.VA = va ra.CA = &ca ra.PA = pa ra.DNSResolver = &mocks.DNSResolver{} AuthzInitial.RegistrationID = Registration.ID challenges, combinations, err := pa.ChallengesFor(AuthzInitial.Identifier, &Registration.Key) AuthzInitial.Challenges = challenges AuthzInitial.Combinations = combinations AuthzFinal = AuthzInitial AuthzFinal.Status = "valid" exp := time.Now().Add(365 * 24 * time.Hour) AuthzFinal.Expires = &exp AuthzFinal.Challenges[0].Status = "valid" return va, ssa, ra, fc, cleanUp }
func setup(t *testing.T) *testCtx { // Create an SA dbMap, err := sa.NewDbMap(saDBConnStr) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } fc := clock.NewFake() fc.Add(1 * time.Hour) ssa, err := sa.NewSQLStorageAuthority(dbMap, fc) if err != nil { t.Fatalf("Failed to create SA: %s", err) } saDBCleanUp := test.ResetTestDatabase(t, dbMap.Db) cadb, caDBCleanUp := caDBImpl(t) paDbMap, err := sa.NewDbMap(paDBConnStr) test.AssertNotError(t, err, "Could not construct dbMap") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, false) test.AssertNotError(t, err, "Couldn't create PADB") paDBCleanUp := test.ResetTestDatabase(t, paDbMap.Db) cleanUp := func() { saDBCleanUp() caDBCleanUp() paDBCleanUp() } // TODO(jmhodges): use of this pkg here is a bug caused by using a real SA reg := satest.CreateWorkingRegistration(t, ssa) // Create a CA caConfig := cmd.CAConfig{ Profile: profileName, SerialPrefix: 17, Key: cmd.KeyConfig{ File: caKeyFile, }, Expiry: "8760h", LifespanOCSP: "45m", MaxNames: 2, CFSSL: cfsslConfig.Config{ Signing: &cfsslConfig.Signing{ Profiles: map[string]*cfsslConfig.SigningProfile{ profileName: &cfsslConfig.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: []cfsslConfig.CertificatePolicy{ cfsslConfig.CertificatePolicy{ ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}), }, }, ExpiryString: "8760h", Backdate: time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKeyAlgorithm: true, PublicKey: true, SignatureAlgorithm: true, }, }, }, Default: &cfsslConfig.SigningProfile{ ExpiryString: "8760h", }, }, OCSP: &ocspConfig.Config{ CACertFile: caCertFile, ResponderCertFile: caCertFile, KeyFile: caKeyFile, }, }, } return &testCtx{cadb, ssa, caConfig, reg, pa, fc, cleanUp} }
// NewCertificateAuthorityImpl creates a CA that talks to a remote CFSSL // instance. (To use a local signer, simply instantiate CertificateAuthorityImpl // directly.) Communications with the CA are authenticated with MACs, // using CFSSL's authenticated signature scheme. A CA created in this way // issues for a single profile on the remote signer, which is indicated // by name in this constructor. func NewCertificateAuthorityImpl(cadb core.CertificateAuthorityDatabase, config Config) (*CertificateAuthorityImpl, error) { var ca *CertificateAuthorityImpl var err error logger := blog.GetAuditLogger() logger.Notice("Certificate Authority Starting") if config.SerialPrefix <= 0 || config.SerialPrefix >= 256 { err = errors.New("Must have a positive non-zero serial prefix less than 256 for CA.") return nil, err } // Create the remote signer localProfile := cfsslConfig.SigningProfile{ Expiry: time.Hour, // BOGUS: Required by CFSSL, but not used RemoteName: config.Server, // BOGUS: Only used as a flag by CFSSL RemoteServer: config.Server, UseSerialSeq: true, } localProfile.Provider, err = auth.New(config.AuthKey, nil) if err != nil { return nil, err } signer, err := remote.NewSigner(&cfsslConfig.Signing{Default: &localProfile}) if err != nil { return nil, err } issuer, err := loadIssuer(config.IssuerCert) if err != nil { return nil, err } // In test mode, load a private key from a file. // TODO: This should rely on the CFSSL config, to make it easy to use a key // from a file vs an HSM. https://github.com/letsencrypt/boulder/issues/163 issuerKey, err := loadIssuerKey(config.IssuerKey) if err != nil { return nil, err } // Set up our OCSP signer. Note this calls for both the issuer cert and the // OCSP signing cert, which are the same in our case. ocspSigner, err := ocsp.NewSigner(issuer, issuer, issuerKey, time.Hour*24*4) if err != nil { return nil, err } pa := policy.NewPolicyAuthorityImpl() ca = &CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, profile: config.Profile, PA: pa, DB: cadb, Prefix: config.SerialPrefix, log: logger, NotAfter: issuer.NotAfter, } ca.ValidityPeriod, err = time.ParseDuration(config.Expiry) if err != nil { return nil, err } return ca, nil }
func initAuthorities(t *testing.T) (*DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, clock.FakeClock, func()) { err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey) test.AssertNotError(t, err, "Failed to unmarshal private JWK") err = json.Unmarshal(ShortKeyJSON, &ShortKey) test.AssertNotError(t, err, "Failed to unmarshall JWK") fc := clock.NewFake() dbMap, err := sa.NewDbMap(saDBConnStr) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } ssa, err := sa.NewSQLStorageAuthority(dbMap, fc) if err != nil { t.Fatalf("Failed to create SA: %s", err) } saDBCleanUp := test.ResetTestDatabase(t, dbMap.Db) va := &DummyValidationAuthority{} // PEM files in certificate-authority_test.go caKeyPEM, _ := pem.Decode([]byte(CAkeyPEM)) caKey, _ := x509.ParsePKCS1PrivateKey(caKeyPEM.Bytes) caCertPEM, _ := pem.Decode([]byte(CAcertPEM)) caCert, _ := x509.ParseCertificate(caCertPEM.Bytes) basicPolicy := &cfsslConfig.Signing{ Default: &cfsslConfig.SigningProfile{ Usage: []string{"server auth", "client auth"}, Expiry: 1 * time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKey: true, PublicKeyAlgorithm: true, SignatureAlgorithm: true, DNSNames: true, }, }, } signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, basicPolicy) ocspSigner, _ := ocsp.NewSigner(caCert, caCert, caKey, time.Hour) paDbMap, err := sa.NewDbMap(paDBConnStr) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } policyDBCleanUp := test.ResetTestDatabase(t, paDbMap.Db) pa, err := policy.NewPolicyAuthorityImpl(paDbMap, false) test.AssertNotError(t, err, "Couldn't create PA") cadb, caDBCleanUp := caDBImpl(t) ca := ca.CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, SA: ssa, PA: pa, DB: cadb, ValidityPeriod: time.Hour * 2190, NotAfter: time.Now().Add(time.Hour * 8761), Clk: fc, } cleanUp := func() { saDBCleanUp() caDBCleanUp() policyDBCleanUp() } csrDER, _ := hex.DecodeString(CSRhex) ExampleCSR, _ = x509.ParseCertificateRequest(csrDER) Registration, _ = ssa.NewRegistration(core.Registration{Key: AccountKeyA}) ra := NewRegistrationAuthorityImpl(fc, blog.GetAuditLogger()) ra.SA = ssa ra.VA = va ra.CA = &ca ra.PA = pa ra.DNSResolver = &mocks.MockDNS{} AuthzInitial.RegistrationID = Registration.ID AuthzUpdated = AuthzInitial AuthzFinal = AuthzUpdated AuthzFinal.Status = "valid" exp := time.Now().Add(365 * 24 * time.Hour) AuthzFinal.Expires = &exp AuthzFinal.Challenges[0].Status = "valid" return va, ssa, &ra, fc, cleanUp }
func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationAuthority, *sa.SQLStorageAuthority, core.RegistrationAuthority) { err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey) test.AssertNotError(t, err, "Failed to unmarshal private JWK") err = json.Unmarshal(ShortKeyJSON, &ShortKey) test.AssertNotError(t, err, "Failed to unmarshall JWK") sa, err := sa.NewSQLStorageAuthority("sqlite3", ":memory:") test.AssertNotError(t, err, "Failed to create SA") sa.CreateTablesIfNotExists() va := &DummyValidationAuthority{} // PEM files in certificate-authority_test.go caKeyPEM, _ := pem.Decode([]byte(CAkeyPEM)) caKey, _ := x509.ParsePKCS1PrivateKey(caKeyPEM.Bytes) caCertPEM, _ := pem.Decode([]byte(CAcertPEM)) caCert, _ := x509.ParseCertificate(caCertPEM.Bytes) basicPolicy := &cfsslConfig.Signing{ Default: &cfsslConfig.SigningProfile{ Usage: []string{"server auth", "client auth"}, Expiry: 1 * time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKey: true, PublicKeyAlgorithm: true, SignatureAlgorithm: true, DNSNames: true, }, }, } signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, basicPolicy) ocspSigner, _ := ocsp.NewSigner(caCert, caCert, caKey, time.Hour) pa := policy.NewPolicyAuthorityImpl() cadb, _ := test.NewMockCertificateAuthorityDatabase() ca := ca.CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, SA: sa, PA: pa, DB: cadb, ValidityPeriod: time.Hour * 2190, NotAfter: time.Now().Add(time.Hour * 8761), MaxKeySize: 4096, } csrDER, _ := hex.DecodeString(CSRhex) ExampleCSR, _ = x509.ParseCertificateRequest(csrDER) // This registration implicitly gets ID = 1 Registration, _ = sa.NewRegistration(core.Registration{Key: AccountKeyA}) ra := NewRegistrationAuthorityImpl() ra.SA = sa ra.VA = va ra.CA = &ca ra.PA = pa ra.AuthzBase = "http://acme.invalid/authz/" ra.MaxKeySize = 4096 AuthzInitial.RegistrationID = Registration.ID AuthzUpdated = AuthzInitial AuthzUpdated.Challenges[0].Path = "Hf5GrX4Q7EBax9hc2jJnfw" AuthzFinal = AuthzUpdated AuthzFinal.Status = "valid" exp := time.Now().Add(365 * 24 * time.Hour) AuthzFinal.Expires = &exp AuthzFinal.Challenges[0].Status = "valid" return &ca, va, sa, &ra }
// NewCertificateAuthorityImpl creates a CA that talks to a remote CFSSL // instance. (To use a local signer, simply instantiate CertificateAuthorityImpl // directly.) Communications with the CA are authenticated with MACs, // using CFSSL's authenticated signature scheme. A CA created in this way // issues for a single profile on the remote signer, which is indicated // by name in this constructor. func NewCertificateAuthorityImpl(cadb core.CertificateAuthorityDatabase, config Config, issuerCert string) (*CertificateAuthorityImpl, error) { var ca *CertificateAuthorityImpl var err error logger := blog.GetAuditLogger() logger.Notice("Certificate Authority Starting") if config.SerialPrefix <= 0 || config.SerialPrefix >= 256 { err = errors.New("Must have a positive non-zero serial prefix less than 256 for CA.") return nil, err } // CFSSL requires processing JSON configs through its own LoadConfig, so we // serialize and then deserialize. cfsslJSON, err := json.Marshal(config.CFSSL) if err != nil { return nil, err } cfsslConfigObj, err := cfsslConfig.LoadConfig(cfsslJSON) if err != nil { return nil, err } // Load the private key, which can be a file or a PKCS#11 key. priv, err := loadKey(config.Key) if err != nil { return nil, err } issuer, err := loadIssuer(issuerCert) if err != nil { return nil, err } signer, err := local.NewSigner(priv, issuer, x509.SHA256WithRSA, cfsslConfigObj.Signing) if err != nil { return nil, err } if config.LifespanOCSP == "" { return nil, errors.New("Config must specify an OCSP lifespan period.") } lifespanOCSP, err := time.ParseDuration(config.LifespanOCSP) if err != nil { return nil, err } // Set up our OCSP signer. Note this calls for both the issuer cert and the // OCSP signing cert, which are the same in our case. ocspSigner, err := ocsp.NewSigner(issuer, issuer, priv, lifespanOCSP) if err != nil { return nil, err } pa := policy.NewPolicyAuthorityImpl() ca = &CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, profile: config.Profile, PA: pa, DB: cadb, Prefix: config.SerialPrefix, log: logger, NotAfter: issuer.NotAfter, } if config.Expiry == "" { return nil, errors.New("Config must specify an expiry period.") } ca.ValidityPeriod, err = time.ParseDuration(config.Expiry) if err != nil { return nil, err } ca.MaxNames = config.MaxNames return ca, nil }
func setup(t *testing.T) *testCtx { // Create an SA dbMap, err := sa.NewDbMap(vars.DBConnSA) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } fc := clock.NewFake() fc.Add(1 * time.Hour) ssa, err := sa.NewSQLStorageAuthority(dbMap, fc) if err != nil { t.Fatalf("Failed to create SA: %s", err) } saDBCleanUp := test.ResetSATestDatabase(t) paDbMap, err := sa.NewDbMap(vars.DBConnPolicy) test.AssertNotError(t, err, "Could not construct dbMap") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, false, nil) test.AssertNotError(t, err, "Couldn't create PADB") paDBCleanUp := test.ResetPolicyTestDatabase(t) cleanUp := func() { saDBCleanUp() paDBCleanUp() } // TODO(jmhodges): use of this pkg here is a bug caused by using a real SA reg := satest.CreateWorkingRegistration(t, ssa) // Create a CA caConfig := cmd.CAConfig{ RSAProfile: rsaProfileName, ECDSAProfile: ecdsaProfileName, SerialPrefix: 17, Expiry: "8760h", LifespanOCSP: "45m", MaxNames: 2, HSMFaultTimeout: cmd.ConfigDuration{Duration: 60 * time.Second}, CFSSL: cfsslConfig.Config{ Signing: &cfsslConfig.Signing{ Profiles: map[string]*cfsslConfig.SigningProfile{ rsaProfileName: &cfsslConfig.SigningProfile{ Usage: []string{"digital signature", "key encipherment", "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: []cfsslConfig.CertificatePolicy{ cfsslConfig.CertificatePolicy{ ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}), }, }, ExpiryString: "8760h", Backdate: time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKeyAlgorithm: true, PublicKey: true, SignatureAlgorithm: true, }, ClientProvidesSerialNumbers: true, }, ecdsaProfileName: &cfsslConfig.SigningProfile{ Usage: []string{"digital signature", "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: []cfsslConfig.CertificatePolicy{ cfsslConfig.CertificatePolicy{ ID: cfsslConfig.OID(asn1.ObjectIdentifier{2, 23, 140, 1, 2, 1}), }, }, ExpiryString: "8760h", Backdate: time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKeyAlgorithm: true, PublicKey: true, SignatureAlgorithm: true, }, ClientProvidesSerialNumbers: true, }, }, Default: &cfsslConfig.SigningProfile{ ExpiryString: "8760h", }, }, OCSP: &ocspConfig.Config{ CACertFile: caCertFile, ResponderCertFile: caCertFile, KeyFile: caKeyFile, }, }, } stats := mocks.NewStatter() keyPolicy := core.KeyPolicy{ AllowRSA: true, AllowECDSANISTP256: true, AllowECDSANISTP384: true, } return &testCtx{ ssa, caConfig, reg, pa, keyPolicy, fc, &stats, cleanUp, } }
func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationAuthority, *sa.SQLStorageAuthority, *RegistrationAuthorityImpl, func()) { err := json.Unmarshal(AccountKeyJSONA, &AccountKeyA) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONB, &AccountKeyB) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountKeyJSONC, &AccountKeyC) test.AssertNotError(t, err, "Failed to unmarshal public JWK") err = json.Unmarshal(AccountPrivateKeyJSON, &AccountPrivateKey) test.AssertNotError(t, err, "Failed to unmarshal private JWK") err = json.Unmarshal(ShortKeyJSON, &ShortKey) test.AssertNotError(t, err, "Failed to unmarshall JWK") dbMap, err := sa.NewDbMap(dbConnStr) if err != nil { t.Fatalf("Failed to create dbMap: %s", err) } ssa, err := sa.NewSQLStorageAuthority(dbMap) if err != nil { t.Fatalf("Failed to create SA: %s", err) } err = ssa.CreateTablesIfNotExists() if err != nil { t.Fatalf("Failed to create SA tables: %s", err) } if err = dbMap.TruncateTables(); err != nil { t.Fatalf("Failed to truncate SA tables: %s", err) } va := &DummyValidationAuthority{} // PEM files in certificate-authority_test.go caKeyPEM, _ := pem.Decode([]byte(CAkeyPEM)) caKey, _ := x509.ParsePKCS1PrivateKey(caKeyPEM.Bytes) caCertPEM, _ := pem.Decode([]byte(CAcertPEM)) caCert, _ := x509.ParseCertificate(caCertPEM.Bytes) basicPolicy := &cfsslConfig.Signing{ Default: &cfsslConfig.SigningProfile{ Usage: []string{"server auth", "client auth"}, Expiry: 1 * time.Hour, CSRWhitelist: &cfsslConfig.CSRWhitelist{ PublicKey: true, PublicKeyAlgorithm: true, SignatureAlgorithm: true, DNSNames: true, }, }, } signer, _ := local.NewSigner(caKey, caCert, x509.SHA256WithRSA, basicPolicy) ocspSigner, _ := ocsp.NewSigner(caCert, caCert, caKey, time.Hour) pa := policy.NewPolicyAuthorityImpl() cadb, caDBCleanUp := caDBImpl(t) ca := ca.CertificateAuthorityImpl{ Signer: signer, OCSPSigner: ocspSigner, SA: ssa, PA: pa, DB: cadb, ValidityPeriod: time.Hour * 2190, NotAfter: time.Now().Add(time.Hour * 8761), MaxKeySize: 4096, } cleanUp := func() { if err = dbMap.TruncateTables(); err != nil { t.Fatalf("Failed to truncate tables after the test: %s", err) } dbMap.Db.Close() caDBCleanUp() } csrDER, _ := hex.DecodeString(CSRhex) ExampleCSR, _ = x509.ParseCertificateRequest(csrDER) // This registration implicitly gets ID = 1 Registration, _ = ssa.NewRegistration(core.Registration{Key: AccountKeyA}) ra := NewRegistrationAuthorityImpl() ra.SA = ssa ra.VA = va ra.CA = &ca ra.PA = pa ra.AuthzBase = "http://acme.invalid/authz/" ra.MaxKeySize = 4096 ra.DNSResolver = &mocks.MockDNS{} AuthzInitial.RegistrationID = Registration.ID AuthzUpdated = AuthzInitial AuthzFinal = AuthzUpdated AuthzFinal.Status = "valid" exp := time.Now().Add(365 * 24 * time.Hour) AuthzFinal.Expires = &exp AuthzFinal.Challenges[0].Status = "valid" return &ca, va, ssa, &ra, cleanUp }
func main() { app := cmd.NewAppShell("boulder-ra", "Handles service orchestration") app.Action = func(c cmd.Config) { stats, err := statsd.NewClient(c.Statsd.Server, c.Statsd.Prefix) cmd.FailOnError(err, "Couldn't connect to statsd") // Set up logging auditlogger, err := blog.Dial(c.Syslog.Network, c.Syslog.Server, c.Syslog.Tag, stats) cmd.FailOnError(err, "Could not connect to Syslog") auditlogger.Info(app.VersionString()) // AUDIT[ Error Conditions ] 9cc4d537-8534-4970-8665-4b382abe82f3 defer auditlogger.AuditPanic() blog.SetAuditLogger(auditlogger) go cmd.DebugServer(c.RA.DebugAddr) paDbMap, err := sa.NewDbMap(c.PA.DBConnect) cmd.FailOnError(err, "Couldn't connect to policy database") pa, err := policy.NewPolicyAuthorityImpl(paDbMap, c.PA.EnforcePolicyWhitelist) cmd.FailOnError(err, "Couldn't create PA") rateLimitPolicies, err := cmd.LoadRateLimitPolicies(c.RA.RateLimitPoliciesFilename) cmd.FailOnError(err, "Couldn't load rate limit policies file") go cmd.ProfileCmd("RA", stats) vaRPC, err := rpc.NewAmqpRPCClient("RA->VA", c.AMQP.VA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") caRPC, err := rpc.NewAmqpRPCClient("RA->CA", c.AMQP.CA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") saRPC, err := rpc.NewAmqpRPCClient("RA->SA", c.AMQP.SA.Server, c, stats) cmd.FailOnError(err, "Unable to create RPC client") vac, err := rpc.NewValidationAuthorityClient(vaRPC) cmd.FailOnError(err, "Unable to create VA client") cac, err := rpc.NewCertificateAuthorityClient(caRPC) cmd.FailOnError(err, "Unable to create CA client") sac, err := rpc.NewStorageAuthorityClient(saRPC) cmd.FailOnError(err, "Unable to create SA client") var dc *ra.DomainCheck if c.RA.UseIsSafeDomain { dc = &ra.DomainCheck{&vac} } rai := ra.NewRegistrationAuthorityImpl(clock.Default(), auditlogger, stats, dc, rateLimitPolicies, c.RA.MaxContactsPerRegistration) rai.PA = pa raDNSTimeout, err := time.ParseDuration(c.Common.DNSTimeout) cmd.FailOnError(err, "Couldn't parse RA DNS timeout") if !c.Common.DNSAllowLoopbackAddresses { rai.DNSResolver = core.NewDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) } else { rai.DNSResolver = core.NewTestDNSResolverImpl(raDNSTimeout, []string{c.Common.DNSResolver}) } rai.VA = &vac rai.CA = &cac rai.SA = &sac ras, err := rpc.NewAmqpRPCServer(c.AMQP.RA.Server, c.RA.MaxConcurrentRPCServerRequests, c) cmd.FailOnError(err, "Unable to create RA RPC server") rpc.NewRegistrationAuthorityServer(ras, rai) err = ras.Start(c) cmd.FailOnError(err, "Unable to run RA RPC server") } app.Run() }