1 /* 2 * libjingle 3 * Copyright 2012, Google Inc. 4 * Copyright 2012, RTFM Inc. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright notice, 12 * this list of conditions and the following disclaimer in the documentation 13 * and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 20 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef TALK_BASE_SSLFINGERPRINT_H_ 30 #define TALK_BASE_SSLFINGERPRINT_H_ 31 32 #include <ctype.h> 33 #include <string> 34 35 #include "talk/base/buffer.h" 36 #include "talk/base/helpers.h" 37 #include "talk/base/messagedigest.h" 38 #include "talk/base/sslidentity.h" 39 #include "talk/base/stringencode.h" 40 41 namespace talk_base { 42 43 struct SSLFingerprint { 44 static SSLFingerprint* Create(const std::string& algorithm, 45 const talk_base::SSLIdentity* identity) { 46 if (!identity) { 47 return NULL; 48 } 49 50 return Create(algorithm, &(identity->certificate())); 51 } 52 53 static SSLFingerprint* Create(const std::string& algorithm, 54 const talk_base::SSLCertificate* cert) { 55 uint8 digest_val[64]; 56 size_t digest_len; 57 bool ret = cert->ComputeDigest( 58 algorithm, digest_val, sizeof(digest_val), &digest_len); 59 if (!ret) { 60 return NULL; 61 } 62 63 return new SSLFingerprint(algorithm, digest_val, digest_len); 64 } 65 66 static SSLFingerprint* CreateFromRfc4572(const std::string& algorithm, 67 const std::string& fingerprint) { 68 if (algorithm.empty()) 69 return NULL; 70 71 if (fingerprint.empty()) 72 return NULL; 73 74 size_t value_len; 75 char value[talk_base::MessageDigest::kMaxSize]; 76 value_len = talk_base::hex_decode_with_delimiter(value, sizeof(value), 77 fingerprint.c_str(), 78 fingerprint.length(), 79 ':'); 80 if (!value_len) 81 return NULL; 82 83 return new SSLFingerprint(algorithm, 84 reinterpret_cast<uint8*>(value), 85 value_len); 86 } 87 88 SSLFingerprint(const std::string& algorithm, const uint8* digest_in, 89 size_t digest_len) : algorithm(algorithm) { 90 digest.SetData(digest_in, digest_len); 91 } 92 SSLFingerprint(const SSLFingerprint& from) 93 : algorithm(from.algorithm), digest(from.digest) {} 94 bool operator==(const SSLFingerprint& other) const { 95 return algorithm == other.algorithm && 96 digest == other.digest; 97 } 98 99 std::string GetRfc4572Fingerprint() const { 100 std::string fingerprint = 101 talk_base::hex_encode_with_delimiter( 102 digest.data(), digest.length(), ':'); 103 std::transform(fingerprint.begin(), fingerprint.end(), 104 fingerprint.begin(), ::toupper); 105 return fingerprint; 106 } 107 108 std::string algorithm; 109 talk_base::Buffer digest; 110 }; 111 112 } // namespace talk_base 113 114 #endif // TALK_BASE_SSLFINGERPRINT_H_ 115