| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 1 | /* | 
 | 2 |  *  Copyright 2012 The WebRTC Project Authors. All rights reserved. | 
 | 3 |  * | 
 | 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 | 
 | 6 |  *  tree. An additional intellectual property rights grant can be found | 
 | 7 |  *  in the file PATENTS.  All contributing project authors may | 
 | 8 |  *  be found in the AUTHORS file in the root of the source tree. | 
 | 9 |  */ | 
 | 10 |  | 
| Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 11 | #include "rtc_base/sslfingerprint.h" | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 12 |  | 
 | 13 | #include <ctype.h> | 
 | 14 | #include <string> | 
 | 15 |  | 
| Mirko Bonadei | 92ea95e | 2017-09-15 06:47:31 +0200 | [diff] [blame] | 16 | #include "rtc_base/helpers.h" | 
 | 17 | #include "rtc_base/logging.h" | 
 | 18 | #include "rtc_base/messagedigest.h" | 
 | 19 | #include "rtc_base/stringencode.h" | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 20 |  | 
 | 21 | namespace rtc { | 
 | 22 |  | 
 | 23 | SSLFingerprint* SSLFingerprint::Create( | 
 | 24 |     const std::string& algorithm, const rtc::SSLIdentity* identity) { | 
 | 25 |   if (!identity) { | 
| deadbeef | 37f5ecf | 2017-02-27 14:06:41 -0800 | [diff] [blame] | 26 |     return nullptr; | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 27 |   } | 
 | 28 |  | 
 | 29 |   return Create(algorithm, &(identity->certificate())); | 
 | 30 | } | 
 | 31 |  | 
 | 32 | SSLFingerprint* SSLFingerprint::Create( | 
 | 33 |     const std::string& algorithm, const rtc::SSLCertificate* cert) { | 
| Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 34 |   uint8_t digest_val[64]; | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 35 |   size_t digest_len; | 
 | 36 |   bool ret = cert->ComputeDigest( | 
 | 37 |       algorithm, digest_val, sizeof(digest_val), &digest_len); | 
 | 38 |   if (!ret) { | 
| deadbeef | 37f5ecf | 2017-02-27 14:06:41 -0800 | [diff] [blame] | 39 |     return nullptr; | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 40 |   } | 
 | 41 |  | 
 | 42 |   return new SSLFingerprint(algorithm, digest_val, digest_len); | 
 | 43 | } | 
 | 44 |  | 
 | 45 | SSLFingerprint* SSLFingerprint::CreateFromRfc4572( | 
 | 46 |     const std::string& algorithm, const std::string& fingerprint) { | 
 | 47 |   if (algorithm.empty() || !rtc::IsFips180DigestAlgorithm(algorithm)) | 
| deadbeef | 37f5ecf | 2017-02-27 14:06:41 -0800 | [diff] [blame] | 48 |     return nullptr; | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 49 |  | 
 | 50 |   if (fingerprint.empty()) | 
| deadbeef | 37f5ecf | 2017-02-27 14:06:41 -0800 | [diff] [blame] | 51 |     return nullptr; | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 52 |  | 
 | 53 |   size_t value_len; | 
 | 54 |   char value[rtc::MessageDigest::kMaxSize]; | 
 | 55 |   value_len = rtc::hex_decode_with_delimiter(value, sizeof(value), | 
 | 56 |                                                    fingerprint.c_str(), | 
 | 57 |                                                    fingerprint.length(), | 
 | 58 |                                                    ':'); | 
 | 59 |   if (!value_len) | 
| deadbeef | 37f5ecf | 2017-02-27 14:06:41 -0800 | [diff] [blame] | 60 |     return nullptr; | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 61 |  | 
| Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 62 |   return new SSLFingerprint(algorithm, reinterpret_cast<uint8_t*>(value), | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 63 |                             value_len); | 
 | 64 | } | 
 | 65 |  | 
| deadbeef | 8662f94 | 2017-01-20 21:20:51 -0800 | [diff] [blame] | 66 | SSLFingerprint* SSLFingerprint::CreateFromCertificate( | 
 | 67 |     const RTCCertificate* cert) { | 
 | 68 |   std::string digest_alg; | 
 | 69 |   if (!cert->ssl_certificate().GetSignatureDigestAlgorithm(&digest_alg)) { | 
| Mirko Bonadei | 675513b | 2017-11-09 11:09:25 +0100 | [diff] [blame] | 70 |     RTC_LOG(LS_ERROR) | 
 | 71 |         << "Failed to retrieve the certificate's digest algorithm"; | 
| deadbeef | 8662f94 | 2017-01-20 21:20:51 -0800 | [diff] [blame] | 72 |     return nullptr; | 
 | 73 |   } | 
 | 74 |  | 
 | 75 |   SSLFingerprint* fingerprint = Create(digest_alg, cert->identity()); | 
 | 76 |   if (!fingerprint) { | 
| Mirko Bonadei | 675513b | 2017-11-09 11:09:25 +0100 | [diff] [blame] | 77 |     RTC_LOG(LS_ERROR) << "Failed to create identity fingerprint, alg=" | 
 | 78 |                       << digest_alg; | 
| deadbeef | 8662f94 | 2017-01-20 21:20:51 -0800 | [diff] [blame] | 79 |   } | 
 | 80 |   return fingerprint; | 
 | 81 | } | 
 | 82 |  | 
| Peter Boström | 0c4e06b | 2015-10-07 12:23:21 +0200 | [diff] [blame] | 83 | SSLFingerprint::SSLFingerprint(const std::string& algorithm, | 
 | 84 |                                const uint8_t* digest_in, | 
 | 85 |                                size_t digest_len) | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 86 |     : algorithm(algorithm) { | 
 | 87 |   digest.SetData(digest_in, digest_len); | 
 | 88 | } | 
 | 89 |  | 
 | 90 | SSLFingerprint::SSLFingerprint(const SSLFingerprint& from) | 
 | 91 |     : algorithm(from.algorithm), digest(from.digest) {} | 
 | 92 |  | 
 | 93 | bool SSLFingerprint::operator==(const SSLFingerprint& other) const { | 
 | 94 |   return algorithm == other.algorithm && | 
 | 95 |          digest == other.digest; | 
 | 96 | } | 
 | 97 |  | 
 | 98 | std::string SSLFingerprint::GetRfc4572Fingerprint() const { | 
 | 99 |   std::string fingerprint = | 
| Karl Wiberg | 9478437 | 2015-04-20 14:03:07 +0200 | [diff] [blame] | 100 |       rtc::hex_encode_with_delimiter(digest.data<char>(), digest.size(), ':'); | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 101 |   std::transform(fingerprint.begin(), fingerprint.end(), | 
 | 102 |                  fingerprint.begin(), ::toupper); | 
 | 103 |   return fingerprint; | 
 | 104 | } | 
 | 105 |  | 
| mikescarlett | e774867 | 2016-04-29 20:20:54 -0700 | [diff] [blame] | 106 | std::string SSLFingerprint::ToString() const { | 
| henrike@webrtc.org | f048872 | 2014-05-13 18:00:26 +0000 | [diff] [blame] | 107 |   std::string fp_str = algorithm; | 
 | 108 |   fp_str.append(" "); | 
 | 109 |   fp_str.append(GetRfc4572Fingerprint()); | 
 | 110 |   return fp_str; | 
 | 111 | } | 
 | 112 |  | 
 | 113 | }  // namespace rtc |