2020-05-22 16:18:41 +03:00
/*
2021-09-01 01:51:40 +03:00
* Copyright ( c ) 2013 - 2021 , The PurpleI2P Project
2020-05-22 16:18:41 +03:00
*
* This file is part of Purple i2pd project and licensed under BSD3
*
* See full license text in LICENSE file at top of project tree
*/
2013-12-20 07:05:45 +04:00
# ifndef IDENTITY_H__
# define IDENTITY_H__
# include <inttypes.h>
# include <string.h>
2014-07-11 23:39:38 +04:00
# include <string>
2015-04-07 23:02:07 +03:00
# include <memory>
2016-10-10 15:59:45 +03:00
# include <atomic>
2019-02-08 00:04:31 +03:00
# include <vector>
2020-03-31 02:27:10 +03:00
# include <mutex>
2015-11-03 17:15:49 +03:00
# include "Base.h"
2014-08-21 19:15:04 +04:00
# include "Signature.h"
2017-11-07 23:05:22 +03:00
# include "CryptoKey.h"
2013-12-20 07:05:45 +04:00
namespace i2p
{
namespace data
{
2014-07-08 03:22:19 +04:00
typedef Tag < 32 > IdentHash ;
2017-08-07 20:46:42 +03:00
inline std : : string GetIdentHashAbbreviation ( const IdentHash & ident )
{
return ident . ToBase64 ( ) . substr ( 0 , 4 ) ;
2015-11-03 17:15:49 +03:00
}
2014-04-07 22:01:24 +04:00
2013-12-21 05:22:55 +04:00
struct Keys
{
uint8_t privateKey [ 256 ] ;
uint8_t signingPrivateKey [ 20 ] ;
uint8_t publicKey [ 256 ] ;
uint8_t signingKey [ 128 ] ;
} ;
2017-08-07 20:46:42 +03:00
2014-08-06 19:09:06 +04:00
const uint8_t CERTIFICATE_TYPE_NULL = 0 ;
const uint8_t CERTIFICATE_TYPE_HASHCASH = 1 ;
const uint8_t CERTIFICATE_TYPE_HIDDEN = 2 ;
2017-08-07 20:46:42 +03:00
const uint8_t CERTIFICATE_TYPE_SIGNED = 3 ;
const uint8_t CERTIFICATE_TYPE_MULTIPLE = 4 ;
2014-08-06 19:09:06 +04:00
const uint8_t CERTIFICATE_TYPE_KEY = 5 ;
2013-12-20 07:05:45 +04:00
struct Identity
{
uint8_t publicKey [ 256 ] ;
uint8_t signingKey [ 128 ] ;
2016-01-10 01:26:17 +03:00
uint8_t certificate [ 3 ] ; // byte 1 - type, bytes 2-3 - length
2013-12-22 20:29:57 +04:00
2014-08-24 00:06:56 +04:00
Identity ( ) = default ;
Identity ( const Keys & keys ) { * this = keys ; } ;
2013-12-22 20:29:57 +04:00
Identity & operator = ( const Keys & keys ) ;
2014-08-06 19:09:06 +04:00
size_t FromBuffer ( const uint8_t * buf , size_t len ) ;
2014-09-20 03:25:40 +04:00
IdentHash Hash ( ) const ;
2014-10-21 00:57:18 +04:00
} ;
2016-01-10 01:26:17 +03:00
2014-10-21 00:57:18 +04:00
Keys CreateRandomKeys ( ) ;
2017-08-07 20:46:42 +03:00
2014-08-22 05:57:24 +04:00
const size_t DEFAULT_IDENTITY_SIZE = sizeof ( Identity ) ; // 387 bytes
2017-08-07 20:46:42 +03:00
2014-08-24 06:06:53 +04:00
const uint16_t CRYPTO_KEY_TYPE_ELGAMAL = 0 ;
2017-11-13 19:50:17 +03:00
const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC = 1 ;
2020-11-15 02:28:50 +03:00
const uint16_t CRYPTO_KEY_TYPE_ECIES_X25519_AEAD = 4 ;
2017-11-13 19:50:17 +03:00
const uint16_t CRYPTO_KEY_TYPE_ECIES_P256_SHA256_AES256CBC_TEST = 65280 ; // TODO: remove later
2017-11-09 23:01:07 +03:00
const uint16_t CRYPTO_KEY_TYPE_ECIES_GOSTR3410_CRYPTO_PRO_A_SHA256_AES256CBC = 65281 ; // TODO: use GOST R 34.11 instead SHA256 and GOST 28147-89 instead AES
2017-11-02 23:13:10 +03:00
2014-08-24 06:06:53 +04:00
const uint16_t SIGNING_KEY_TYPE_DSA_SHA1 = 0 ;
const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA256_P256 = 1 ;
2014-11-25 04:19:13 +03:00
const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA384_P384 = 2 ;
const uint16_t SIGNING_KEY_TYPE_ECDSA_SHA512_P521 = 3 ;
2014-12-10 23:48:07 +03:00
const uint16_t SIGNING_KEY_TYPE_RSA_SHA256_2048 = 4 ;
const uint16_t SIGNING_KEY_TYPE_RSA_SHA384_3072 = 5 ;
const uint16_t SIGNING_KEY_TYPE_RSA_SHA512_4096 = 6 ;
2015-04-08 23:28:52 +03:00
const uint16_t SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519 = 7 ;
2017-03-31 17:04:39 +03:00
const uint16_t SIGNING_KEY_TYPE_EDDSA_SHA512_ED25519ph = 8 ; // not implemented
2017-03-31 19:26:20 +03:00
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_CRYPTO_PRO_A_GOSTR3411_256 = 9 ;
const uint16_t SIGNING_KEY_TYPE_GOSTR3410_TC26_A_512_GOSTR3411_512 = 10 ; // approved by FSB
2019-02-27 21:18:09 +03:00
const uint16_t SIGNING_KEY_TYPE_REDDSA_SHA512_ED25519 = 11 ; // for LeaseSet2 only
2017-03-31 17:04:39 +03:00
2014-08-24 06:06:53 +04:00
typedef uint16_t SigningKeyType ;
2017-08-07 20:46:42 +03:00
typedef uint16_t CryptoKeyType ;
2021-11-27 23:30:35 +03:00
const size_t MAX_EXTENDED_BUFFER_SIZE = 8 ; // cryptoKeyType + signingKeyType + 4 extra bytes of P521
2014-08-22 05:57:24 +04:00
class IdentityEx
2021-11-27 23:30:35 +03:00
{
2014-08-22 05:57:24 +04:00
public :
IdentityEx ( ) ;
2014-08-24 06:06:53 +04:00
IdentityEx ( const uint8_t * publicKey , const uint8_t * signingKey ,
2017-11-02 23:13:10 +03:00
SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1 , CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL ) ;
2014-08-22 05:57:24 +04:00
IdentityEx ( const uint8_t * buf , size_t len ) ;
IdentityEx ( const IdentityEx & other ) ;
2015-11-03 17:15:49 +03:00
IdentityEx ( const Identity & standard ) ;
2014-08-22 05:57:24 +04:00
~ IdentityEx ( ) ;
IdentityEx & operator = ( const IdentityEx & other ) ;
2014-08-23 07:02:48 +04:00
IdentityEx & operator = ( const Identity & standard ) ;
2014-09-20 03:25:40 +04:00
2014-08-22 05:57:24 +04:00
size_t FromBuffer ( const uint8_t * buf , size_t len ) ;
2014-08-23 07:02:48 +04:00
size_t ToBuffer ( uint8_t * buf , size_t len ) const ;
2014-12-01 22:50:10 +03:00
size_t FromBase64 ( const std : : string & s ) ;
std : : string ToBase64 ( ) const ;
2019-01-02 01:00:37 +03:00
const Identity & GetStandardIdentity ( ) const { return m_StandardIdentity ; } ;
2017-08-07 20:46:42 +03:00
2014-08-22 05:57:24 +04:00
const IdentHash & GetIdentHash ( ) const { return m_IdentHash ; } ;
2019-01-02 01:00:37 +03:00
const uint8_t * GetEncryptionPublicKey ( ) const { return m_StandardIdentity . publicKey ; } ;
uint8_t * GetEncryptionPublicKeyBuffer ( ) { return m_StandardIdentity . publicKey ; } ;
2018-01-06 06:48:51 +03:00
std : : shared_ptr < i2p : : crypto : : CryptoKeyEncryptor > CreateEncryptor ( const uint8_t * key ) const ;
2014-08-22 05:57:24 +04:00
size_t GetFullLen ( ) const { return m_ExtendedLen + DEFAULT_IDENTITY_SIZE ; } ;
2014-08-23 07:02:48 +04:00
size_t GetSigningPublicKeyLen ( ) const ;
2019-03-05 20:41:01 +03:00
const uint8_t * GetSigningPublicKeyBuffer ( ) const ; // returns NULL for P521
2014-12-11 05:31:06 +03:00
size_t GetSigningPrivateKeyLen ( ) const ;
2014-08-23 07:02:48 +04:00
size_t GetSignatureLen ( ) const ;
2014-08-23 16:41:06 +04:00
bool Verify ( const uint8_t * buf , size_t len , const uint8_t * signature ) const ;
2014-08-24 06:06:53 +04:00
SigningKeyType GetSigningKeyType ( ) const ;
2017-11-28 19:33:51 +03:00
bool IsRSA ( ) const ; // signing key type
2014-11-25 04:19:13 +03:00
CryptoKeyType GetCryptoKeyType ( ) const ;
2017-08-07 20:46:42 +03:00
void DropVerifier ( ) const ; // to save memory
2014-11-26 18:28:06 +03:00
2022-05-20 19:56:05 +03:00
bool operator = = ( const IdentityEx & other ) const { return GetIdentHash ( ) = = other . GetIdentHash ( ) ; }
2019-01-02 01:00:37 +03:00
void RecalculateIdentHash ( uint8_t * buff = nullptr ) ;
2017-08-07 20:46:42 +03:00
2019-01-09 20:47:47 +03:00
static i2p : : crypto : : Verifier * CreateVerifier ( SigningKeyType keyType ) ;
2020-03-01 13:25:50 +03:00
static std : : shared_ptr < i2p : : crypto : : CryptoKeyEncryptor > CreateEncryptor ( CryptoKeyType keyType , const uint8_t * key ) ;
2019-01-09 20:47:47 +03:00
2014-08-22 05:57:24 +04:00
private :
2014-11-20 20:21:27 +03:00
void CreateVerifier ( ) const ;
2016-04-07 04:02:58 +03:00
void UpdateVerifier ( i2p : : crypto : : Verifier * verifier ) const ;
2017-08-07 20:46:42 +03:00
2014-08-22 05:57:24 +04:00
private :
Identity m_StandardIdentity ;
IdentHash m_IdentHash ;
2020-03-31 02:27:10 +03:00
mutable i2p : : crypto : : Verifier * m_Verifier = nullptr ;
mutable std : : mutex m_VerifierMutex ;
2014-08-22 05:57:24 +04:00
size_t m_ExtendedLen ;
2021-11-27 23:30:35 +03:00
uint8_t m_ExtendedBuffer [ MAX_EXTENDED_BUFFER_SIZE ] ;
2017-08-07 20:46:42 +03:00
} ;
2014-08-24 00:06:56 +04:00
class PrivateKeys // for eepsites
2014-03-20 00:38:55 +04:00
{
2014-08-24 00:06:56 +04:00
public :
2017-08-07 20:46:42 +03:00
2015-11-03 17:15:49 +03:00
PrivateKeys ( ) = default ;
PrivateKeys ( const PrivateKeys & other ) { * this = other ; } ;
PrivateKeys ( const Keys & keys ) { * this = keys ; } ;
2014-08-24 00:06:56 +04:00
PrivateKeys & operator = ( const Keys & keys ) ;
2014-08-24 06:54:08 +04:00
PrivateKeys & operator = ( const PrivateKeys & other ) ;
2015-11-03 17:15:49 +03:00
~ PrivateKeys ( ) = default ;
2017-08-07 20:46:42 +03:00
2015-11-03 17:15:49 +03:00
std : : shared_ptr < const IdentityEx > GetPublic ( ) const { return m_Public ; } ;
2014-08-24 00:06:56 +04:00
const uint8_t * GetPrivateKey ( ) const { return m_PrivateKey ; } ;
const uint8_t * GetSigningPrivateKey ( ) const { return m_SigningPrivateKey ; } ;
2019-02-08 00:04:31 +03:00
size_t GetSignatureLen ( ) const ; // might not match identity
2019-02-08 20:19:51 +03:00
bool IsOfflineSignature ( ) const { return m_TransientSignatureLen > 0 ; } ;
2020-03-01 13:25:50 +03:00
uint8_t * GetPadding ( ) ;
2019-02-08 00:04:31 +03:00
void RecalculateIdentHash ( uint8_t * buf = nullptr ) { m_Public - > RecalculateIdentHash ( buf ) ; }
2014-08-24 06:54:08 +04:00
void Sign ( const uint8_t * buf , int len , uint8_t * signature ) const ;
2014-08-26 22:56:00 +04:00
2019-02-08 20:19:51 +03:00
size_t GetFullLen ( ) const ;
2014-08-24 00:06:56 +04:00
size_t FromBuffer ( const uint8_t * buf , size_t len ) ;
size_t ToBuffer ( uint8_t * buf , size_t len ) const ;
2014-08-24 06:06:53 +04:00
2014-12-01 22:50:10 +03:00
size_t FromBase64 ( const std : : string & s ) ;
std : : string ToBase64 ( ) const ;
2017-11-07 23:05:22 +03:00
std : : shared_ptr < i2p : : crypto : : CryptoKeyDecryptor > CreateDecryptor ( const uint8_t * key ) const ;
2017-11-08 21:49:48 +03:00
static std : : shared_ptr < i2p : : crypto : : CryptoKeyDecryptor > CreateDecryptor ( CryptoKeyType cryptoType , const uint8_t * key ) ;
2017-11-02 23:13:10 +03:00
static PrivateKeys CreateRandomKeys ( SigningKeyType type = SIGNING_KEY_TYPE_DSA_SHA1 , CryptoKeyType cryptoType = CRYPTO_KEY_TYPE_ELGAMAL ) ;
2020-03-01 13:25:50 +03:00
static void GenerateSigningKeyPair ( SigningKeyType type , uint8_t * priv , uint8_t * pub ) ;
2017-11-02 23:13:10 +03:00
static void GenerateCryptoKeyPair ( CryptoKeyType type , uint8_t * priv , uint8_t * pub ) ; // priv and pub are 256 bytes long
2019-04-05 23:03:58 +03:00
static i2p : : crypto : : Signer * CreateSigner ( SigningKeyType keyType , const uint8_t * priv ) ;
2017-08-07 20:46:42 +03:00
2019-02-12 22:56:39 +03:00
// offline keys
2020-03-01 13:25:50 +03:00
PrivateKeys CreateOfflineKeys ( SigningKeyType type , uint32_t expires ) const ;
2019-02-20 20:36:05 +03:00
const std : : vector < uint8_t > & GetOfflineSignature ( ) const { return m_OfflineSignature ; } ;
2019-02-08 20:19:51 +03:00
2014-08-24 06:54:08 +04:00
private :
2016-07-25 16:57:35 +03:00
void CreateSigner ( ) const ;
2019-02-08 00:04:31 +03:00
void CreateSigner ( SigningKeyType keyType ) const ;
2020-10-30 01:41:21 +03:00
size_t GetPrivateKeyLen ( ) const ;
2017-08-07 20:46:42 +03:00
2014-08-24 00:06:56 +04:00
private :
2015-11-03 17:15:49 +03:00
std : : shared_ptr < IdentityEx > m_Public ;
2014-08-24 00:06:56 +04:00
uint8_t m_PrivateKey [ 256 ] ;
2019-02-08 00:04:31 +03:00
uint8_t m_SigningPrivateKey [ 128 ] ; // assume private key doesn't exceed 128 bytes
2016-07-25 16:57:35 +03:00
mutable std : : unique_ptr < i2p : : crypto : : Signer > m_Signer ;
2019-02-08 00:04:31 +03:00
std : : vector < uint8_t > m_OfflineSignature ; // non zero length, if applicable
2019-02-08 20:19:51 +03:00
size_t m_TransientSignatureLen = 0 ;
size_t m_TransientSigningPrivateKeyLen = 0 ;
2014-03-20 00:38:55 +04:00
} ;
2014-01-04 06:24:20 +04:00
// kademlia
struct XORMetric
{
2014-06-04 03:57:42 +04:00
union
2017-08-07 20:46:42 +03:00
{
2014-06-04 03:57:42 +04:00
uint8_t metric [ 32 ] ;
2017-08-07 20:46:42 +03:00
uint64_t metric_ll [ 4 ] ;
} ;
2014-01-04 06:24:20 +04:00
void SetMin ( ) { memset ( metric , 0 , 32 ) ; } ;
void SetMax ( ) { memset ( metric , 0xFF , 32 ) ; } ;
bool operator < ( const XORMetric & other ) const { return memcmp ( metric , other . metric , 32 ) < 0 ; } ;
2017-08-07 20:46:42 +03:00
} ;
2014-01-04 06:24:20 +04:00
2014-10-14 18:41:40 +04:00
IdentHash CreateRoutingKey ( const IdentHash & ident ) ;
2017-08-07 20:46:42 +03:00
XORMetric operator ^ ( const IdentHash & key1 , const IdentHash & key2 ) ;
2020-03-01 13:25:50 +03:00
// destination for delivery instructions
2013-12-20 07:05:45 +04:00
class RoutingDestination
{
public :
2014-02-21 05:28:41 +04:00
2015-04-07 23:02:07 +03:00
RoutingDestination ( ) { } ;
virtual ~ RoutingDestination ( ) { } ;
2017-08-07 20:46:42 +03:00
2022-05-20 19:56:05 +03:00
virtual std : : shared_ptr < const IdentityEx > GetIdentity ( ) const = 0 ;
2021-09-01 01:51:40 +03:00
virtual void Encrypt ( const uint8_t * data , uint8_t * encrypted ) const = 0 ; // encrypt data for
2017-08-07 20:46:42 +03:00
virtual bool IsDestination ( ) const = 0 ; // for garlic
2017-11-02 21:50:57 +03:00
const IdentHash & GetIdentHash ( ) const { return GetIdentity ( ) - > GetIdentHash ( ) ; } ;
2019-12-19 23:59:15 +03:00
virtual CryptoKeyType GetEncryptionType ( ) const { return GetIdentity ( ) - > GetCryptoKeyType ( ) ; } ; // override in LeaseSet2
2017-08-07 20:46:42 +03:00
} ;
2014-03-14 23:13:34 +04:00
2017-08-07 20:46:42 +03:00
class LocalDestination
2014-03-14 23:13:34 +04:00
{
public :
2014-04-08 21:01:14 +04:00
virtual ~ LocalDestination ( ) { } ;
2021-09-01 01:51:40 +03:00
virtual bool Decrypt ( const uint8_t * encrypted , uint8_t * data , CryptoKeyType preferredCrypto = CRYPTO_KEY_TYPE_ELGAMAL ) const = 0 ;
2016-05-26 21:54:33 +03:00
virtual std : : shared_ptr < const IdentityEx > GetIdentity ( ) const = 0 ;
2014-08-26 06:47:12 +04:00
2017-08-07 20:46:42 +03:00
const IdentHash & GetIdentHash ( ) const { return GetIdentity ( ) - > GetIdentHash ( ) ; } ;
2020-03-20 01:33:42 +03:00
virtual bool SupportsEncryptionType ( CryptoKeyType keyType ) const { return GetIdentity ( ) - > GetCryptoKeyType ( ) = = keyType ; } ; // override for LeaseSet
virtual const uint8_t * GetEncryptionPublicKey ( CryptoKeyType keyType ) const { return GetIdentity ( ) - > GetEncryptionPublicKey ( ) ; } ; // override for LeaseSet
2017-08-07 20:46:42 +03:00
} ;
2013-12-20 07:05:45 +04:00
}
}
# endif