userver: userver/crypto/verifiers.hpp Source File
Loading...
Searching...
No Matches
verifiers.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/crypto/verifiers.hpp
4/// @brief Digital signature verifiers
5/// @ingroup userver_universal
6
7#include <initializer_list>
8#include <memory>
9#include <string>
10#include <string_view>
11
12#include <userver/crypto/basic_types.hpp>
13#include <userver/crypto/certificate.hpp>
14#include <userver/crypto/exception.hpp>
15#include <userver/crypto/public_key.hpp>
16#include <userver/utils/flags.hpp>
17
18USERVER_NAMESPACE_BEGIN
19
20namespace crypto {
21
22/// Base verifier class
23class Verifier : public NamedAlgo {
24 public:
25 explicit Verifier(const std::string& name);
26 ~Verifier() override;
27
28 /// Verifies a signature against the message
29 virtual void Verify(std::initializer_list<std::string_view> data,
30 std::string_view raw_signature) const = 0;
31};
32
33/// "none" algorithm verifier
34class VerifierNone final : public Verifier {
35 public:
36 VerifierNone();
37
38 /// Verifies a signature against the message
39 void Verify(std::initializer_list<std::string_view> data,
40 std::string_view raw_signature) const override;
41};
42
43/// HMAC-SHA verifier
44template <DigestSize bits>
45class HmacShaVerifier final : public Verifier {
46 public:
47 /// Constructor from a shared secret
48 explicit HmacShaVerifier(std::string secret);
49 ~HmacShaVerifier() override;
50
51 /// Verifies a signature against the message
52 void Verify(std::initializer_list<std::string_view> data,
53 std::string_view raw_signature) const override;
54
55 private:
56 std::string secret_;
57};
58
59/// @name Verifies HMAC SHA MAC.
60/// @{
61using VerifierHs1 = HmacShaVerifier<DigestSize::k160>;
62using VerifierHs256 = HmacShaVerifier<DigestSize::k256>;
63using VerifierHs384 = HmacShaVerifier<DigestSize::k384>;
64using VerifierHs512 = HmacShaVerifier<DigestSize::k512>;
65/// @}
66
67/// Generic verifier for asymmetric cryptography
68template <DsaType type, DigestSize bits>
69class DsaVerifier final : public Verifier {
70 public:
71 /// Constructor from public key
72 explicit DsaVerifier(PublicKey pubkey);
73
74 /// Constructor from a PEM-encoded public key or a X509 certificate
75 explicit DsaVerifier(std::string_view pubkey);
76
77 /// Verifies a signature against the message
78 void Verify(std::initializer_list<std::string_view> data,
79 std::string_view raw_signature) const override;
80
81 /// Verifies a signature against the message digest.
82 ///
83 /// Not available for RSASSA-PSS.
84 /// @warning Do not use this function when the raw message is available!
85 void VerifyDigest(std::string_view digest,
86 std::string_view raw_signature) const;
87
88 private:
89 PublicKey pkey_;
90};
91
92/// @name Verifies RSASSA signature using SHA-2 and PKCS1 padding.
93/// @{
94using VerifierRs256 = DsaVerifier<DsaType::kRsa, DigestSize::k256>;
95using VerifierRs384 = DsaVerifier<DsaType::kRsa, DigestSize::k384>;
96using VerifierRs512 = DsaVerifier<DsaType::kRsa, DigestSize::k512>;
97/// @}
98
99/// @name Verifies ECDSA as per RFC7518.
100///
101/// OpenSSL generates ECDSA signatures in ASN.1/DER format, RFC7518 specifies
102/// signature as a concatenation of zero-padded big-endian `(R, S)` values.
103/// @{
104using VerifierEs256 = DsaVerifier<DsaType::kEc, DigestSize::k256>;
105using VerifierEs384 = DsaVerifier<DsaType::kEc, DigestSize::k384>;
106using VerifierEs512 = DsaVerifier<DsaType::kEc, DigestSize::k512>;
107/// @}
108
109/// @name Verifies RSASSA signature using SHA-2 and PSS padding as per RFC7518.
110///
111/// JWA specifications require using MGF1 function with the same hash function
112/// as for the digest and salt length to be the same size as the hash output.
113/// @{
114using VerifierPs256 = DsaVerifier<DsaType::kRsaPss, DigestSize::k256>;
115using VerifierPs384 = DsaVerifier<DsaType::kRsaPss, DigestSize::k384>;
116using VerifierPs512 = DsaVerifier<DsaType::kRsaPss, DigestSize::k512>;
117/// @}
118
119/// @name CMS verifier per RFC 5652
120class CmsVerifier final : public NamedAlgo {
121 public:
122 /// Verifier flags
123 enum class Flags {
124 kNone = 0x0,
125 /// If set the signing certificate is not verified.
126 kNoSignerCertVerify = 0x20,
127 };
128
129 /// Input encoding
130 enum class InForm { kDer, kPem, kSMime };
131
132 /// Constructor from certificate
134
135 ~CmsVerifier() override;
136
137 /// Verifies a CMS signed message as specified by flags
138 void Verify(std::initializer_list<std::string_view> data,
139 utils::Flags<Flags> flags, InForm in_form) const;
140
141 private:
142 Certificate cert_;
143};
144
145namespace weak {
146
147/// Verifies RSASSA signature using SHA-1 and PKCS1 padding.
148using VerifierRs1 = DsaVerifier<DsaType::kRsa, DigestSize::k160>;
149
150/// Verifies RSASSA signature using SHA-1 and PSS padding.
151///
152/// JWA specifications require using MGF1 function with the same hash function
153/// as for the digest and salt length to be the same size as the hash output.
154using VerifierPs1 = DsaVerifier<DsaType::kRsaPss, DigestSize::k160>;
155
156} // namespace weak
157} // namespace crypto
158
159USERVER_NAMESPACE_END