proxygen
Certificate-inl.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree.
7  */
8 
9 #include <folly/ScopeGuard.h>
11 #include <openssl/x509.h>
12 #include <openssl/x509v3.h>
13 
14 namespace fizz {
15 
16 template <>
17 inline std::vector<SignatureScheme> CertUtils::getSigSchemes<KeyType::P256>() {
19 }
20 
21 template <>
22 inline std::vector<SignatureScheme> CertUtils::getSigSchemes<KeyType::P384>() {
24 }
25 
26 template <>
27 inline std::vector<SignatureScheme> CertUtils::getSigSchemes<KeyType::P521>() {
29 }
30 
31 template <>
32 inline std::vector<SignatureScheme> CertUtils::getSigSchemes<KeyType::RSA>() {
34 }
35 
36 template <KeyType T>
39  std::vector<folly::ssl::X509UniquePtr> certs,
40  const std::vector<std::shared_ptr<fizz::CertificateCompressor>>&
41  compressors) {
42  if (certs.size() == 0) {
43  throw std::runtime_error("Must supply at least 1 cert");
44  }
45  if (X509_check_private_key(certs[0].get(), pkey.get()) != 1) {
46  throw std::runtime_error("Cert does not match private key");
47  }
48  // TODO: more strict validation of chaining requirements.
49  signature_.setKey(std::move(pkey));
50  certs_ = std::move(certs);
51  for (const auto& compressor : compressors) {
52  compressedCerts_[compressor->getAlgorithm()] =
53  compressor->compress(getCertMessage());
54  }
55 }
56 
57 template <KeyType T>
59  return folly::ssl::OpenSSLCertUtils::getCommonName(*certs_.front())
60  .value_or("");
61 }
62 
63 template <KeyType T>
64 std::vector<std::string> SelfCertImpl<T>::getAltIdentities() const {
66 }
67 
68 template <KeyType T>
70  Buf certificateRequestContext) const {
72  certs_, std::move(certificateRequestContext));
73 }
74 
75 template <KeyType T>
78  return CertUtils::cloneCompressedCert(compressedCerts_.at(algo));
79 }
80 
81 template <KeyType T>
82 std::vector<SignatureScheme> SelfCertImpl<T>::getSigSchemes() const {
83  return CertUtils::getSigSchemes<T>();
84 }
85 
86 template <>
88  SignatureScheme scheme,
90  folly::ByteRange toBeSigned) const {
91  auto signData = CertUtils::prepareSignData(context, toBeSigned);
92  switch (scheme) {
93  case SignatureScheme::ecdsa_secp256r1_sha256:
94  return signature_.sign<SignatureScheme::ecdsa_secp256r1_sha256>(
95  signData->coalesce());
96  default:
97  throw std::runtime_error("Unsupported signature scheme");
98  }
99 }
100 
101 template <>
103  SignatureScheme scheme,
105  folly::ByteRange toBeSigned) const {
106  auto signData = CertUtils::prepareSignData(context, toBeSigned);
107  switch (scheme) {
108  case SignatureScheme::ecdsa_secp384r1_sha384:
109  return signature_.sign<SignatureScheme::ecdsa_secp384r1_sha384>(
110  signData->coalesce());
111  default:
112  throw std::runtime_error("Unsupported signature scheme");
113  }
114 }
115 
116 template <>
118  SignatureScheme scheme,
120  folly::ByteRange toBeSigned) const {
121  auto signData = CertUtils::prepareSignData(context, toBeSigned);
122  switch (scheme) {
123  case SignatureScheme::ecdsa_secp521r1_sha512:
124  return signature_.sign<SignatureScheme::ecdsa_secp521r1_sha512>(
125  signData->coalesce());
126  default:
127  throw std::runtime_error("Unsupported signature scheme");
128  }
129 }
130 
131 template <>
133  SignatureScheme scheme,
135  folly::ByteRange toBeSigned) const {
136  auto signData = CertUtils::prepareSignData(context, toBeSigned);
137  switch (scheme) {
138  case SignatureScheme::rsa_pss_sha256:
139  return signature_.sign<SignatureScheme::rsa_pss_sha256>(
140  signData->coalesce());
141  default:
142  throw std::runtime_error("Unsupported signature scheme");
143  }
144 }
145 
146 template <KeyType T>
148  folly::ssl::EvpPkeyUniquePtr key(X509_get_pubkey(cert.get()));
149  if (!key) {
150  throw std::runtime_error("could not get key from cert");
151  }
152  signature_.setKey(std::move(key));
153  cert_ = std::move(cert);
154 }
155 
156 template <KeyType T>
159 }
160 
161 template <>
163  SignatureScheme scheme,
165  folly::ByteRange toBeSigned,
166  folly::ByteRange signature) const {
167  auto signData = CertUtils::prepareSignData(context, toBeSigned);
168  switch (scheme) {
169  case SignatureScheme::ecdsa_secp256r1_sha256:
170  return signature_.verify<SignatureScheme::ecdsa_secp256r1_sha256>(
171  signData->coalesce(), signature);
172  default:
173  throw std::runtime_error("Unsupported signature scheme");
174  }
175 }
176 
177 template <>
179  SignatureScheme scheme,
181  folly::ByteRange toBeSigned,
182  folly::ByteRange signature) const {
183  auto signData = CertUtils::prepareSignData(context, toBeSigned);
184  switch (scheme) {
185  case SignatureScheme::ecdsa_secp384r1_sha384:
186  return signature_.verify<SignatureScheme::ecdsa_secp384r1_sha384>(
187  signData->coalesce(), signature);
188  default:
189  throw std::runtime_error("Unsupported signature scheme");
190  }
191 }
192 
193 template <>
195  SignatureScheme scheme,
197  folly::ByteRange toBeSigned,
198  folly::ByteRange signature) const {
199  auto signData = CertUtils::prepareSignData(context, toBeSigned);
200  switch (scheme) {
201  case SignatureScheme::ecdsa_secp521r1_sha512:
202  return signature_.verify<SignatureScheme::ecdsa_secp521r1_sha512>(
203  signData->coalesce(), signature);
204  default:
205  throw std::runtime_error("Unsupported signature scheme");
206  }
207 }
208 
209 template <>
211  SignatureScheme scheme,
213  folly::ByteRange toBeSigned,
214  folly::ByteRange signature) const {
215  auto signData = CertUtils::prepareSignData(context, toBeSigned);
216  switch (scheme) {
217  case SignatureScheme::rsa_pss_sha256:
218  return signature_.verify<SignatureScheme::rsa_pss_sha256>(
219  signData->coalesce(), signature);
220  default:
221  throw std::runtime_error("Unsupported signature scheme");
222  }
223 }
224 
225 template <KeyType T>
227  X509_up_ref(cert_.get());
228  return folly::ssl::X509UniquePtr(cert_.get());
229 }
230 
231 template <KeyType T>
233  X509_up_ref(certs_.front().get());
234  return folly::ssl::X509UniquePtr(certs_.front().get());
235 }
236 } // namespace fizz
void verify(int extras)
CertificateCompressionAlgorithm
Definition: Types.h:167
std::unique_ptr< X509, X509Deleter > X509UniquePtr
context
Definition: CMakeCache.txt:563
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::vector< SignatureScheme > getSigSchemes() const override
SignatureScheme
Definition: Types.h:257
std::unique_ptr< EVP_PKEY, EvpPkeyDeleter > EvpPkeyUniquePtr
std::vector< std::string > getAltIdentities() const override
SelfCertImpl(folly::ssl::EvpPkeyUniquePtr pkey, std::vector< folly::ssl::X509UniquePtr > certs, const std::vector< std::shared_ptr< fizz::CertificateCompressor >> &compressors={})
static std::vector< std::string > getSubjectAltNames(X509 &x509)
CompressedCertificate getCompressedCert(CertificateCompressionAlgorithm algo) const override
Buf sign(SignatureScheme scheme, CertificateVerifyContext context, folly::ByteRange toBeSigned) const override
CertificateMsg getCertMessage(Buf certificateRequestContext=nullptr) const override
static CertificateMsg getCertMessage(const std::vector< folly::ssl::X509UniquePtr > &certs, Buf certificateRequestContext)
Definition: Certificate.cpp:59
Definition: Actions.h:16
static Optional< std::string > getCommonName(X509 &x509)
CertificateVerifyContext
Definition: Certificate.h:20
FOLLY_CPP14_CONSTEXPR Value value_or(U &&dflt) const &
Definition: Optional.h:330
const char * string
Definition: Conv.cpp:212
std::unique_ptr< folly::IOBuf > Buf
Definition: Types.h:22
static CompressedCertificate cloneCompressedCert(const CompressedCertificate &src)
std::string getIdentity() const override