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