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