1 /* 2 * livesig.h 3 * 4 * Implements sign and verify functions using DNSSEC public keys using OpenSSL 5 * if available. 6 * 7 * Supports RSASHA1, and if OpenSSL is compiled with --enable-ec, ECDSAP256* 8 * and ECDSAP384* 9 * 10 * Also supports an OpenSSL less mode, which uses no crypto 11 * (POPT_CONT_INT_PROT_NONE). To use it, compile without -DOPENSSL. In that 12 * case the private key is a 1 random byte and the public key is that byte 13 * repeated SWIFT_CIPM_NONE_KEYLEN times. 14 * 15 * Created by Arno Bakker 16 * Copyright 2013-2016 Vrije Universiteit Amsterdam. All rights reserved. 17 */ 18 #ifndef SWIFT_LIVESIG_H_ 19 #define SWIFT_LIVESIG_H_ 20 21 // Length of fake signature in SIGNED_INTEGRITY when Content Integrity Protection off 22 #define SWIFT_CIPM_NONE_KEYLEN 21 // bytes, must be larger than Sha1Hash::SIZE 23 #define SWIFT_CIPM_NONE_SIGLEN 20 // bytes 24 25 26 #ifdef OPENSSL 27 28 #include <openssl/evp.h> 29 #include <openssl/rand.h> 30 31 #else 32 33 // Dummy funcs, so swift will compile for VOD and live with no CIPM without OpenSSL. 34 // When CIPM is NONE the private key is 1 byte and the public key is that byte 35 // repeated 21 times. 36 // 37 typedef uint8_t EVP_PKEY; 38 typedef int EVP_MD_CTX; 39 #define EVP_PKEY_free(x) 40 #define EVP_PKEY_size(x) SWIFT_CIPM_NONE_SIGLEN 41 42 #endif 43 44 namespace swift 45 { 46 47 // http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xml 48 typedef enum { 49 POPT_LIVE_SIG_ALG_RSASHA1 = 5, 50 POPT_LIVE_SIG_ALG_ECDSAP256SHA256 = 13, 51 POPT_LIVE_SIG_ALG_ECDSAP384SHA384 = 14, 52 POPT_LIVE_SIG_ALG_PRIVATEDNS = 253 53 } popt_live_sig_alg_t; 54 55 56 // Arno, 2013-10-09: Gives nice short SwarmIDs 57 #define DEFAULT_LIVE_SIG_ALG POPT_LIVE_SIG_ALG_ECDSAP256SHA256 58 59 60 /** Structure for holding a signature */ 61 struct Signature { 62 uint8_t *sigbits_; 63 uint16_t siglen_; SignatureSignature64 Signature() : sigbits_(NULL), siglen_(0) {} 65 Signature(uint8_t *sb, uint16_t len); 66 Signature(bool hex, const uint8_t *sb, uint16_t len); 67 Signature(const Signature ©); 68 Signature & operator = (const Signature &source); 69 ~Signature(); bitsSignature70 uint8_t *bits() { 71 return sigbits_; 72 } lengthSignature73 uint16_t length() { 74 return siglen_; 75 } 76 std::string hex() const; 77 78 const static Signature NOSIG; 79 }; 80 81 // Default keysize when using RSASHA1 82 #define SWIFT_RSA_DEFAULT_KEYSIZE 1024 // bits 83 84 85 struct SwarmPubKey; 86 87 // Callback used when generating (RSA) keys, see https://www.openssl.org/docs/crypto/BN_generate_prime.html 88 typedef void (*simple_openssl_callback_t)(int); 89 90 91 /** Public/private (source) or just public key (client) for signing, and verification, resp. */ 92 struct KeyPair { 93 public: KeyPairKeyPair94 KeyPair() { // keep compiler happy 95 alg_ = POPT_LIVE_SIG_ALG_PRIVATEDNS; 96 evp_ = NULL; 97 } KeyPairKeyPair98 KeyPair(popt_live_sig_alg_t alg,EVP_PKEY *evp) { 99 alg_ = alg; 100 evp_ = evp; 101 } ~KeyPairKeyPair102 ~KeyPair() { 103 if (evp_ != NULL) 104 EVP_PKEY_free(evp_); 105 evp_ = NULL; 106 107 } 108 109 /** Create a new key pair, calling callback as the key is generated */ 110 static KeyPair *Generate(popt_live_sig_alg_t alg, uint16_t keysize=SWIFT_RSA_DEFAULT_KEYSIZE, 111 simple_openssl_callback_t callback=NULL); 112 113 /** For testing */ GetEVPKeyPair114 EVP_PKEY *GetEVP() { 115 return evp_; 116 } 117 118 /** Return PPSPP encoded public key = Algorithm byte + DNSSEC encoded public key */ 119 SwarmPubKey *GetSwarmPubKey(); 120 121 /** Returns a Signature with the private key over data */ 122 Signature *Sign(uint8_t *data, uint16_t datalength); 123 124 /** Returns whether the Signature was made by the public key over data */ 125 bool Verify(uint8_t *data, uint16_t datalength,Signature &sig); 126 127 /** Returns the DNSSEC signature algorithm used */ GetSigAlgKeyPair128 popt_live_sig_alg_t GetSigAlg() { 129 return alg_; 130 } 131 132 /** Returns the number of bytes a signature takes on the wire */ 133 uint16_t GetSigSizeInBytes(); 134 135 /** Returns NULL on error. */ 136 static KeyPair *ReadPrivateKey(std::string keypairfilename); 137 /** Returns -1 on error */ 138 int WritePrivateKey(std::string keypairfilename); 139 140 protected: 141 popt_live_sig_alg_t alg_; 142 EVP_PKEY *evp_; 143 }; 144 145 146 /** -08: SwarmID for live streams is an Algorithm Byte followed by a public key 147 * encoded as in a DNSSEC DNSKEY resource record without BASE-64 encoding. 148 */ 149 struct SwarmPubKey { 150 public: SwarmPubKeySwarmPubKey151 SwarmPubKey() : bits_(NULL), len_(0) {} 152 SwarmPubKey(uint8_t *bits, uint16_t len); 153 SwarmPubKey(const SwarmPubKey& copy); 154 SwarmPubKey(std::string hexstr); 155 ~SwarmPubKey(); 156 SwarmPubKey & operator = (const SwarmPubKey &source); 157 bool operator == (const SwarmPubKey& b) const; bitsSwarmPubKey158 uint8_t *bits() { 159 return bits_; 160 } lengthSwarmPubKey161 uint16_t length() { 162 return len_; 163 } 164 std::string hex() const; 165 KeyPair *GetPublicKeyPair() const; 166 167 const static SwarmPubKey NOSPUBKEY; 168 protected: 169 uint8_t *bits_; 170 uint16_t len_; 171 }; 172 173 } 174 175 #endif /* SWIFT_LIVESIG_H_ */ 176