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