diff --git a/ca/certificate-authority_test.go b/ca/certificate-authority_test.go index f2cfa07c6..e8f50e10d 100644 --- a/ca/certificate-authority_test.go +++ b/ca/certificate-authority_test.go @@ -427,6 +427,14 @@ func TestIssueCertificate(t *testing.T) { test.Assert(t, certStatus.Status == core.OCSPStatusGood, "Certificate status was not good") test.Assert(t, certStatus.SubscriberApproved == false, "Subscriber shouldn't have approved cert yet.") } +} + + +func TestRejectNoName(t *testing.T) { + cadb, storageAuthority, caConfig := setup(t) + ca, err := NewCertificateAuthorityImpl(cadb, caConfig) + test.AssertNotError(t, err, "Failed to create CA") + ca.SA = storageAuthority // Test that the CA rejects CSRs with no names csrDER, _ := hex.DecodeString(NO_NAME_CSR_HEX) @@ -436,3 +444,19 @@ func TestIssueCertificate(t *testing.T) { t.Errorf("CA improperly agreed to create a certificate with no name") } } + +func TestShortKey(t *testing.T) { + cadb, storageAuthority, caConfig := setup(t) + ca, err := NewCertificateAuthorityImpl(cadb, caConfig) + ca.SA = storageAuthority + + csrDER, err := ioutil.ReadFile("shortkey-csr.der") + if err != nil { + t.Errorf("Failed to read shortkey-csr.der") + } + csr, _ := x509.ParseCertificateRequest(csrDER) + _, err = ca.IssueCertificate(*csr) + if err == nil { + t.Errorf("CA improperly created a certificate with short key.") + } +} diff --git a/ca/shortkey-csr.der b/ca/shortkey-csr.der new file mode 100644 index 000000000..aa0ef8d7e Binary files /dev/null and b/ca/shortkey-csr.der differ diff --git a/core/util.go b/core/util.go index 51ec48a0f..e3f23e791 100644 --- a/core/util.go +++ b/core/util.go @@ -97,6 +97,11 @@ func Fingerprint256(data []byte) string { // URLs that automatically marshal/unmarshal to JSON strings type AcmeURL url.URL +func (u AcmeURL) String() string { + url := url.URL(u) + return url.String() +} + func (u AcmeURL) PathSegments() (segments []string) { segments = strings.Split(u.Path, "/") if len(segments) > 0 && len(segments[0]) == 0 { diff --git a/ra/registration-authority_test.go b/ra/registration-authority_test.go index 0c66bbb36..1d89687d8 100644 --- a/ra/registration-authority_test.go +++ b/ra/registration-authority_test.go @@ -63,13 +63,21 @@ func (cadb *MockCADatabase) IncrementAndGetSerial() (int, error) { var ( // These values we simulate from the client AccountKeyJSON = []byte(`{ - "kty": "EC", - "crv": "P-521", - "x": "AHKZLLOsCOzz5cY97ewNUajB957y-C-U88c3v13nmGZx6sYl_oJXu9A5RkTKqjqvjyekWF-7ytDyRXYgCF5cj0Kt", - "y": "AdymlHvOiLxXkEhayXQnNCvDX4h9htZaCJN34kfmC6pV5OhQHiraVySsUdaQkAgDPrwQrJmbnX9cwlGfP-HqHZR1" - }`) + "e": "AQAB", + "kty": "RSA", + "n": "tSwgy3ORGvc7YJI9B2qqkelZRUC6F1S5NwXFvM4w5-M0TsxbFsH5UH6adigV0jzsDJ5imAechcSoOhAh9POceCbPN1sTNwLpNbOLiQQ7RD5mY_pSUHWXNmS9R4NZ3t2fQAzPeW7jOfF0LKuJRGkekx6tXP1uSnNibgpJULNc4208dgBaCHo3mvaE2HV2GmVl1yxwWX5QZZkGQGjNDZYnjFfa2DKVvFs0QbAk21ROm594kAxlRlMMrvqlf24Eq4ERO0ptzpZgm_3j_e4hGRD39gJS7kAzK-j2cacFQ5Qi2Y6wZI2p-FCq_wiYsfEAIkATPBiLKl_6d_Jfcvs_impcXQ" + }`) + AccountKey = jose.JsonWebKey{} + ShortKeyJSON = []byte(`{ + "e": "AQAB", + "kty": "RSA", + "n": "tSwgy3ORGvc7YJI9B2qqkelZRUC6F1S5NwXFvM4w5-M0TsxbFsH5UH6adigV0jzsDJ5imAechcSoOhAh9POceCbPN1sTNwLpNbOLiQQ7RD5mY_" + }`) + + ShortKey = jose.JsonWebKey{} + AuthzRequest = core.Authorization{ Identifier: core.AcmeIdentifier{ Type: core.IdentifierDNS, @@ -96,6 +104,9 @@ func initAuthorities(t *testing.T) (core.CertificateAuthority, *DummyValidationA err := json.Unmarshal(AccountKeyJSON, &AccountKey) test.AssertNotError(t, err, "Failed to unmarshall 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.InitTables() @@ -131,6 +142,60 @@ func assertAuthzEqual(t *testing.T, a1, a2 core.Authorization) { // Not testing: Contact, Challenges } +func TestNewRegistration(t *testing.T) { + _, _, sa, ra := initAuthorities(t) + mailto, _ := url.Parse("mailto:foo@bar.com") + input := core.Registration{ + Contact: []core.AcmeURL{core.AcmeURL(*mailto)}, + } + + result, err := ra.NewRegistration(input, AccountKey) + test.AssertNotError(t, err, "Could not create new registration") + + test.Assert(t, result.Key.Equals(AccountKey), "Key didn't match") + test.Assert(t, len(result.Contact) == 1, "Wrong number of contacts") + test.Assert(t, mailto.String() == result.Contact[0].String(), + "Contact didn't match") + test.Assert(t, result.Agreement == "", "Agreement didn't default empty") + test.Assert(t, result.RecoveryToken != "", "Recovery token not filled") + + reg, err := sa.GetRegistration(result.ID) + test.AssertNotError(t, err, "Failed to retrieve registration") + test.Assert(t, reg.Key.Equals(AccountKey), "Retrieved registration differed.") +} + +func TestNewRegistrationNoFieldOverwrite(t *testing.T) { + _, _, _, ra := initAuthorities(t) + mailto, _ := url.Parse("mailto:foo@bar.com") + input := core.Registration{ + ID: "hi", + Key: ShortKey, + RecoveryToken: "RecoverMe", + Contact: []core.AcmeURL{core.AcmeURL(*mailto)}, + Agreement: "I agreed", + } + + result, err := ra.NewRegistration(input, AccountKey) + test.AssertNotError(t, err, "Could not create new registration") + + test.Assert(t, result.ID != "hi", "ID shouldn't be overwritten") + test.Assert(t, !result.Key.Equals(ShortKey), "Key shouldn't be overwritten") + // TODO: Enable this test case once we validate terms agreement. + // test.Assert(t, result.Agreement != "I agreed", "Agreement shouldn't be overwritten with invalid URL") + test.Assert(t, result.RecoveryToken != "RecoverMe", "Recovery token shouldn't be overwritten") +} + +func TestNewRegistrationBadKey(t *testing.T) { + _, _, _, ra := initAuthorities(t) + mailto, _ := url.Parse("mailto:foo@bar.com") + input := core.Registration{ + Contact: []core.AcmeURL{core.AcmeURL(*mailto)}, + } + + _, err := ra.NewRegistration(input, ShortKey) + test.AssertError(t, err, "Should have rejected authorization with short key") +} + func TestNewAuthorization(t *testing.T) { _, _, sa, ra := initAuthorities(t)