userver: userver/crypto/verifiers.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
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