Identity.h
1 /* 2 * Copyright (c) 2013-2026, The PurpleI2P Project 3 * 4 * This file is part of Purple i2pd project and licensed under BSD3 5 * 6 * See full license text in LICENSE file at top of project tree 7 */ 8 9 #ifndef IDENTITY_H__ 10 #define IDENTITY_H__ 11 12 #include <inttypes.h> 13 #include <string.h> 14 #include <string> 15 #include <string_view> 16 #include <memory> 17 #include <vector> 18 #include "Base.h" 19 #include "Signature.h" 20 21 namespace i2p 22 { 23 namespace crypto 24 { 25 class CryptoKeyEncryptor; 26 class CryptoKeyDecryptor; 27 } 28 namespace data 29 { 30 typedef Tag<32> IdentHash; 31 inline std::string GetIdentHashAbbreviation (const IdentHash& ident) 32 { 33 return ident.ToBase64 ().substr (0, 4); 34 } 35 36 std::vector<IdentHash> ExtractIdentHashes (std::string_view hashes); 37 38 struct Keys 39 { 40 uint8_t privateKey[256]; 41 uint8_t signingPrivateKey[20]; 42 uint8_t publicKey[256]; 43 uint8_t signingKey[128]; 44 }; 45 46 const uint8_t CERTIFICATE_TYPE_NULL = 0; 47 const uint8_t CERTIFICATE_TYPE_HASHCASH = 1; 48 const uint8_t CERTIFICATE_TYPE_HIDDEN = 2; 49 const uint8_t CERTIFICATE_TYPE_SIGNED = 3; 50 const uint8_t CERTIFICATE_TYPE_MULTIPLE = 4; 51 const uint8_t CERTIFICATE_TYPE_KEY = 5; 52 53 struct Identity 54 { 55 uint8_t publicKey[256]; 56 uint8_t signingKey[128]; 57 uint8_t certificate[3]; // byte 1 - type, bytes 2-3 - length 58 59 Identity () = default; 60 Identity (const Keys& keys) { *this = keys; }; 61 Identity& operator=(const Keys& keys); 62 size_t FromBuffer (const uint8_t * buf, size_t len); 63 IdentHash Hash () const; 64 operator uint8_t * () { return reinterpret_cast<uint8_t *>(this); } 65 operator const uint8_t * () const { return reinterpret_cast<const uint8_t *>(this); } 66 }; 67 68 Keys CreateRandomKeys (); 69 70 const size_t DEFAULT_IDENTITY_SIZE = sizeof (Identity); // 387 bytes 71 72 const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0; 73 const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1; 74 const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD = 4; 75 const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM512_X25519_AEAD = 5; 76 const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM768_X25519_AEAD = 6; 77 const uint16_t CRYPTO_KEY_TYPE_ECIES_MLKEM1024_X25519_AEAD = 7; 78 79 const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0; 80 const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1; 81 const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA384_P384 = 2; 82 const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA512_P521 = 3; 83 const uint16_t SIGNING_KEY_TYPE_RSA_SHA256_2048 = 4; 84 const uint16_t SIGNING_KEY_TYPE_RSA_SHA384_3072 = 5; 85 const uint16_t SIGNING_KEY_TYPE_RSA_SHA512_4096 = 6; 86 const uint16_t SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 = 7; 87 const uint16_t SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph = 8; // since openssl 3.0.0 88 const uint16_t SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256 = 9; 89 const uint16_t SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512 = 10; // approved by FSB 90 const uint16_t SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 = 11; // for LeaseSet2 only 91 const uint16_t SIGNING_KEY_TYPE_MLDSA44 = 12; 92 93 typedef uint16_t SigningKeyType; 94 typedef uint16_t CryptoKeyType; 95 96 const size_t MAX_EXTENDED_BUFFER_SIZE = 8; // cryptoKeyType + signingKeyType + 4 extra bytes of P521 97 class IdentityEx 98 { 99 public: 100 101 IdentityEx (); 102 IdentityEx (const uint8_t * publicKey, const uint8_t * signingKey, 103 SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1, CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL); 104 IdentityEx (const uint8_t * buf, size_t len); 105 IdentityEx (const IdentityEx& other); 106 IdentityEx (const Identity& standard); 107 ~IdentityEx (); 108 IdentityEx& operator=(const IdentityEx& other); 109 IdentityEx& operator=(const Identity& standard); 110 111 size_t FromBuffer (const uint8_t * buf, size_t len); 112 size_t ToBuffer (uint8_t * buf, size_t len) const; 113 size_t FromBase64(std::string_view s); 114 std::string ToBase64 () const; 115 const Identity& GetStandardIdentity () const { return m_StandardIdentity; }; 116 117 const IdentHash& GetIdentHash () const { return m_IdentHash; }; 118 const uint8_t * GetEncryptionPublicKey () const { return m_StandardIdentity.publicKey; }; 119 uint8_t * GetEncryptionPublicKeyBuffer () { return m_StandardIdentity.publicKey; }; 120 std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> CreateEncryptor (const uint8_t * key) const; 121 size_t GetFullLen () const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE; }; 122 size_t GetSigningPublicKeyLen () const; 123 const uint8_t * GetSigningPublicKeyBuffer () const; // returns NULL for P521 124 size_t GetSigningPrivateKeyLen () const; 125 size_t GetSignatureLen () const; 126 bool Verify (const uint8_t * buf, size_t len, const uint8_t * signature) const; 127 SigningKeyType GetSigningKeyType () const; 128 bool IsRSA () const; // signing key type 129 CryptoKeyType GetCryptoKeyType () const; 130 131 bool operator == (const IdentityEx & other) const { return GetIdentHash() == other.GetIdentHash(); } 132 void RecalculateIdentHash(uint8_t * buff=nullptr); 133 134 static i2p::crypto::Verifier * CreateVerifier (SigningKeyType keyType); 135 static std::shared_ptr<i2p::crypto::CryptoKeyEncryptor> CreateEncryptor (CryptoKeyType keyType, const uint8_t * key); 136 137 private: 138 139 void CreateVerifier (); 140 141 private: 142 143 Identity m_StandardIdentity; 144 IdentHash m_IdentHash; 145 std::unique_ptr<i2p::crypto::Verifier> m_Verifier; 146 size_t m_ExtendedLen; 147 union 148 { 149 uint8_t m_ExtendedBuffer[MAX_EXTENDED_BUFFER_SIZE]; 150 uint8_t * m_ExtendedBufferPtr; 151 }; 152 }; 153 154 size_t GetIdentityBufferLen (const uint8_t * buf, size_t len); // return actual identity length in buffer 155 156 class PrivateKeys // for eepsites 157 { 158 public: 159 160 PrivateKeys () = default; 161 PrivateKeys (const PrivateKeys& other) { *this = other; }; 162 PrivateKeys (const Keys& keys) { *this = keys; }; 163 PrivateKeys& operator=(const Keys& keys); 164 PrivateKeys& operator=(const PrivateKeys& other); 165 ~PrivateKeys () = default; 166 167 std::shared_ptr<const IdentityEx> GetPublic () const { return m_Public; }; 168 const uint8_t * GetPrivateKey () const { return m_PrivateKey; }; 169 const uint8_t * GetSigningPrivateKey () const { return m_SigningPrivateKey.data (); }; 170 size_t GetSignatureLen () const; // might not match identity 171 bool IsOfflineSignature () const { return m_TransientSignatureLen > 0; }; 172 uint8_t * GetPadding(); 173 void RecalculateIdentHash(uint8_t * buf=nullptr) { m_Public->RecalculateIdentHash(buf); } 174 void Sign (const uint8_t * buf, int len, uint8_t * signature) const; 175 176 size_t GetFullLen () const; 177 size_t FromBuffer (const uint8_t * buf, size_t len); 178 size_t ToBuffer (uint8_t * buf, size_t len) const; 179 180 size_t FromBase64(std::string_view s); 181 std::string ToBase64 () const; 182 183 std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> CreateDecryptor (const uint8_t * key) const; 184 185 static std::shared_ptr<i2p::crypto::CryptoKeyDecryptor> CreateDecryptor (CryptoKeyType cryptoType, const uint8_t * key); 186 static PrivateKeys CreateRandomKeys (SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1, CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL, bool isDestination = false); 187 static void GenerateSigningKeyPair (SigningKeyType type, uint8_t * priv, uint8_t * pub); 188 static void GenerateCryptoKeyPair (CryptoKeyType type, uint8_t * priv, uint8_t * pub); // priv and pub are 256 bytes long 189 static i2p::crypto::Signer * CreateSigner (SigningKeyType keyType, const uint8_t * priv); 190 191 // offline keys 192 PrivateKeys CreateOfflineKeys (SigningKeyType type, uint32_t expires) const; 193 const std::vector<uint8_t>& GetOfflineSignature () const { return m_OfflineSignature; }; 194 195 private: 196 197 void CreateSigner () const; 198 void CreateSigner (SigningKeyType keyType) const; 199 size_t GetPrivateKeyLen () const; 200 201 private: 202 203 std::shared_ptr<IdentityEx> m_Public; 204 uint8_t m_PrivateKey[256]; 205 std::vector<uint8_t> m_SigningPrivateKey; 206 mutable std::unique_ptr<i2p::crypto::Signer> m_Signer; 207 std::vector<uint8_t> m_OfflineSignature; // non zero length, if applicable 208 size_t m_TransientSignatureLen = 0; 209 size_t m_TransientSigningPrivateKeyLen = 0; 210 }; 211 212 // kademlia 213 struct XORMetric 214 { 215 union 216 { 217 uint8_t metric[32]; 218 uint64_t metric_ll[4]; 219 }; 220 221 void SetMin () { memset (metric, 0, 32); }; 222 void SetMax () { memset (metric, 0xFF, 32); }; 223 bool operator< (const XORMetric& other) const { return memcmp (metric, other.metric, 32) < 0; }; 224 }; 225 226 IdentHash CreateRoutingKey (const IdentHash& ident, bool nextDay = false); 227 XORMetric operator^(const IdentHash& key1, const IdentHash& key2); 228 229 // destination for delivery instructions 230 class RoutingDestination 231 { 232 public: 233 234 RoutingDestination () {}; 235 virtual ~RoutingDestination () {}; 236 237 virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0; 238 virtual void Encrypt (const uint8_t * data, uint8_t * encrypted) const = 0; // encrypt data for 239 virtual bool IsDestination () const = 0; // for garlic 240 241 const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; 242 virtual CryptoKeyType GetEncryptionType () const { return GetIdentity ()->GetCryptoKeyType (); }; // override in LeaseSet2 243 }; 244 245 class LocalDestination 246 { 247 public: 248 249 virtual ~LocalDestination() {}; 250 virtual bool Decrypt (const uint8_t * encrypted, uint8_t * data, CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL) const = 0; 251 virtual std::shared_ptr<const IdentityEx> GetIdentity () const = 0; 252 253 const IdentHash& GetIdentHash () const { return GetIdentity ()->GetIdentHash (); }; 254 virtual bool SupportsEncryptionType (CryptoKeyType keyType) const { return GetIdentity ()->GetCryptoKeyType () == keyType; }; // override for LeaseSet 255 virtual const uint8_t * GetEncryptionPublicKey (CryptoKeyType keyType) const { return GetIdentity ()->GetEncryptionPublicKey (); }; // override for LeaseSet 256 }; 257 } 258 } 259 260 #endif