proxygen
Utilities.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 #pragma once
10 
12 
13 namespace fizz {
14 namespace test {
15 
16 struct CertAndKey {
19 };
20 
21 template <typename A, typename B>
22 void throwIfNeq(const A& a, const B& b, const std::string& msg) {
23  if (a != b) {
24  throw std::runtime_error(msg);
25  }
26 }
27 
28 template <typename A>
29 void throwIfNull(const A& a, const std::string& msg) {
30  if (a == nullptr) {
31  throw std::runtime_error(msg);
32  }
33 }
34 
36  folly::ssl::EvpPkeyUniquePtr pk(EVP_PKEY_new());
37  throwIfNull(pk, "private key creation failed");
38 
39  folly::ssl::X509UniquePtr crt(X509_new());
40  throwIfNull(crt, "cert creation failed");
41 
43  EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
44  throwIfNull(grp, "group creation failed");
45 
46  EC_GROUP_set_asn1_flag(grp.get(), OPENSSL_EC_NAMED_CURVE);
47  EC_GROUP_set_point_conversion_form(grp.get(), POINT_CONVERSION_UNCOMPRESSED);
48 
49  throwIfNeq(EC_GROUP_check(grp.get(), nullptr), 1, "group check failed");
50 
51  folly::ssl::EcKeyUniquePtr ec(EC_KEY_new());
52  throwIfNull(ec, "ec key creation error");
53 
54  throwIfNeq(EC_KEY_set_group(ec.get(), grp.get()), 1, "failed to set group");
55 
56  throwIfNeq(EC_KEY_generate_key(ec.get()), 1, "ec generation failed");
57 
58  throwIfNeq(
59  EVP_PKEY_set1_EC_KEY(pk.get(), ec.get()),
60  1,
61  "private key assignment failed");
62 
63  X509_set_version(crt.get(), 2);
64  static int serial = 0;
65  ASN1_INTEGER_set(X509_get_serialNumber(crt.get()), serial++);
66  X509_gmtime_adj(X509_get_notBefore(crt.get()), 0);
67  X509_gmtime_adj(X509_get_notAfter(crt.get()), 31536000);
68 
69  throwIfNeq(
70  X509_set_pubkey(crt.get(), pk.get()), 1, "public key assignment failed");
71 
72  X509_NAME* name = X509_get_subject_name(crt.get());
73  const std::vector<std::pair<std::string, std::string>> entries{
74  {"C", "US"}, {"O", "Facebook, Inc."}, {"CN", cn}};
75  for (const auto& entry : entries) {
76  throwIfNeq(
77  X509_NAME_add_entry_by_txt(
78  name,
79  entry.first.c_str(),
80  MBSTRING_ASC,
81  reinterpret_cast<const unsigned char*>(entry.second.c_str()),
82  -1,
83  -1,
84  0),
85  1,
86  std::string("failed to set name entry: ") + entry.first);
87  }
88 
89  if (ca) {
90  X509V3_CTX ctx;
91  X509V3_set_ctx_nodb(&ctx);
92  std::array<char, 8> constraint{"CA:TRUE"};
93  folly::ssl::X509ExtensionUniquePtr ext(X509V3_EXT_conf_nid(
94  nullptr, &ctx, NID_basic_constraints, constraint.data()));
95  throwIfNull(ext, "failed to create extension");
96  throwIfNeq(
97  X509_EXTENSION_set_critical(ext.get(), 1), 1, "failed to set critical");
98  throwIfNeq(
99  X509_add_ext(crt.get(), ext.get(), -1), 1, "failed to add extension");
100  }
101 
102  if (issuer) {
103  throwIfNeq(
104  X509_set_issuer_name(
105  crt.get(), X509_get_subject_name(issuer->cert.get())),
106  1,
107  "failed to set issuer");
108  if (X509_sign(crt.get(), issuer->key.get(), EVP_sha256()) == 0) {
109  throw std::runtime_error("failed to sign certificate");
110  }
111  } else {
112  throwIfNeq(
113  X509_set_issuer_name(crt.get(), name), 1, "failed to set issuer");
114  if (X509_sign(crt.get(), pk.get(), EVP_sha256()) == 0) {
115  throw std::runtime_error("failed to self-sign certificate");
116  }
117  }
118 
119  return {std::move(crt), std::move(pk)};
120 }
121 
122 std::shared_ptr<PeerCert> getPeerCert(const CertAndKey& cert) {
123  return std::make_shared<PeerCertImpl<KeyType::P256>>(
124  folly::ssl::X509UniquePtr(X509_dup(cert.cert.get())));
125 }
126 } // namespace test
127 } // namespace fizz
folly::ssl::EvpPkeyUniquePtr key
Definition: Utilities.h:18
void throwIfNull(const A &a, const std::string &msg)
Definition: Utilities.h:29
std::unique_ptr< int > A
std::unique_ptr< X509, X509Deleter > X509UniquePtr
char b
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
std::unique_ptr< EVP_PKEY, EvpPkeyDeleter > EvpPkeyUniquePtr
std::unique_ptr< EC_KEY, EcKeyDeleter > EcKeyUniquePtr
const char * name
Definition: http_parser.c:437
std::unique_ptr< EC_GROUP, EcGroupDeleter > EcGroupUniquePtr
Definition: Actions.h:16
char a
folly::ssl::X509UniquePtr cert
Definition: Utilities.h:17
std::unique_ptr< X509_EXTENSION, X509ExtensionDeleter > X509ExtensionUniquePtr
std::shared_ptr< PeerCert > getPeerCert(const CertAndKey &cert)
Definition: Utilities.h:122
CertAndKey createCert(std::string cn, bool ca, CertAndKey *issuer)
Definition: Utilities.h:35
const char * string
Definition: Conv.cpp:212
void throwIfNeq(const A &a, const B &b, const std::string &msg)
Definition: Utilities.h:22