1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CRYPTO_SIGNATURE_VERIFIER_H_
6 #define CRYPTO_SIGNATURE_VERIFIER_H_
7 
8 #include <stdint.h>
9 
10 #include <vector>
11 
12 #include "build/build_config.h"
13 #include "crypto/crypto_export.h"
14 
15 #if defined(USE_OPENSSL)
16 typedef struct env_md_st EVP_MD;
17 typedef struct evp_pkey_ctx_st EVP_PKEY_CTX;
18 #else
19 typedef struct HASHContextStr HASHContext;
20 typedef struct SECKEYPublicKeyStr SECKEYPublicKey;
21 typedef struct VFYContextStr VFYContext;
22 #endif
23 
24 namespace crypto {
25 
26 // The SignatureVerifier class verifies a signature using a bare public key
27 // (as opposed to a certificate).
28 class CRYPTO_EXPORT SignatureVerifier {
29  public:
30   // The set of supported hash functions. Extend as required.
31   enum HashAlgorithm {
32     SHA1,
33     SHA256,
34   };
35 
36   // The set of supported signature algorithms. Extend as required.
37   enum SignatureAlgorithm {
38     RSA_PKCS1_SHA1,
39     RSA_PKCS1_SHA256,
40     ECDSA_SHA256,
41   };
42 
43   SignatureVerifier();
44   ~SignatureVerifier();
45 
46   // Streaming interface:
47 
48   // Initiates a signature verification operation.  This should be followed
49   // by one or more VerifyUpdate calls and a VerifyFinal call.
50   // NOTE: for RSA-PSS signatures, use VerifyInitRSAPSS instead.
51   //
52   // The signature is encoded according to the signature algorithm.
53   //
54   // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo
55   // structure, which contains not only the public key but also its type
56   // (algorithm):
57   //   SubjectPublicKeyInfo  ::=  SEQUENCE  {
58   //       algorithm            AlgorithmIdentifier,
59   //       subjectPublicKey     BIT STRING  }
60   bool VerifyInit(SignatureAlgorithm signature_algorithm,
61                   const uint8_t* signature,
62                   int signature_len,
63                   const uint8_t* public_key_info,
64                   int public_key_info_len);
65 
66   // Initiates a RSA-PSS signature verification operation.  This should be
67   // followed by one or more VerifyUpdate calls and a VerifyFinal call.
68   //
69   // The RSA-PSS signature algorithm parameters are specified with the
70   // |hash_alg|, |mask_hash_alg|, and |salt_len| arguments.
71   //
72   // An RSA-PSS signature is a nonnegative integer encoded as a byte string
73   // (of the same length as the RSA modulus) in big-endian byte order. It
74   // must not be further encoded in an ASN.1 BIT STRING.
75   //
76   // The public key is specified as a DER encoded ASN.1 SubjectPublicKeyInfo
77   // structure, which contains not only the public key but also its type
78   // (algorithm):
79   //   SubjectPublicKeyInfo  ::=  SEQUENCE  {
80   //       algorithm            AlgorithmIdentifier,
81   //       subjectPublicKey     BIT STRING  }
82   bool VerifyInitRSAPSS(HashAlgorithm hash_alg,
83                         HashAlgorithm mask_hash_alg,
84                         int salt_len,
85                         const uint8_t* signature,
86                         int signature_len,
87                         const uint8_t* public_key_info,
88                         int public_key_info_len);
89 
90   // Feeds a piece of the data to the signature verifier.
91   void VerifyUpdate(const uint8_t* data_part, int data_part_len);
92 
93   // Concludes a signature verification operation.  Returns true if the
94   // signature is valid.  Returns false if the signature is invalid or an
95   // error occurred.
96   bool VerifyFinal();
97 
98  private:
99 #if defined(USE_OPENSSL)
100   bool CommonInit(int pkey_type,
101                   const EVP_MD* digest,
102                   const uint8_t* signature,
103                   int signature_len,
104                   const uint8_t* public_key_info,
105                   int public_key_info_len,
106                   EVP_PKEY_CTX** pkey_ctx);
107 #else
108   static SECKEYPublicKey* DecodePublicKeyInfo(const uint8_t* public_key_info,
109                                               int public_key_info_len);
110 #endif
111 
112   void Reset();
113 
114   std::vector<uint8_t> signature_;
115 
116 #if defined(USE_OPENSSL)
117   struct VerifyContext;
118   VerifyContext* verify_context_;
119 #else
120   // Used for all signature types except RSA-PSS.
121   VFYContext* vfy_context_;
122 
123   // Used for RSA-PSS signatures.
124   HashAlgorithm hash_alg_;
125   HashAlgorithm mask_hash_alg_;
126   unsigned int salt_len_;
127   SECKEYPublicKey* public_key_;
128   HASHContext* hash_context_;
129 #endif
130 };
131 
132 }  // namespace crypto
133 
134 #endif  // CRYPTO_SIGNATURE_VERIFIER_H_
135