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 3645779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // The set of supported signature algorithms. Extend as required. 3745779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko enum SignatureAlgorithm { 3845779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko RSA_PKCS1_SHA1, 3945779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko RSA_PKCS1_SHA256, 4045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko ECDSA_SHA256, 4145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko }; 4245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko 4359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat SignatureVerifier(); 4459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat ~SignatureVerifier(); 4559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 4659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Streaming interface: 4759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 4859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Initiates a signature verification operation. This should be followed 4959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // by one or more VerifyUpdate calls and a VerifyFinal call. 5059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // NOTE: for RSA-PSS signatures, use VerifyInitRSAPSS instead. 5159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 5245779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko // The signature is encoded according to the signature algorithm. 5359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 5459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo 5559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // structure, which contains not only the public key but also its type 5659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // (algorithm): 5759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // SubjectPublicKeyInfo ::= SEQUENCE { 5859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // algorithm AlgorithmIdentifier, 5959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // subjectPublicKey BIT STRING } 6045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko bool VerifyInit(SignatureAlgorithm signature_algorithm, 610d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* signature, 6259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int signature_len, 630d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* public_key_info, 6459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len); 6559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 6659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Initiates a RSA-PSS signature verification operation. This should be 6759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // followed by one or more VerifyUpdate calls and a VerifyFinal call. 6859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 6959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The RSA-PSS signature algorithm parameters are specified with the 7059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // |hash_alg|, |mask_hash_alg|, and |salt_len| arguments. 7159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 7259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // An RSA-PSS signature is a nonnegative integer encoded as a byte string 7359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // (of the same length as the RSA modulus) in big-endian byte order. It 7459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // must not be further encoded in an ASN.1 BIT STRING. 7559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // 7659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo 7759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // structure, which contains not only the public key but also its type 7859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // (algorithm): 7959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // SubjectPublicKeyInfo ::= SEQUENCE { 8059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // algorithm AlgorithmIdentifier, 8159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // subjectPublicKey BIT STRING } 8259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat bool VerifyInitRSAPSS(HashAlgorithm hash_alg, 8359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HashAlgorithm mask_hash_alg, 8459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int salt_len, 850d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* signature, 8659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int signature_len, 870d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* public_key_info, 8859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len); 8959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 9059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Feeds a piece of the data to the signature verifier. 910d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko void VerifyUpdate(const uint8_t* data_part, int data_part_len); 9259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 9359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Concludes a signature verification operation. Returns true if the 9459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // signature is valid. Returns false if the signature is invalid or an 9559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // error occurred. 9659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat bool VerifyFinal(); 9759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 9859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat private: 9959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#if defined(USE_OPENSSL) 10045779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko bool CommonInit(int pkey_type, 10145779228f8c9e40851cfd23f727e2bd8ffdd4714Alex Vakulenko const EVP_MD* digest, 1020d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* signature, 10359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int signature_len, 1040d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko const uint8_t* public_key_info, 10559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len, 10659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat EVP_PKEY_CTX** pkey_ctx); 10759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#else 1080d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko static SECKEYPublicKey* DecodePublicKeyInfo(const uint8_t* public_key_info, 10959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat int public_key_info_len); 11059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif 11159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 11259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat void Reset(); 11359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 1140d205d712abd16eeed2f5d5b1052a367d23a223fAlex Vakulenko std::vector<uint8_t> signature_; 11559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 11659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#if defined(USE_OPENSSL) 11759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat struct VerifyContext; 11859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat VerifyContext* verify_context_; 11959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#else 12059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Used for all signature types except RSA-PSS. 12159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat VFYContext* vfy_context_; 12259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 12359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat // Used for RSA-PSS signatures. 12459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HashAlgorithm hash_alg_; 12559c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HashAlgorithm mask_hash_alg_; 12659c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat unsigned int salt_len_; 12759c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat SECKEYPublicKey* public_key_; 12859c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat HASHContext* hash_context_; 12959c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif 13059c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat}; 13159c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 13259c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat} // namespace crypto 13359c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat 13459c5f4b0fb104e8e4806e4934a3d5d112ad695abDaniel Erat#endif // CRYPTO_SIGNATURE_VERIFIER_H_ 135