Home | History | Annotate | Download | only in base
      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