Index: content/renderer/webcrypto_impl_openssl.cc |
diff --git a/content/renderer/webcrypto_impl_openssl.cc b/content/renderer/webcrypto_impl_openssl.cc |
index 9aa1a4253016bb10bd7859a32e42afb5c3483cd0..cd42d458bb0ac6260ae28eee655d1441d6f0fbff 100644 |
--- a/content/renderer/webcrypto_impl_openssl.cc |
+++ b/content/renderer/webcrypto_impl_openssl.cc |
@@ -4,19 +4,75 @@ |
#include "content/renderer/webcrypto_impl.h" |
+#include <openssl/evp.h> |
+ |
+#include "base/logging.h" |
+#include "crypto/openssl_util.h" |
+#include "third_party/WebKit/public/platform/WebArrayBuffer.h" |
+#include "third_party/WebKit/public/platform/WebCryptoAlgorithm.h" |
+ |
namespace content { |
-void WebCryptoImpl::Init() { |
-} |
+void WebCryptoImpl::Init() { crypto::EnsureOpenSSLInit(); } |
-bool WebCryptoImpl::DigestInternal( |
- const WebKit::WebCryptoAlgorithm& algorithm, |
- const unsigned char* data, |
- unsigned data_size, |
- WebKit::WebArrayBuffer* buffer) { |
- // TODO(bryaneyler): Placeholder for OpenSSL implementation. |
- // Issue http://crbug.com/267888. |
- return false; |
+bool WebCryptoImpl::DigestInternal(const WebKit::WebCryptoAlgorithm& algorithm, |
+ const unsigned char* data, |
+ unsigned data_size, |
+ WebKit::WebArrayBuffer* buffer) { |
+ |
+ crypto::OpenSSLErrStackTracer(FROM_HERE); |
+ |
+ const EVP_MD* digest_algorithm; |
+ switch (algorithm.id()) { |
+ case WebKit::WebCryptoAlgorithmIdSha1: |
+ digest_algorithm = EVP_sha1(); |
+ break; |
+ case WebKit::WebCryptoAlgorithmIdSha224: |
+ digest_algorithm = EVP_sha224(); |
+ break; |
+ case WebKit::WebCryptoAlgorithmIdSha256: |
+ digest_algorithm = EVP_sha256(); |
+ break; |
+ case WebKit::WebCryptoAlgorithmIdSha384: |
+ digest_algorithm = EVP_sha384(); |
+ break; |
+ case WebKit::WebCryptoAlgorithmIdSha512: |
+ digest_algorithm = EVP_sha512(); |
+ break; |
+ default: |
+ // Not a digest algorithm. |
+ return false; |
+ } |
+ |
+ crypto::ScopedOpenSSL<EVP_MD_CTX, EVP_MD_CTX_destroy> digest_context( |
+ EVP_MD_CTX_create()); |
+ if (!digest_context.get()) { |
+ return false; |
+ } |
+ |
+ if (!EVP_DigestInit_ex(digest_context.get(), digest_algorithm, NULL) || |
+ !EVP_DigestUpdate(digest_context.get(), data, data_size)) { |
+ return false; |
+ } |
+ |
+ const int hash_expected_size = EVP_MD_CTX_size(digest_context.get()); |
+ if (hash_expected_size <= 0) { |
Bryan Eyler
2013/09/25 22:33:05
Would this be better as a DCHECK, since this shoul
padolph
2013/09/25 22:48:39
Probably, but I'm not sure we can define exact pro
|
+ return false; |
+ } |
+ DCHECK_LE(hash_expected_size, EVP_MAX_MD_SIZE); |
+ |
+ *buffer = WebKit::WebArrayBuffer::create(hash_expected_size, 1); |
+ unsigned char* const hash_buffer = |
+ reinterpret_cast<unsigned char* const>(buffer->data()); |
+ |
+ unsigned hash_size = 0; |
+ if (!EVP_DigestFinal_ex(digest_context.get(), hash_buffer, &hash_size) || |
+ static_cast<int>(hash_size) != hash_expected_size) { |
+ buffer->reset(); |
+ return false; |
+ } |
+ |
+ return true; |
} |
bool WebCryptoImpl::ImportKeyInternal( |