15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 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)#ifndef CRYPTO_SIGNATURE_VERIFIER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CRYPTO_SIGNATURE_VERIFIER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/crypto_export.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(USE_OPENSSL)
16eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef struct env_md_st EVP_MD;
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef struct HASHContextStr HASHContext;
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef struct SECKEYPublicKeyStr SECKEYPublicKey;
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct VFYContextStr VFYContext;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace crypto {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The SignatureVerifier class verifies a signature using a bare public key
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (as opposed to a certificate).
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CRYPTO_EXPORT SignatureVerifier {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The set of supported hash functions. Extend as required.
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  enum HashAlgorithm {
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SHA1,
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    SHA256,
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  };
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SignatureVerifier();
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~SignatureVerifier();
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Streaming interface:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initiates a signature verification operation.  This should be followed
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // by one or more VerifyUpdate calls and a VerifyFinal call.
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // NOTE: for RSA-PSS signatures, use VerifyInitRSAPSS instead.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The signature algorithm is specified as a DER encoded ASN.1
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // AlgorithmIdentifier structure:
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   AlgorithmIdentifier  ::=  SEQUENCE  {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       algorithm               OBJECT IDENTIFIER,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       parameters              ANY DEFINED BY algorithm OPTIONAL  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The signature is encoded according to the signature algorithm, but it
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // must not be further encoded in an ASN.1 BIT STRING.
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Note: An RSA signature is actually a big integer.  It must be in
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // big-endian byte order.
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // structure, which contains not only the public key but also its type
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (algorithm):
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   SubjectPublicKeyInfo  ::=  SEQUENCE  {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       algorithm            AlgorithmIdentifier,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //       subjectPublicKey     BIT STRING  }
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool VerifyInit(const uint8* signature_algorithm,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int signature_algorithm_len,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const uint8* signature,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int signature_len,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const uint8* public_key_info,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  int public_key_info_len);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
69eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Initiates a RSA-PSS signature verification operation.  This should be
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // followed by one or more VerifyUpdate calls and a VerifyFinal call.
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The RSA-PSS signature algorithm parameters are specified with the
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // |hash_alg|, |mask_hash_alg|, and |salt_len| arguments.
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // An RSA-PSS signature is a nonnegative integer encoded as a byte string
76eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // (of the same length as the RSA modulus) in big-endian byte order. It
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // must not be further encoded in an ASN.1 BIT STRING.
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // structure, which contains not only the public key but also its type
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // (algorithm):
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   SubjectPublicKeyInfo  ::=  SEQUENCE  {
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //       algorithm            AlgorithmIdentifier,
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //       subjectPublicKey     BIT STRING  }
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool VerifyInitRSAPSS(HashAlgorithm hash_alg,
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        HashAlgorithm mask_hash_alg,
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        int salt_len,
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        const uint8* signature,
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        int signature_len,
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        const uint8* public_key_info,
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                        int public_key_info_len);
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Feeds a piece of the data to the signature verifier.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void VerifyUpdate(const uint8* data_part, int data_part_len);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Concludes a signature verification operation.  Returns true if the
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // signature is valid.  Returns false if the signature is invalid or an
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // error occurred.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool VerifyFinal();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: we can provide a one-shot interface if there is interest:
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   bool Verify(const uint8* data,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               int data_len,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               const uint8* signature_algorithm,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               int signature_algorithm_len,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               const uint8* signature,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               int signature_len,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               const uint8* public_key_info,
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               int public_key_info_len);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(USE_OPENSSL)
113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool CommonInit(const EVP_MD* digest,
114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  const uint8* signature,
115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  int signature_len,
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  const uint8* public_key_info,
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  int public_key_info_len,
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                  EVP_PKEY_CTX** pkey_ctx);
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  static SECKEYPublicKey* DecodePublicKeyInfo(const uint8* public_key_info,
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                              int public_key_info_len);
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Reset();
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<uint8> signature_;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_OPENSSL)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct VerifyContext;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VerifyContext* verify_context_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Used for all signature types except RSA-PSS.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VFYContext* vfy_context_;
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Used for RSA-PSS signatures.
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HashAlgorithm hash_alg_;
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HashAlgorithm mask_hash_alg_;
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  unsigned int salt_len_;
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SECKEYPublicKey* public_key_;
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  HASHContext* hash_context_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace crypto
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CRYPTO_SIGNATURE_VERIFIER_H_
147