15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/signature_verifier.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cryptohi.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <keyhi.h> 9eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <pk11pub.h> 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <secerr.h> 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include <sechash.h> 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/nss_util.h" 16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "crypto/third_party/nss/chromium-nss.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace { 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochHASH_HashType ToNSSHashType(SignatureVerifier::HashAlgorithm hash_alg) { 23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch switch (hash_alg) { 24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SignatureVerifier::SHA1: 25eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return HASH_AlgSHA1; 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case SignatureVerifier::SHA256: 27eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return HASH_AlgSHA256; 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 29eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return HASH_AlgNULL; 30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSECStatus VerifyRSAPSS_End(SECKEYPublicKey* public_key, 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HASHContext* hash_context, 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HASH_HashType mask_hash_alg, 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int salt_len, 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const unsigned char* signature, 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int signature_len) { 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int hash_len = HASH_ResultLenContext(hash_context); 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<unsigned char> hash(hash_len); 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HASH_End(hash_context, &hash[0], &hash_len, hash.size()); 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int modulus_len = SECKEY_PublicKeyStrength(public_key); 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (signature_len != modulus_len) { 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch PORT_SetError(SEC_ERROR_BAD_SIGNATURE); 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return SECFailure; 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<unsigned char> enc(signature_len); 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECStatus rv = PK11_PubEncryptRaw(public_key, &enc[0], 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const_cast<unsigned char*>(signature), 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch signature_len, NULL); 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (rv != SECSuccess) { 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch LOG(WARNING) << "PK11_PubEncryptRaw failed"; 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return rv; 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 55eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return emsa_pss_verify(&hash[0], &enc[0], enc.size(), 56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HASH_GetType(hash_context), mask_hash_alg, 57eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch salt_len); 58eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 59eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} // namespace 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSignatureVerifier::SignatureVerifier() 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : vfy_context_(NULL), 64eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch hash_alg_(SHA1), 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mask_hash_alg_(SHA1), 66eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch salt_len_(0), 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public_key_(NULL), 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch hash_context_(NULL) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnsureNSSInit(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SignatureVerifier::~SignatureVerifier() { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reset(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SignatureVerifier::VerifyInit(const uint8* signature_algorithm, 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int signature_algorithm_len, 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* signature, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int signature_len, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* public_key_info, 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int public_key_info_len) { 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (vfy_context_ || hash_context_) 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature_.assign(signature, signature + signature_len); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECKEYPublicKey* public_key = DecodePublicKeyInfo(public_key_info, 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public_key_info_len); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!public_key) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PLArenaPool* arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!arena) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEY_DestroyPublicKey(public_key); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem sig_alg_der; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig_alg_der.type = siBuffer; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig_alg_der.data = const_cast<uint8*>(signature_algorithm); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig_alg_der.len = signature_algorithm_len; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECAlgorithmID sig_alg_id; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECStatus rv; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = SEC_QuickDERDecodeItem(arena, &sig_alg_id, 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sig_alg_der); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEY_DestroyPublicKey(public_key); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_FreeArena(arena, PR_TRUE); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECItem sig; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig.type = siBuffer; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig.data = const_cast<uint8*>(signature); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sig.len = signature_len; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECOidTag hash_alg_tag; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfy_context_ = VFY_CreateContextWithAlgorithmID(public_key, &sig, 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sig_alg_id, &hash_alg_tag, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SECKEY_DestroyPublicKey(public_key); // Done with public_key. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PORT_FreeArena(arena, PR_TRUE); // Done with sig_alg_id. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!vfy_context_) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A corrupted RSA signature could be detected without the data, so 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // VFY_CreateContextWithAlgorithmID may fail with SEC_ERROR_BAD_SIGNATURE 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (-8182). 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = VFY_Begin(vfy_context_); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != SECSuccess) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool SignatureVerifier::VerifyInitRSAPSS(HashAlgorithm hash_alg, 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HashAlgorithm mask_hash_alg, 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int salt_len, 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* signature, 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int signature_len, 143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* public_key_info, 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int public_key_info_len) { 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (vfy_context_ || hash_context_) 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch signature_.assign(signature, signature + signature_len); 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECKEYPublicKey* public_key = DecodePublicKeyInfo(public_key_info, 151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public_key_info_len); 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!public_key) 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public_key_ = public_key; 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch hash_alg_ = hash_alg; 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mask_hash_alg_ = mask_hash_alg; 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch salt_len_ = salt_len; 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch hash_context_ = HASH_Create(ToNSSHashType(hash_alg_)); 160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!hash_context_) 161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HASH_Begin(hash_context_); 163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return true; 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SignatureVerifier::VerifyUpdate(const uint8* data_part, 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int data_part_len) { 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (vfy_context_) { 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECStatus rv = VFY_Update(vfy_context_, data_part, data_part_len); 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK_EQ(SECSuccess, rv); 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HASH_Update(hash_context_, data_part, data_part_len); 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SignatureVerifier::VerifyFinal() { 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECStatus rv; 178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (vfy_context_) { 179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = VFY_End(vfy_context_); 180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else { 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch rv = VerifyRSAPSS_End(public_key_, hash_context_, 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ToNSSHashType(mask_hash_alg_), salt_len_, 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch signature_.data(), 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch signature_.size()); 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Reset(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If signature verification fails, the error code is 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SEC_ERROR_BAD_SIGNATURE (-8182). 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (rv == SECSuccess); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// static 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochSECKEYPublicKey* SignatureVerifier::DecodePublicKeyInfo( 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const uint8* public_key_info, 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int public_key_info_len) { 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CERTSubjectPublicKeyInfo* spki = NULL; 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECItem spki_der; 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spki_der.type = siBuffer; 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spki_der.data = const_cast<uint8*>(public_key_info); 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spki_der.len = public_key_info_len; 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch spki = SECKEY_DecodeDERSubjectPublicKeyInfo(&spki_der); 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!spki) 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return NULL; 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECKEYPublicKey* public_key = SECKEY_ExtractPublicKey(spki); 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECKEY_DestroySubjectPublicKeyInfo(spki); // Done with spki. 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return public_key; 208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SignatureVerifier::Reset() { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (vfy_context_) { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VFY_DestroyContext(vfy_context_, PR_TRUE); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vfy_context_ = NULL; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (hash_context_) { 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch HASH_Destroy(hash_context_); 217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch hash_context_ = NULL; 218eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (public_key_) { 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SECKEY_DestroyPublicKey(public_key_); 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public_key_ = NULL; 222eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signature_.clear(); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace crypto 227