1 /* 2 * Copyright 2004 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 11 #if HAVE_OPENSSL_SSL_H 12 13 #include "webrtc/base/openssldigest.h" 14 15 #include "webrtc/base/common.h" 16 #include "webrtc/base/openssl.h" 17 18 namespace rtc { 19 20 OpenSSLDigest::OpenSSLDigest(const std::string& algorithm) { 21 EVP_MD_CTX_init(&ctx_); 22 if (GetDigestEVP(algorithm, &md_)) { 23 EVP_DigestInit_ex(&ctx_, md_, NULL); 24 } else { 25 md_ = NULL; 26 } 27 } 28 29 OpenSSLDigest::~OpenSSLDigest() { 30 EVP_MD_CTX_cleanup(&ctx_); 31 } 32 33 size_t OpenSSLDigest::Size() const { 34 if (!md_) { 35 return 0; 36 } 37 return EVP_MD_size(md_); 38 } 39 40 void OpenSSLDigest::Update(const void* buf, size_t len) { 41 if (!md_) { 42 return; 43 } 44 EVP_DigestUpdate(&ctx_, buf, len); 45 } 46 47 size_t OpenSSLDigest::Finish(void* buf, size_t len) { 48 if (!md_ || len < Size()) { 49 return 0; 50 } 51 unsigned int md_len; 52 EVP_DigestFinal_ex(&ctx_, static_cast<unsigned char*>(buf), &md_len); 53 EVP_DigestInit_ex(&ctx_, md_, NULL); // prepare for future Update()s 54 ASSERT(md_len == Size()); 55 return md_len; 56 } 57 58 bool OpenSSLDigest::GetDigestEVP(const std::string& algorithm, 59 const EVP_MD** mdp) { 60 const EVP_MD* md; 61 if (algorithm == DIGEST_MD5) { 62 md = EVP_md5(); 63 } else if (algorithm == DIGEST_SHA_1) { 64 md = EVP_sha1(); 65 } else if (algorithm == DIGEST_SHA_224) { 66 md = EVP_sha224(); 67 } else if (algorithm == DIGEST_SHA_256) { 68 md = EVP_sha256(); 69 } else if (algorithm == DIGEST_SHA_384) { 70 md = EVP_sha384(); 71 } else if (algorithm == DIGEST_SHA_512) { 72 md = EVP_sha512(); 73 } else { 74 return false; 75 } 76 77 // Can't happen 78 ASSERT(EVP_MD_size(md) >= 16); 79 *mdp = md; 80 return true; 81 } 82 83 bool OpenSSLDigest::GetDigestName(const EVP_MD* md, 84 std::string* algorithm) { 85 ASSERT(md != NULL); 86 ASSERT(algorithm != NULL); 87 88 int md_type = EVP_MD_type(md); 89 if (md_type == NID_md5) { 90 *algorithm = DIGEST_MD5; 91 } else if (md_type == NID_sha1) { 92 *algorithm = DIGEST_SHA_1; 93 } else if (md_type == NID_sha224) { 94 *algorithm = DIGEST_SHA_224; 95 } else if (md_type == NID_sha256) { 96 *algorithm = DIGEST_SHA_256; 97 } else if (md_type == NID_sha384) { 98 *algorithm = DIGEST_SHA_384; 99 } else if (md_type == NID_sha512) { 100 *algorithm = DIGEST_SHA_512; 101 } else { 102 algorithm->clear(); 103 return false; 104 } 105 106 return true; 107 } 108 109 bool OpenSSLDigest::GetDigestSize(const std::string& algorithm, 110 size_t* length) { 111 const EVP_MD *md; 112 if (!GetDigestEVP(algorithm, &md)) 113 return false; 114 115 *length = EVP_MD_size(md); 116 return true; 117 } 118 119 } // namespace rtc 120 121 #endif // HAVE_OPENSSL_SSL_H 122 123