signature_verifier.h revision 0d205d712abd16eeed2f5d5b1052a367d23a223f
159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Copyright (c) 2012 The Chromium Authors. All rights reserved. 259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// Use of this source code is governed by a BSD-style license that can be 359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// found in the LICENSE file. 459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#ifndef CRYPTO_SIGNATURE_VERIFIER_H_ 659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#define CRYPTO_SIGNATURE_VERIFIER_H_ 759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 80d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko#include <stdint.h> 90d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko 1059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include <vector> 1159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 1259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "build/build_config.h" 1359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#include "crypto/crypto_export.h" 1459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 1559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#if defined(USE_OPENSSL) 1659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattypedef struct env_md_st EVP_MD; 1759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattypedef struct evp_pkey_ctx_st EVP_PKEY_CTX; 1859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#else 1959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattypedef struct HASHContextStr HASHContext; 2059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattypedef struct SECKEYPublicKeyStr SECKEYPublicKey; 2159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erattypedef struct VFYContextStr VFYContext; 2259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif 2359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 2459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratnamespace crypto { 2559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 2659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// The SignatureVerifier class verifies a signature using a bare public key 2759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat// (as opposed to a certificate). 2859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Eratclass CRYPTO_EXPORT SignatureVerifier { 2959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat public: 3059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The set of supported hash functions. Extend as required. 3159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat enum HashAlgorithm { 3259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat SHA1, 3359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat SHA256, 3459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat }; 3559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 3659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat SignatureVerifier(); 3759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat ~SignatureVerifier(); 3859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 3959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Streaming interface: 4059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 4159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Initiates a signature verification operation. This should be followed 4259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // by one or more VerifyUpdate calls and a VerifyFinal call. 4359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // NOTE: for RSA-PSS signatures, use VerifyInitRSAPSS instead. 4459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 4559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The signature algorithm is specified as a DER encoded ASN.1 4659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // AlgorithmIdentifier structure: 4759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // AlgorithmIdentifier ::= SEQUENCE { 4859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // algorithm OBJECT IDENTIFIER, 4959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // parameters ANY DEFINED BY algorithm OPTIONAL } 5059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 5159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The signature is encoded according to the signature algorithm, but it 5259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // must not be further encoded in an ASN.1 BIT STRING. 5359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Note: An RSA signature is actually a big integer. It must be in 5459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // big-endian byte order. 5559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 5659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo 5759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // structure, which contains not only the public key but also its type 5859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // (algorithm): 5959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // SubjectPublicKeyInfo ::= SEQUENCE { 6059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // algorithm AlgorithmIdentifier, 6159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // subjectPublicKey BIT STRING } 620d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko bool VerifyInit(const uint8_t* signature_algorithm, 6359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int signature_algorithm_len, 640d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* signature, 6559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int signature_len, 660d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* public_key_info, 6759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len); 6859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 6959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Initiates a RSA-PSS signature verification operation. This should be 7059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // followed by one or more VerifyUpdate calls and a VerifyFinal call. 7159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 7259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The RSA-PSS signature algorithm parameters are specified with the 7359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // |hash_alg|, |mask_hash_alg|, and |salt_len| arguments. 7459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 7559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // An RSA-PSS signature is a nonnegative integer encoded as a byte string 7659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // (of the same length as the RSA modulus) in big-endian byte order. It 7759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // must not be further encoded in an ASN.1 BIT STRING. 7859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 7959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo 8059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // structure, which contains not only the public key but also its type 8159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // (algorithm): 8259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // SubjectPublicKeyInfo ::= SEQUENCE { 8359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // algorithm AlgorithmIdentifier, 8459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // subjectPublicKey BIT STRING } 8559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat bool VerifyInitRSAPSS(HashAlgorithm hash_alg, 8659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HashAlgorithm mask_hash_alg, 8759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int salt_len, 880d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* signature, 8959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int signature_len, 900d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* public_key_info, 9159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len); 9259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 9359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Feeds a piece of the data to the signature verifier. 940d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko void VerifyUpdate(const uint8_t* data_part, int data_part_len); 9559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 9659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Concludes a signature verification operation. Returns true if the 9759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // signature is valid. Returns false if the signature is invalid or an 9859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // error occurred. 9959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat bool VerifyFinal(); 10059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 10159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Note: we can provide a one-shot interface if there is interest: 1020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // bool Verify(const uint8_t* data, 10359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // int data_len, 1040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // const uint8_t* signature_algorithm, 10559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // int signature_algorithm_len, 1060d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // const uint8_t* signature, 10759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // int signature_len, 1080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko // const uint8_t* public_key_info, 10959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // int public_key_info_len); 11059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 11159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private: 11259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#if defined(USE_OPENSSL) 11359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat bool CommonInit(const EVP_MD* digest, 1140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* signature, 11559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int signature_len, 1160d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* public_key_info, 11759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len, 11859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat EVP_PKEY_CTX** pkey_ctx); 11959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#else 1200d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko static SECKEYPublicKey* DecodePublicKeyInfo(const uint8_t* public_key_info, 12159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len); 12259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif 12359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 12459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat void Reset(); 12559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 1260d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko std::vector<uint8_t> signature_; 12759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 12859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#if defined(USE_OPENSSL) 12959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat struct VerifyContext; 13059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat VerifyContext* verify_context_; 13159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#else 13259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Used for all signature types except RSA-PSS. 13359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat VFYContext* vfy_context_; 13459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 13559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Used for RSA-PSS signatures. 13659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HashAlgorithm hash_alg_; 13759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HashAlgorithm mask_hash_alg_; 13859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat unsigned int salt_len_; 13959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat SECKEYPublicKey* public_key_; 14059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HASHContext* hash_context_; 14159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif 14259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}; 14359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 14459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat} // namespace crypto 14559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 14659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif // CRYPTO_SIGNATURE_VERIFIER_H_ 147