Aktualizr
C++ SOTA Client
crypto.h
1 #ifndef CRYPTO_H_
2 #define CRYPTO_H_
3 
4 #include <openssl/engine.h>
5 #include <openssl/err.h>
6 #include <openssl/evp.h>
7 #include <openssl/opensslv.h>
8 #include <openssl/pem.h>
9 #include <openssl/pkcs12.h>
10 #include <openssl/rand.h>
11 #include <openssl/rsa.h>
12 #include <sodium.h>
13 #include <boost/algorithm/hex.hpp>
14 #include <boost/algorithm/string.hpp>
15 #include <boost/algorithm/string/case_conv.hpp>
16 
17 #include <string>
18 #include <utility>
19 
20 #include "utilities/types.h"
21 #include "utilities/utils.h"
22 
23 // some older versions of openssl have BIO_new_mem_buf defined with fisrt parameter of type (void*)
24 // which is not true and breaks our build
25 #undef BIO_new_mem_buf
26 BIO *BIO_new_mem_buf(const void *, int);
27 
28 class PublicKey {
29  public:
30  PublicKey() = default;
31  explicit PublicKey(const boost::filesystem::path &path);
32 
33  explicit PublicKey(Json::Value uptane_json);
34 
35  PublicKey(std::string value, KeyType type);
36 
37  std::string Value() const { return value_; }
38 
39  KeyType Type() const { return type_; }
40  /**
41  * Verify a signature using this public key
42  */
43  bool VerifySignature(const std::string &signature, const std::string &message) const;
44  /**
45  * Uptane Json representation of this public key. Used in root.json
46  * and during provisioning.
47  */
48  Json::Value ToUptane() const;
49 
50  std::string KeyId() const;
51  bool operator==(const PublicKey &rhs) const;
52 
53  bool operator!=(const PublicKey &rhs) const { return !(*this == rhs); }
54 
55  private:
56  // std::string can be implicitly converted to a Json::Value. Make sure that
57  // the Json::Value constructor is not called accidentally.
58  PublicKey(std::string);
59  std::string value_;
60  KeyType type_{KeyType::kUnknown};
61 };
62 
64  public:
65  virtual void update(const unsigned char *part, uint64_t size) = 0;
66  virtual std::string getHexDigest() = 0;
67  virtual ~MultiPartHasher() = default;
68 };
69 
71  public:
72  MultiPartSHA512Hasher() { crypto_hash_sha512_init(&state_); }
73  ~MultiPartSHA512Hasher() override = default;
74  void update(const unsigned char *part, uint64_t size) override { crypto_hash_sha512_update(&state_, part, size); }
75  std::string getHexDigest() override {
76  unsigned char sha512_hash[crypto_hash_sha512_BYTES];
77  crypto_hash_sha512_final(&state_, static_cast<unsigned char *>(sha512_hash));
78  return boost::algorithm::hex(std::string(reinterpret_cast<char *>(sha512_hash), crypto_hash_sha512_BYTES));
79  }
80 
81  private:
82  crypto_hash_sha512_state state_{};
83 };
84 
86  public:
87  MultiPartSHA256Hasher() { crypto_hash_sha256_init(&state_); }
88  ~MultiPartSHA256Hasher() override = default;
89  void update(const unsigned char *part, uint64_t size) override { crypto_hash_sha256_update(&state_, part, size); }
90  std::string getHexDigest() override {
91  unsigned char sha256_hash[crypto_hash_sha256_BYTES];
92  crypto_hash_sha256_final(&state_, static_cast<unsigned char *>(sha256_hash));
93  return boost::algorithm::hex(std::string(reinterpret_cast<char *>(sha256_hash), crypto_hash_sha256_BYTES));
94  }
95 
96  private:
97  crypto_hash_sha256_state state_{};
98 };
99 
100 class Crypto {
101  public:
102  static std::string sha256digest(const std::string &text);
103  static std::string sha512digest(const std::string &text);
104  static std::string RSAPSSSign(ENGINE *engine, const std::string &private_key, const std::string &message);
105  static std::string Sign(KeyType key_type, ENGINE *engine, const std::string &private_key, const std::string &message);
106  static std::string ED25519Sign(const std::string &private_key, const std::string &message);
107  static bool parseP12(BIO *p12_bio, const std::string &p12_password, std::string *out_pkey, std::string *out_cert,
108  std::string *out_ca);
109  static bool extractSubjectCN(const std::string &cert, std::string *cn);
110  static bool generateRSAKeyPair(KeyType key_type, std::string *public_key, std::string *private_key);
111  static bool generateEDKeyPair(std::string *public_key, std::string *private_key);
112  static bool generateKeyPair(KeyType key_type, std::string *public_key, std::string *private_key);
113 
114  static bool RSAPSSVerify(const std::string &public_key, const std::string &signature, const std::string &message);
115  static bool ED25519Verify(const std::string &public_key, const std::string &signature, const std::string &message);
116 
117  static bool IsRsaKeyType(KeyType type);
118  static KeyType IdentifyRSAKeyType(const std::string &public_key_pem);
119 };
120 
121 #endif // CRYPTO_H_
Json::Value ToUptane() const
Uptane Json representation of this public key.
Definition: crypto.cc:72
Definition: crypto.h:100
bool VerifySignature(const std::string &signature, const std::string &message) const
Verify a signature using this public key.
Definition: crypto.cc:58
static bool generateRSAKeyPair(KeyType key_type, std::string *public_key, std::string *private_key)
Generate a RSA keypair.
Definition: crypto.cc:331