1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "crypto/signature_verifier.h"
7 #include <openssl/evp.h>
8 #include <openssl/x509.h>
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/stl_util-inl.h"
15 #include "crypto/openssl_util.h"
19 struct SignatureVerifier::VerifyContext
{
20 ScopedOpenSSL
<EVP_PKEY
, EVP_PKEY_free
> public_key
;
21 ScopedOpenSSL
<EVP_MD_CTX
, EVP_MD_CTX_destroy
> ctx
;
24 SignatureVerifier::SignatureVerifier()
25 : verify_context_(NULL
) {
28 SignatureVerifier::~SignatureVerifier() {
32 bool SignatureVerifier::VerifyInit(const uint8
* signature_algorithm
,
33 int signature_algorithm_len
,
34 const uint8
* signature
,
36 const uint8
* public_key_info
,
37 int public_key_info_len
) {
38 DCHECK(!verify_context_
);
39 verify_context_
= new VerifyContext
;
40 OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
42 ScopedOpenSSL
<X509_ALGOR
, X509_ALGOR_free
> algorithm(
43 d2i_X509_ALGOR(NULL
, &signature_algorithm
, signature_algorithm_len
));
47 const EVP_MD
* digest
= EVP_get_digestbyobj(algorithm
.get()->algorithm
);
50 signature_
.assign(signature
, signature
+ signature_len
);
52 // BIO_new_mem_buf is not const aware, but it does not modify the buffer.
53 char* data
= reinterpret_cast<char*>(const_cast<uint8
*>(public_key_info
));
54 ScopedOpenSSL
<BIO
, BIO_free_all
> bio(BIO_new_mem_buf(data
,
55 public_key_info_len
));
59 verify_context_
->public_key
.reset(d2i_PUBKEY_bio(bio
.get(), NULL
));
60 if (!verify_context_
->public_key
.get())
63 verify_context_
->ctx
.reset(EVP_MD_CTX_create());
64 int rv
= EVP_VerifyInit_ex(verify_context_
->ctx
.get(), digest
, NULL
);
68 void SignatureVerifier::VerifyUpdate(const uint8
* data_part
,
70 DCHECK(verify_context_
);
71 OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
72 int rv
= EVP_VerifyUpdate(verify_context_
->ctx
.get(),
73 data_part
, data_part_len
);
77 bool SignatureVerifier::VerifyFinal() {
78 DCHECK(verify_context_
);
79 OpenSSLErrStackTracer
err_tracer(FROM_HERE
);
80 int rv
= EVP_VerifyFinal(verify_context_
->ctx
.get(),
81 vector_as_array(&signature_
), signature_
.size(),
82 verify_context_
->public_key
.get());
88 void SignatureVerifier::Reset() {
89 delete verify_context_
;
90 verify_context_
= NULL
;