Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(982)

Side by Side Diff: webrtc/base/opensslidentity.cc

Issue 1468273004: Provide method for returning certificate expiration timestamp. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Misc fixes. Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. 2 * Copyright 2004 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
11 #include <ctime>
hbos 2015/11/25 11:18:31 Move this to the other includes, everything else i
torbjorng (webrtc) 2015/11/25 14:27:11 Done.
12
11 #if HAVE_OPENSSL_SSL_H 13 #if HAVE_OPENSSL_SSL_H
12 14
13 #include "webrtc/base/opensslidentity.h" 15 #include "webrtc/base/opensslidentity.h"
14 16
15 // Must be included first before openssl headers. 17 // Must be included first before openssl headers.
16 #include "webrtc/base/win32.h" // NOLINT 18 #include "webrtc/base/win32.h" // NOLINT
17 19
18 #include <openssl/bio.h> 20 #include <openssl/bio.h>
19 #include <openssl/err.h> 21 #include <openssl/err.h>
20 #include <openssl/pem.h> 22 #include <openssl/pem.h>
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 // clear during SSL negotiation, so there may be a privacy issue in 125 // clear during SSL negotiation, so there may be a privacy issue in
124 // putting anything recognizable here. 126 // putting anything recognizable here.
125 if ((name = X509_NAME_new()) == NULL || 127 if ((name = X509_NAME_new()) == NULL ||
126 !X509_NAME_add_entry_by_NID( 128 !X509_NAME_add_entry_by_NID(
127 name, NID_commonName, MBSTRING_UTF8, 129 name, NID_commonName, MBSTRING_UTF8,
128 (unsigned char*)params.common_name.c_str(), -1, -1, 0) || 130 (unsigned char*)params.common_name.c_str(), -1, -1, 0) ||
129 !X509_set_subject_name(x509, name) || 131 !X509_set_subject_name(x509, name) ||
130 !X509_set_issuer_name(x509, name)) 132 !X509_set_issuer_name(x509, name))
131 goto error; 133 goto error;
132 134
133 if (!X509_gmtime_adj(X509_get_notBefore(x509), params.not_before) || 135 if (params.absolute_time) {
134 !X509_gmtime_adj(X509_get_notAfter(x509), params.not_after)) 136 time_t zero = 0; // Make time epoch based.
137 if (!X509_time_adj_ex(X509_get_notBefore(x509), 0, params.not_before,
138 &zero) ||
139 !X509_time_adj_ex(X509_get_notAfter(x509), 0, params.not_after, &zero))
140 goto error;
141 } else {
142 if (!X509_time_adj_ex(X509_get_notBefore(x509), 0, params.not_before,
143 NULL) ||
144 !X509_time_adj_ex(X509_get_notAfter(x509), 0, params.not_after, NULL))
135 goto error; 145 goto error;
146 }
136 147
137 if (!X509_sign(x509, pkey, EVP_sha256())) 148 if (!X509_sign(x509, pkey, EVP_sha256()))
138 goto error; 149 goto error;
139 150
140 BN_free(serial_number); 151 BN_free(serial_number);
141 X509_NAME_free(name); 152 X509_NAME_free(name);
142 LOG(LS_INFO) << "Returning certificate"; 153 LOG(LS_INFO) << "Returning certificate";
143 return x509; 154 return x509;
144 155
145 error: 156 error:
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 377
367 void OpenSSLCertificate::AddReference() const { 378 void OpenSSLCertificate::AddReference() const {
368 ASSERT(x509_ != NULL); 379 ASSERT(x509_ != NULL);
369 #if defined(OPENSSL_IS_BORINGSSL) 380 #if defined(OPENSSL_IS_BORINGSSL)
370 X509_up_ref(x509_); 381 X509_up_ref(x509_);
371 #else 382 #else
372 CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509); 383 CRYPTO_add(&x509_->references, 1, CRYPTO_LOCK_X509);
373 #endif 384 #endif
374 } 385 }
375 386
387 // Convert from std::tm to number of seconds from epoch.
388 // Note that std::tm is relative to 1900-01-01.
389 static int64_t tm_to_seconds(const std::tm& tm) {
390 static short int cumul_days[12] = {0, 31, 59, 90, 120, 151,
391 181, 212, 243, 273, 304, 334};
392
393 int year = tm.tm_year + 1900;
394 int month = tm.tm_mon;
395 int day = tm.tm_mday - 1;
396 int hour = tm.tm_hour;
397 int min = tm.tm_min;
398 int sec = tm.tm_sec;
399
400 // If expiration time is in a leap year, number of days depends on exact date.
401 if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) {
402 if (month <= 2 - 1) { // February or earlier (|month| is zero based).
403 day -= 1;
404 }
405 }
406
407 day += cumul_days[month];
408
409 // Add number of leap days between 1970 and the expiration time.
410 day += ((year / 4 - 1970 / 4) - (year / 100 - 1970 / 100) +
411 (year / 400 - 1970 / 400));
412
413 year -= 1970;
414 return ((((int64_t)year * 365 + day) * 24 + hour) * 60 + min) * 60 + sec;
415 }
416
417 #define ASN1_READ2(x) \
418 do { \
419 x = 10 * s[0] + s[1] - '0' * 11; \
420 s += 2; \
421 bytes_left -= 2; \
422 } while (0)
423 #define ASN1_READ4(x) \
424 do { \
425 x = 1000 * s[0] + 100 * s[1] + 10 * s[2] + s[3] - '0' * 1111; \
426 s += 4; \
427 bytes_left -= 4; \
428 } while (0)
429
430 // Convert from ASN1 TIME as restricted by RFC 5280 to milliseconds from epoch.
431 // If the ASN1_TIME cannot be read, return -1. Use std::tm for intermediate
432 // results in the way specified by Unix time functions.
433 static int64_t asn1_time_to_time_t(const ASN1_TIME* time) {
434 std::tm tm;
435 int year;
436 int month;
437 const unsigned char* s = (const unsigned char*)time->data;
438 size_t bytes_left = time->length;
439
440 if (time->type == V_ASN1_UTCTIME) {
441 // ASN1 format: yymmddhhmm[ss]Z where the Z is literal, but RFC 5280 only
442 // requires us to support exactly yymmddhhmmssZ.
443
444 if (bytes_left < 9)
445 return -1;
446
447 ASN1_READ2(year);
448 if (year < 70)
449 year += 100;
450 } else if (time->type == V_ASN1_GENERALIZEDTIME) {
451 // ASN1 format: yyyymmddhh[mm[ss[.fff]]]Z where the Z is literal. but
452 // RFC 5280 only requires us to support exactly yyyymmddhhmmssZ.
453
454 if (bytes_left < 11)
455 return -1;
456
457 ASN1_READ4(year);
458 year -= 1900;
459 } else {
460 return -1;
461 }
462
463 // Zeroing the entire structure helps with the defaulting of the minute and
464 // second fields, as well as a bunch of other (here unused) fields.
465 memset(&tm, 0, sizeof(tm));
466
467 tm.tm_year = year;
468 ASN1_READ2(month);
469 tm.tm_mon = month - 1;
470 ASN1_READ2(tm.tm_mday);
471 ASN1_READ2(tm.tm_hour);
472 ASN1_READ2(tm.tm_min);
473 ASN1_READ2(tm.tm_sec);
474
475 if (bytes_left != 1 || s[0] != 'Z') {
476 // A final Z means UTC, mandated by RFC 5280, and compatible with OpenSSL.
477 return -1;
478 }
479
480 return 1000 * tm_to_seconds(tm);
481 }
482 #undef ASN1_READ4
483 #undef ASN1_READ2
484
485 int64_t OpenSSLCertificate::CertificateExpirationTime() const {
486 ASN1_TIME* exptime = X509_get_notAfter(x509_);
487 return asn1_time_to_time_t(exptime);
488 }
489
376 OpenSSLIdentity::OpenSSLIdentity(OpenSSLKeyPair* key_pair, 490 OpenSSLIdentity::OpenSSLIdentity(OpenSSLKeyPair* key_pair,
377 OpenSSLCertificate* certificate) 491 OpenSSLCertificate* certificate)
378 : key_pair_(key_pair), certificate_(certificate) { 492 : key_pair_(key_pair), certificate_(certificate) {
379 ASSERT(key_pair != NULL); 493 ASSERT(key_pair != NULL);
380 ASSERT(certificate != NULL); 494 ASSERT(certificate != NULL);
381 } 495 }
382 496
383 OpenSSLIdentity::~OpenSSLIdentity() = default; 497 OpenSSLIdentity::~OpenSSLIdentity() = default;
384 498
385 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal( 499 OpenSSLIdentity* OpenSSLIdentity::GenerateInternal(
386 const SSLIdentityParams& params) { 500 const SSLIdentityParams& params) {
387 OpenSSLKeyPair* key_pair = OpenSSLKeyPair::Generate(params.key_params); 501 OpenSSLKeyPair* key_pair = OpenSSLKeyPair::Generate(params.key_params);
388 if (key_pair) { 502 if (key_pair) {
389 OpenSSLCertificate* certificate = 503 OpenSSLCertificate* certificate =
390 OpenSSLCertificate::Generate(key_pair, params); 504 OpenSSLCertificate::Generate(key_pair, params);
391 if (certificate) 505 if (certificate)
392 return new OpenSSLIdentity(key_pair, certificate); 506 return new OpenSSLIdentity(key_pair, certificate);
393 delete key_pair; 507 delete key_pair;
394 } 508 }
395 LOG(LS_INFO) << "Identity generation failed"; 509 LOG(LS_INFO) << "Identity generation failed";
396 return NULL; 510 return NULL;
397 } 511 }
398 512
399 OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name, 513 OpenSSLIdentity* OpenSSLIdentity::Generate(const std::string& common_name,
400 const KeyParams& key_params) { 514 const KeyParams& key_params) {
401 SSLIdentityParams params; 515 SSLIdentityParams params;
402 params.key_params = key_params; 516 params.key_params = key_params;
403 params.common_name = common_name; 517 params.common_name = common_name;
518 params.absolute_time = false;
404 params.not_before = CERTIFICATE_WINDOW; 519 params.not_before = CERTIFICATE_WINDOW;
405 params.not_after = CERTIFICATE_LIFETIME; 520 params.not_after = CERTIFICATE_LIFETIME;
406 return GenerateInternal(params); 521 return GenerateInternal(params);
407 } 522 }
408 523
409 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest( 524 OpenSSLIdentity* OpenSSLIdentity::GenerateForTest(
410 const SSLIdentityParams& params) { 525 const SSLIdentityParams& params) {
411 return GenerateInternal(params); 526 return GenerateInternal(params);
412 } 527 }
413 528
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
455 SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) { 570 SSL_CTX_use_PrivateKey(ctx, key_pair_->pkey()) != 1) {
456 LogSSLErrors("Configuring key and certificate"); 571 LogSSLErrors("Configuring key and certificate");
457 return false; 572 return false;
458 } 573 }
459 return true; 574 return true;
460 } 575 }
461 576
462 } // namespace rtc 577 } // namespace rtc
463 578
464 #endif // HAVE_OPENSSL_SSL_H 579 #endif // HAVE_OPENSSL_SSL_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698