OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2011 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 20 matching lines...) Expand all Loading... | |
31 "-----END CERTIFICATE-----\n"; | 31 "-----END CERTIFICATE-----\n"; |
32 | 32 |
33 const unsigned char kTestCertSha1[] = {0xA6, 0xC8, 0x59, 0xEA, | 33 const unsigned char kTestCertSha1[] = {0xA6, 0xC8, 0x59, 0xEA, |
34 0xC3, 0x7E, 0x6D, 0x33, | 34 0xC3, 0x7E, 0x6D, 0x33, |
35 0xCF, 0xE2, 0x69, 0x9D, | 35 0xCF, 0xE2, 0x69, 0x9D, |
36 0x74, 0xE6, 0xF6, 0x8A, | 36 0x74, 0xE6, 0xF6, 0x8A, |
37 0x9E, 0x47, 0xA7, 0xCA}; | 37 0x9E, 0x47, 0xA7, 0xCA}; |
38 | 38 |
39 class SSLIdentityTest : public testing::Test { | 39 class SSLIdentityTest : public testing::Test { |
40 public: | 40 public: |
41 SSLIdentityTest() : | 41 SSLIdentityTest() |
42 identity1_(), identity2_() { | 42 : identity_rsa1_(), |
juberti1
2015/07/21 22:54:13
These don't need to be initialized.
torbjorng (webrtc)
2015/08/17 12:12:45
Done.
| |
43 } | 43 identity_rsa2_(), |
44 identity_ecdsa1_(), | |
45 identity_ecdsa2_() {} | |
44 | 46 |
45 ~SSLIdentityTest() { | 47 ~SSLIdentityTest() { |
46 } | 48 } |
47 | 49 |
48 virtual void SetUp() { | 50 virtual void SetUp() { |
49 identity1_.reset(SSLIdentity::Generate("test1")); | 51 identity_rsa1_.reset(SSLIdentity::Generate("test1", rtc::KT_RSA)); |
50 identity2_.reset(SSLIdentity::Generate("test2")); | 52 identity_rsa2_.reset(SSLIdentity::Generate("test2", rtc::KT_RSA)); |
53 identity_ecdsa1_.reset(SSLIdentity::Generate("test3", rtc::KT_ECDSA)); | |
54 identity_ecdsa2_.reset(SSLIdentity::Generate("test4", rtc::KT_ECDSA)); | |
51 | 55 |
52 ASSERT_TRUE(identity1_); | 56 ASSERT_TRUE(identity_rsa1_); |
53 ASSERT_TRUE(identity2_); | 57 ASSERT_TRUE(identity_rsa2_); |
58 ASSERT_TRUE(identity_ecdsa1_); | |
59 ASSERT_TRUE(identity_ecdsa2_); | |
54 | 60 |
55 test_cert_.reset( | 61 test_cert_.reset(rtc::SSLCertificate::FromPEMString(kTestCertificate)); |
56 rtc::SSLCertificate::FromPEMString(kTestCertificate)); | |
57 ASSERT_TRUE(test_cert_); | 62 ASSERT_TRUE(test_cert_); |
58 } | 63 } |
59 | 64 |
60 void TestGetSignatureDigestAlgorithm() { | 65 void TestGetSignatureDigestAlgorithm() { |
61 std::string digest_algorithm; | 66 std::string digest_algorithm; |
62 // Both NSSIdentity::Generate and OpenSSLIdentity::Generate are | 67 |
63 // hard-coded to generate RSA-SHA256 certificates. | 68 ASSERT_TRUE(identity_rsa1_->certificate().GetSignatureDigestAlgorithm( |
64 ASSERT_TRUE(identity1_->certificate().GetSignatureDigestAlgorithm( | |
65 &digest_algorithm)); | |
66 ASSERT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | |
67 ASSERT_TRUE(identity2_->certificate().GetSignatureDigestAlgorithm( | |
68 &digest_algorithm)); | 69 &digest_algorithm)); |
69 ASSERT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | 70 ASSERT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); |
70 | 71 |
72 ASSERT_TRUE(identity_rsa2_->certificate().GetSignatureDigestAlgorithm( | |
73 &digest_algorithm)); | |
74 ASSERT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | |
75 | |
76 ASSERT_TRUE(identity_ecdsa1_->certificate().GetSignatureDigestAlgorithm( | |
77 &digest_algorithm)); | |
78 ASSERT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | |
79 | |
80 ASSERT_TRUE(identity_ecdsa2_->certificate().GetSignatureDigestAlgorithm( | |
81 &digest_algorithm)); | |
82 ASSERT_EQ(rtc::DIGEST_SHA_256, digest_algorithm); | |
83 | |
71 // The test certificate has an MD5-based signature. | 84 // The test certificate has an MD5-based signature. |
72 ASSERT_TRUE(test_cert_->GetSignatureDigestAlgorithm(&digest_algorithm)); | 85 ASSERT_TRUE(test_cert_->GetSignatureDigestAlgorithm(&digest_algorithm)); |
73 ASSERT_EQ(rtc::DIGEST_MD5, digest_algorithm); | 86 ASSERT_EQ(rtc::DIGEST_MD5, digest_algorithm); |
74 } | 87 } |
75 | 88 |
76 void TestDigest(const std::string &algorithm, size_t expected_len, | 89 typedef unsigned char DigestType[64]; // 64 is the largest hash used here. |
juberti1
2015/07/21 22:54:13
You can use MessageDigest::kMaxSize instead of 64
torbjorng (webrtc)
2015/08/17 12:12:45
Done.
| |
77 const unsigned char *expected_digest = NULL) { | 90 |
78 unsigned char digest1[64]; | 91 void TestDigestHelper(DigestType digest, |
79 unsigned char digest1b[64]; | 92 const SSLIdentity* identity, |
80 unsigned char digest2[64]; | 93 const std::string& algorithm, |
81 size_t digest1_len; | 94 size_t expected_len) { |
82 size_t digest1b_len; | 95 DigestType digest1; |
83 size_t digest2_len; | 96 size_t digest_len; |
84 bool rv; | 97 bool rv; |
85 | 98 |
86 rv = identity1_->certificate().ComputeDigest(algorithm, | 99 memset(digest, 0, expected_len); |
87 digest1, sizeof(digest1), | 100 rv = identity->certificate().ComputeDigest(algorithm, digest, |
88 &digest1_len); | 101 sizeof(DigestType), &digest_len); |
89 EXPECT_TRUE(rv); | 102 EXPECT_TRUE(rv); |
90 EXPECT_EQ(expected_len, digest1_len); | 103 EXPECT_EQ(expected_len, digest_len); |
91 | 104 |
92 rv = identity1_->certificate().ComputeDigest(algorithm, | 105 // Repeat digest computation for the identity as a sanity check. |
93 digest1b, sizeof(digest1b), | 106 memset(digest1, 0xff, expected_len); |
94 &digest1b_len); | 107 rv = identity->certificate().ComputeDigest(algorithm, digest1, |
108 sizeof(DigestType), &digest_len); | |
95 EXPECT_TRUE(rv); | 109 EXPECT_TRUE(rv); |
96 EXPECT_EQ(expected_len, digest1b_len); | 110 EXPECT_EQ(expected_len, digest_len); |
97 EXPECT_EQ(0, memcmp(digest1, digest1b, expected_len)); | |
98 | 111 |
112 EXPECT_EQ(0, memcmp(digest, digest1, expected_len)); | |
113 } | |
99 | 114 |
100 rv = identity2_->certificate().ComputeDigest(algorithm, | 115 void TestDigest(const std::string& algorithm, size_t expected_len) { |
juberti1
2015/07/21 22:54:13
I would call this TestDigestForGeneratedCerts, or
torbjorng (webrtc)
2015/08/17 12:12:45
Done.
| |
101 digest2, sizeof(digest2), | 116 DigestType digest[4]; |
102 &digest2_len); | |
103 EXPECT_TRUE(rv); | |
104 EXPECT_EQ(expected_len, digest2_len); | |
105 EXPECT_NE(0, memcmp(digest1, digest2, expected_len)); | |
106 | 117 |
107 // If we have an expected hash for the test cert, check it. | 118 ASSERT_TRUE(expected_len <= 64); |
juberti1
2015/07/21 22:54:13
Suggest using <= sizeof(digest[0]), to avoid accid
torbjorng (webrtc)
2015/08/17 12:12:45
Done, except using sizeof(DigestType).
| |
108 if (expected_digest) { | |
109 unsigned char digest3[64]; | |
110 size_t digest3_len; | |
111 | 119 |
112 rv = test_cert_->ComputeDigest(algorithm, digest3, sizeof(digest3), | 120 TestDigestHelper(digest[0], identity_rsa1_.get(), algorithm, expected_len); |
113 &digest3_len); | 121 TestDigestHelper(digest[1], identity_rsa2_.get(), algorithm, expected_len); |
114 EXPECT_TRUE(rv); | 122 TestDigestHelper(digest[2], identity_ecdsa1_.get(), algorithm, |
115 EXPECT_EQ(expected_len, digest3_len); | 123 expected_len); |
116 EXPECT_EQ(0, memcmp(digest3, expected_digest, expected_len)); | 124 TestDigestHelper(digest[3], identity_ecdsa2_.get(), algorithm, |
125 expected_len); | |
126 | |
127 // Sanity check that all four digests are unique. This could theoretically | |
128 // fail, since SHA256 collisions have a non-zero probability. | |
129 for (int i = 0; i < 4; i++) { | |
130 for (int j = 0; j < 4; j++) { | |
131 if (i != j) | |
132 EXPECT_NE(0, memcmp(digest[i], digest[j], expected_len)); | |
133 } | |
117 } | 134 } |
118 } | 135 } |
119 | 136 |
137 void TestDigestExample(const std::string& algorithm, | |
juberti1
2015/07/21 22:54:13
I would call this TestDigestForFixedCert
torbjorng (webrtc)
2015/08/17 12:12:45
Done.
| |
138 size_t expected_len, | |
139 const unsigned char* expected_digest) { | |
140 bool rv; | |
141 DigestType digest; | |
142 size_t digest_len; | |
143 | |
144 ASSERT_TRUE(expected_len <= 64); | |
juberti1
2015/07/21 22:54:13
<= sizeof(digest)
torbjorng (webrtc)
2015/08/17 12:12:45
Done.
| |
145 | |
146 rv = test_cert_->ComputeDigest(algorithm, digest, sizeof(digest), | |
147 &digest_len); | |
148 EXPECT_TRUE(rv); | |
149 EXPECT_EQ(expected_len, digest_len); | |
150 EXPECT_EQ(0, memcmp(digest, expected_digest, expected_len)); | |
151 } | |
152 | |
120 private: | 153 private: |
121 rtc::scoped_ptr<SSLIdentity> identity1_; | 154 rtc::scoped_ptr<SSLIdentity> identity_rsa1_; |
122 rtc::scoped_ptr<SSLIdentity> identity2_; | 155 rtc::scoped_ptr<SSLIdentity> identity_rsa2_; |
156 rtc::scoped_ptr<SSLIdentity> identity_ecdsa1_; | |
157 rtc::scoped_ptr<SSLIdentity> identity_ecdsa2_; | |
123 rtc::scoped_ptr<rtc::SSLCertificate> test_cert_; | 158 rtc::scoped_ptr<rtc::SSLCertificate> test_cert_; |
124 }; | 159 }; |
125 | 160 |
126 TEST_F(SSLIdentityTest, DigestSHA1) { | 161 TEST_F(SSLIdentityTest, DigestSHA1) { |
127 TestDigest(rtc::DIGEST_SHA_1, 20, kTestCertSha1); | 162 TestDigestExample(rtc::DIGEST_SHA_1, 20, kTestCertSha1); |
juberti1
2015/07/21 22:54:13
I would have a call to both TestDigestForGenerated
torbjorng (webrtc)
2015/08/17 12:12:45
Using more hashes checking fixed data makes sense.
| |
128 } | 163 } |
129 | 164 |
130 // HASH_AlgSHA224 is not supported in the chromium linux build. | 165 // HASH_AlgSHA224 is not supported in the chromium linux build. |
131 #if SSL_USE_NSS | 166 #if SSL_USE_NSS |
132 TEST_F(SSLIdentityTest, DISABLED_DigestSHA224) { | 167 TEST_F(SSLIdentityTest, DISABLED_DigestSHA224) { |
133 #else | 168 #else |
134 TEST_F(SSLIdentityTest, DigestSHA224) { | 169 TEST_F(SSLIdentityTest, DigestSHA224) { |
135 #endif | 170 #endif |
136 TestDigest(rtc::DIGEST_SHA_224, 28); | 171 TestDigest(rtc::DIGEST_SHA_224, 28); |
137 } | 172 } |
138 | 173 |
139 TEST_F(SSLIdentityTest, DigestSHA256) { | 174 TEST_F(SSLIdentityTest, DigestSHA256) { |
140 TestDigest(rtc::DIGEST_SHA_256, 32); | 175 TestDigest(rtc::DIGEST_SHA_256, 32); |
141 } | 176 } |
142 | 177 |
143 TEST_F(SSLIdentityTest, DigestSHA384) { | 178 TEST_F(SSLIdentityTest, DigestSHA384) { |
144 TestDigest(rtc::DIGEST_SHA_384, 48); | 179 TestDigest(rtc::DIGEST_SHA_384, 48); |
145 } | 180 } |
146 | 181 |
147 TEST_F(SSLIdentityTest, DigestSHA512) { | 182 TEST_F(SSLIdentityTest, DigestSHA512) { |
148 TestDigest(rtc::DIGEST_SHA_512, 64); | 183 TestDigest(rtc::DIGEST_SHA_512, 64); |
149 } | 184 } |
150 | 185 |
151 TEST_F(SSLIdentityTest, FromPEMStrings) { | 186 TEST_F(SSLIdentityTest, FromPEMStringsRSA) { |
152 static const char kRSA_PRIVATE_KEY_PEM[] = | 187 static const char kRSA_PRIVATE_KEY_PEM[] = |
153 "-----BEGIN RSA PRIVATE KEY-----\n" | 188 "-----BEGIN RSA PRIVATE KEY-----\n" |
154 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n" | 189 "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMYRkbhmI7kVA/rM\n" |
155 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" | 190 "czsZ+6JDhDvnkF+vn6yCAGuRPV03zuRqZtDy4N4to7PZu9PjqrRl7nDMXrG3YG9y\n" |
156 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" | 191 "rlIAZ72KjcKKFAJxQyAKLCIdawKRyp8RdK3LEySWEZb0AV58IadqPZDTNHHRX8dz\n" |
157 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n" | 192 "5aTSMsbbkZ+C/OzTnbiMqLL/vg6jAgMBAAECgYAvgOs4FJcgvp+TuREx7YtiYVsH\n" |
158 "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n" | 193 "mwQPTum2z/8VzWGwR8BBHBvIpVe1MbD/Y4seyI2aco/7UaisatSgJhsU46/9Y4fq\n" |
159 "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n" | 194 "2TwXH9QANf4at4d9n/R6rzwpAJOpgwZgKvdQjkfrKTtgLV+/dawvpxUYkRH4JZM1\n" |
160 "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n" | 195 "CVGukMfKNrSVH4Ap4QJBAOJmGV1ASPnB4r4nc99at7JuIJmd7fmuVUwUgYi4XgaR\n" |
161 "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n" | 196 "WhScBsgYwZ/JoywdyZJgnbcrTDuVcWG56B3vXbhdpMsCQQDf9zeJrjnPZ3Cqm79y\n" |
(...skipping 17 matching lines...) Expand all Loading... | |
179 "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n" | 214 "LJE/mGw3MyFHEqi81jh95J+ypl6xKW6Rm8jKLR87gUvCaVYn/Z4/P3AqcQTB7wOv\n" |
180 "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n" | 215 "UD0A8qfhfDM+LK6rPAnCsVN0NRDY3jvd6rzix9M=\n" |
181 "-----END CERTIFICATE-----\n"; | 216 "-----END CERTIFICATE-----\n"; |
182 | 217 |
183 rtc::scoped_ptr<SSLIdentity> identity( | 218 rtc::scoped_ptr<SSLIdentity> identity( |
184 SSLIdentity::FromPEMStrings(kRSA_PRIVATE_KEY_PEM, kCERT_PEM)); | 219 SSLIdentity::FromPEMStrings(kRSA_PRIVATE_KEY_PEM, kCERT_PEM)); |
185 EXPECT_TRUE(identity); | 220 EXPECT_TRUE(identity); |
186 EXPECT_EQ(kCERT_PEM, identity->certificate().ToPEMString()); | 221 EXPECT_EQ(kCERT_PEM, identity->certificate().ToPEMString()); |
187 } | 222 } |
188 | 223 |
224 #if SSL_USE_OPENSSL | |
225 // This will not work on NSS as PK11_ImportDERPrivateKeyInfoAndReturnKey is not | |
226 // ready for EC keys. Furthermore, NSSIdentity::FromPEMStrings is currently | |
227 // hardwired for RSA (the header matching via kPemTypeRsaPrivateKey needs | |
228 // trivial generalization). | |
229 TEST_F(SSLIdentityTest, FromPEMStringsEC) { | |
230 static const char kRSA_PRIVATE_KEY_PEM[] = | |
231 "-----BEGIN EC PRIVATE KEY-----\n" | |
232 "MHcCAQEEIKkIztWLPbs4Y2zWv7VW2Ov4is2ifleCuPgRB8fRv3IkoAoGCCqGSM49\n" | |
233 "AwEHoUQDQgAEDPV33NrhSdhg9cBRkUWUXnVMXc3h17i9ARbSmNgminKcBXb8/y8L\n" | |
234 "A76cMWQPPM0ybHO8OS7ZVg2U/m+TwE1M2g==\n" | |
235 "-----END EC PRIVATE KEY-----\n"; | |
236 static const char kCERT_PEM[] = | |
237 "-----BEGIN CERTIFICATE-----\n" | |
238 "MIIB0jCCAXmgAwIBAgIJAMCjpFt9t6LMMAoGCCqGSM49BAMCMEUxCzAJBgNVBAYT\n" | |
239 "AkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRn\n" | |
240 "aXRzIFB0eSBMdGQwIBcNMTUwNjMwMTMwMTIyWhgPMjI4OTA0MTMxMzAxMjJaMEUx\n" | |
241 "CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl\n" | |
242 "cm5ldCBXaWRnaXRzIFB0eSBMdGQwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQM\n" | |
243 "9Xfc2uFJ2GD1wFGRRZRedUxdzeHXuL0BFtKY2CaKcpwFdvz/LwsDvpwxZA88zTJs\n" | |
244 "c7w5LtlWDZT+b5PATUzao1AwTjAdBgNVHQ4EFgQUYHq6nxNNIE832ZmaHc/noODO\n" | |
245 "rtAwHwYDVR0jBBgwFoAUYHq6nxNNIE832ZmaHc/noODOrtAwDAYDVR0TBAUwAwEB\n" | |
246 "/zAKBggqhkjOPQQDAgNHADBEAiAQRojsTyZG0BlKoU7gOt5h+yAMLl2cxmDtOIQr\n" | |
247 "GWP/PwIgJynB4AUDsPT0DWmethOXYijB5sY5UPd9DvgmiS/Mr6s=\n" | |
248 "-----END CERTIFICATE-----\n"; | |
249 | |
250 rtc::scoped_ptr<SSLIdentity> identity( | |
251 SSLIdentity::FromPEMStrings(kRSA_PRIVATE_KEY_PEM, kCERT_PEM)); | |
252 EXPECT_TRUE(identity); | |
253 EXPECT_EQ(kCERT_PEM, identity->certificate().ToPEMString()); | |
254 } | |
255 #endif | |
256 | |
189 TEST_F(SSLIdentityTest, PemDerConversion) { | 257 TEST_F(SSLIdentityTest, PemDerConversion) { |
190 std::string der; | 258 std::string der; |
191 EXPECT_TRUE(SSLIdentity::PemToDer("CERTIFICATE", kTestCertificate, &der)); | 259 EXPECT_TRUE(SSLIdentity::PemToDer("CERTIFICATE", kTestCertificate, &der)); |
192 | 260 |
193 EXPECT_EQ(kTestCertificate, SSLIdentity::DerToPem( | 261 EXPECT_EQ(kTestCertificate, SSLIdentity::DerToPem( |
194 "CERTIFICATE", | 262 "CERTIFICATE", |
195 reinterpret_cast<const unsigned char*>(der.data()), der.length())); | 263 reinterpret_cast<const unsigned char*>(der.data()), der.length())); |
196 } | 264 } |
197 | 265 |
198 TEST_F(SSLIdentityTest, GetSignatureDigestAlgorithm) { | 266 TEST_F(SSLIdentityTest, GetSignatureDigestAlgorithm) { |
199 TestGetSignatureDigestAlgorithm(); | 267 TestGetSignatureDigestAlgorithm(); |
200 } | 268 } |
OLD | NEW |