restore sanity checks
This commit is contained in:
@@ -940,6 +940,19 @@ public:
|
|||||||
/*! \note This function can be used to create a public key from a private key. */
|
/*! \note This function can be used to create a public key from a private key. */
|
||||||
virtual void AssignFrom(const NameValuePairs &source) =0;
|
virtual void AssignFrom(const NameValuePairs &source) =0;
|
||||||
|
|
||||||
|
//! check this object for errors
|
||||||
|
/*! \param level denotes the level of thoroughness:
|
||||||
|
0 - using this object won't cause a crash or exception (rng is ignored)
|
||||||
|
1 - this object will probably function (encrypt, sign, etc.) correctly (but may not check for weak keys and such)
|
||||||
|
2 - make sure this object will function correctly, and do reasonable security checks
|
||||||
|
3 - do checks that may take a long time
|
||||||
|
\return true if the tests pass */
|
||||||
|
virtual bool Validate(RandomNumberGenerator &rng, unsigned int level) const =0;
|
||||||
|
|
||||||
|
//! throws InvalidMaterial if this object fails Validate() test
|
||||||
|
virtual void ThrowIfInvalid(RandomNumberGenerator &rng, unsigned int level) const
|
||||||
|
{if (!Validate(rng, level)) throw InvalidMaterial("CryptoMaterial: this object contains invalid values");}
|
||||||
|
|
||||||
// virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false);
|
// virtual std::vector<std::string> GetSupportedFormats(bool includeSaveOnly=false, bool includeLoadOnly=false);
|
||||||
|
|
||||||
//! save key into a BufferedTransformation
|
//! save key into a BufferedTransformation
|
||||||
@@ -967,6 +980,9 @@ public:
|
|||||||
//! save precomputation for later use
|
//! save precomputation for later use
|
||||||
virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
|
virtual void SavePrecomputation(BufferedTransformation &storedPrecomputation) const
|
||||||
{assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
|
{assert(!SupportsPrecomputation()); throw NotImplemented("CryptoMaterial: this object does not support precomputation");}
|
||||||
|
|
||||||
|
// for internal library use
|
||||||
|
void DoQuickSanityCheck() const {ThrowIfInvalid(NullRNG(), 0);}
|
||||||
};
|
};
|
||||||
|
|
||||||
//! interface for generatable crypto material, such as private keys and crypto parameters
|
//! interface for generatable crypto material, such as private keys and crypto parameters
|
||||||
@@ -1045,18 +1061,6 @@ public:
|
|||||||
virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();}
|
virtual const PrivateKey & GetPrivateKey() const {return const_cast<PrivateKeyAlgorithm *>(this)->AccessPrivateKey();}
|
||||||
};
|
};
|
||||||
|
|
||||||
//! interface for key agreement algorithms
|
|
||||||
|
|
||||||
class KeyAgreementAlgorithm : public AsymmetricAlgorithm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CryptoMaterial & AccessMaterial() {return AccessCryptoParameters();}
|
|
||||||
const CryptoMaterial & GetMaterial() const {return GetCryptoParameters();}
|
|
||||||
|
|
||||||
virtual CryptoParameters & AccessCryptoParameters() =0;
|
|
||||||
virtual const CryptoParameters & GetCryptoParameters() const {return const_cast<KeyAgreementAlgorithm *>(this)->AccessCryptoParameters();}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! interface for public-key encryptors and decryptors
|
//! interface for public-key encryptors and decryptors
|
||||||
|
|
||||||
/*! This class provides an interface common to encryptors and decryptors
|
/*! This class provides an interface common to encryptors and decryptors
|
||||||
@@ -1313,206 +1317,8 @@ public:
|
|||||||
const byte *signature, unsigned int signatureLength) const;
|
const byte *signature, unsigned int signatureLength) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
//! interface for domains of simple key agreement protocols
|
|
||||||
|
|
||||||
/*! A key agreement domain is a set of parameters that must be shared
|
|
||||||
by two parties in a key agreement protocol, along with the algorithms
|
|
||||||
for generating key pairs and deriving agreed values.
|
|
||||||
*/
|
|
||||||
class SimpleKeyAgreementDomain : public KeyAgreementAlgorithm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! return length of agreed value produced
|
|
||||||
virtual unsigned int AgreedValueLength() const =0;
|
|
||||||
//! return length of private keys in this domain
|
|
||||||
virtual unsigned int PrivateKeyLength() const =0;
|
|
||||||
//! return length of public keys in this domain
|
|
||||||
virtual unsigned int PublicKeyLength() const =0;
|
|
||||||
//! generate private key
|
|
||||||
/*! \pre size of privateKey == PrivateKeyLength() */
|
|
||||||
virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
|
|
||||||
//! generate public key
|
|
||||||
/*! \pre size of publicKey == PublicKeyLength() */
|
|
||||||
virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
|
|
||||||
//! generate private/public key pair
|
|
||||||
/*! \note equivalent to calling GeneratePrivateKey() and then GeneratePublicKey() */
|
|
||||||
virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
|
|
||||||
//! derive agreed value from your private key and couterparty's public key, return false in case of failure
|
|
||||||
/*! \note If you have previously validated the public key, use validateOtherPublicKey=false to save time.
|
|
||||||
\pre size of agreedValue == AgreedValueLength()
|
|
||||||
\pre length of privateKey == PrivateKeyLength()
|
|
||||||
\pre length of otherPublicKey == PublicKeyLength()
|
|
||||||
*/
|
|
||||||
virtual bool Agree(byte *agreedValue, const byte *privateKey, const byte *otherPublicKey, bool validateOtherPublicKey=true) const =0;
|
|
||||||
|
|
||||||
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
|
|
||||||
bool ValidateDomainParameters(RandomNumberGenerator &rng) const
|
|
||||||
{return GetCryptoParameters().Validate(rng, 2);}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
//! interface for domains of authenticated key agreement protocols
|
//! interface for domains of authenticated key agreement protocols
|
||||||
|
|
||||||
/*! In an authenticated key agreement protocol, each party has two
|
|
||||||
key pairs. The long-lived key pair is called the static key pair,
|
|
||||||
and the short-lived key pair is called the ephemeral key pair.
|
|
||||||
*/
|
|
||||||
class AuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! return length of agreed value produced
|
|
||||||
virtual unsigned int AgreedValueLength() const =0;
|
|
||||||
|
|
||||||
//! return length of static private keys in this domain
|
|
||||||
virtual unsigned int StaticPrivateKeyLength() const =0;
|
|
||||||
//! return length of static public keys in this domain
|
|
||||||
virtual unsigned int StaticPublicKeyLength() const =0;
|
|
||||||
//! generate static private key
|
|
||||||
/*! \pre size of privateKey == PrivateStaticKeyLength() */
|
|
||||||
virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
|
|
||||||
//! generate static public key
|
|
||||||
/*! \pre size of publicKey == PublicStaticKeyLength() */
|
|
||||||
virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
|
|
||||||
//! generate private/public key pair
|
|
||||||
/*! \note equivalent to calling GenerateStaticPrivateKey() and then GenerateStaticPublicKey() */
|
|
||||||
virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
|
|
||||||
|
|
||||||
//! return length of ephemeral private keys in this domain
|
|
||||||
virtual unsigned int EphemeralPrivateKeyLength() const =0;
|
|
||||||
//! return length of ephemeral public keys in this domain
|
|
||||||
virtual unsigned int EphemeralPublicKeyLength() const =0;
|
|
||||||
//! generate ephemeral private key
|
|
||||||
/*! \pre size of privateKey == PrivateEphemeralKeyLength() */
|
|
||||||
virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0;
|
|
||||||
//! generate ephemeral public key
|
|
||||||
/*! \pre size of publicKey == PublicEphemeralKeyLength() */
|
|
||||||
virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0;
|
|
||||||
//! generate private/public key pair
|
|
||||||
/*! \note equivalent to calling GenerateEphemeralPrivateKey() and then GenerateEphemeralPublicKey() */
|
|
||||||
virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const;
|
|
||||||
|
|
||||||
//! derive agreed value from your private keys and couterparty's public keys, return false in case of failure
|
|
||||||
/*! \note The ephemeral public key will always be validated.
|
|
||||||
If you have previously validated the static public key, use validateStaticOtherPublicKey=false to save time.
|
|
||||||
\pre size of agreedValue == AgreedValueLength()
|
|
||||||
\pre length of staticPrivateKey == StaticPrivateKeyLength()
|
|
||||||
\pre length of ephemeralPrivateKey == EphemeralPrivateKeyLength()
|
|
||||||
\pre length of staticOtherPublicKey == StaticPublicKeyLength()
|
|
||||||
\pre length of ephemeralOtherPublicKey == EphemeralPublicKeyLength()
|
|
||||||
*/
|
|
||||||
virtual bool Agree(byte *agreedValue,
|
|
||||||
const byte *staticPrivateKey, const byte *ephemeralPrivateKey,
|
|
||||||
const byte *staticOtherPublicKey, const byte *ephemeralOtherPublicKey,
|
|
||||||
bool validateStaticOtherPublicKey=true) const =0;
|
|
||||||
|
|
||||||
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
|
|
||||||
bool ValidateDomainParameters(RandomNumberGenerator &rng) const
|
|
||||||
{return GetCryptoParameters().Validate(rng, 2);}
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
// interface for password authenticated key agreement protocols, not implemented yet
|
|
||||||
#if 0
|
|
||||||
//! interface for protocol sessions
|
|
||||||
/*! The methods should be called in the following order:
|
|
||||||
|
|
||||||
InitializeSession(rng, parameters); // or call initialize method in derived class
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (OutgoingMessageAvailable())
|
|
||||||
{
|
|
||||||
length = GetOutgoingMessageLength();
|
|
||||||
GetOutgoingMessage(message);
|
|
||||||
; // send outgoing message
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LastMessageProcessed())
|
|
||||||
break;
|
|
||||||
|
|
||||||
; // receive incoming message
|
|
||||||
ProcessIncomingMessage(message);
|
|
||||||
}
|
|
||||||
; // call methods in derived class to obtain result of protocol session
|
|
||||||
*/
|
|
||||||
class ProtocolSession
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! exception thrown when an invalid protocol message is processed
|
|
||||||
class ProtocolError : public Exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ProtocolError(ErrorType errorType, const std::string &s) : Exception(errorType, s) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
//! exception thrown when a function is called unexpectedly
|
|
||||||
/*! for example calling ProcessIncomingMessage() when ProcessedLastMessage() == true */
|
|
||||||
class UnexpectedMethodCall : public Exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UnexpectedMethodCall(const std::string &s) : Exception(OTHER_ERROR, s) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
ProtocolSession() : m_rng(NULL), m_throwOnProtocolError(true), m_validState(false) {}
|
|
||||||
virtual ~ProtocolSession() {}
|
|
||||||
|
|
||||||
virtual void InitializeSession(RandomNumberGenerator &rng, const NameValuePairs ¶meters) =0;
|
|
||||||
|
|
||||||
bool GetThrowOnProtocolError() const {return m_throwOnProtocolError;}
|
|
||||||
void SetThrowOnProtocolError(bool throwOnProtocolError) {m_throwOnProtocolError = throwOnProtocolError;}
|
|
||||||
|
|
||||||
bool HasValidState() const {return m_validState;}
|
|
||||||
|
|
||||||
virtual bool OutgoingMessageAvailable() const =0;
|
|
||||||
virtual unsigned int GetOutgoingMessageLength() const =0;
|
|
||||||
virtual void GetOutgoingMessage(byte *message) =0;
|
|
||||||
|
|
||||||
virtual bool LastMessageProcessed() const =0;
|
|
||||||
virtual void ProcessIncomingMessage(const byte *message, unsigned int messageLength) =0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void HandleProtocolError(Exception::ErrorType errorType, const std::string &s) const;
|
|
||||||
void CheckAndHandleInvalidState() const;
|
|
||||||
void SetValidState(bool valid) {m_validState = valid;}
|
|
||||||
|
|
||||||
RandomNumberGenerator *m_rng;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_throwOnProtocolError, m_validState;
|
|
||||||
};
|
|
||||||
|
|
||||||
class KeyAgreementSession : public ProtocolSession
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual unsigned int GetAgreedValueLength() const =0;
|
|
||||||
virtual void GetAgreedValue(byte *agreedValue) const =0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PasswordAuthenticatedKeyAgreementSession : public KeyAgreementSession
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void InitializePasswordAuthenticatedKeyAgreementSession(RandomNumberGenerator &rng,
|
|
||||||
const byte *myId, unsigned int myIdLength,
|
|
||||||
const byte *counterPartyId, unsigned int counterPartyIdLength,
|
|
||||||
const byte *passwordOrVerifier, unsigned int passwordOrVerifierLength);
|
|
||||||
};
|
|
||||||
|
|
||||||
class PasswordAuthenticatedKeyAgreementDomain : public KeyAgreementAlgorithm
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! return whether the domain parameters stored in this object are valid
|
|
||||||
virtual bool ValidateDomainParameters(RandomNumberGenerator &rng) const
|
|
||||||
{return GetCryptoParameters().Validate(rng, 2);}
|
|
||||||
|
|
||||||
virtual unsigned int GetPasswordVerifierLength(const byte *password, unsigned int passwordLength) const =0;
|
|
||||||
virtual void GeneratePasswordVerifier(RandomNumberGenerator &rng, const byte *userId, unsigned int userIdLength, const byte *password, unsigned int passwordLength, byte *verifier) const =0;
|
|
||||||
|
|
||||||
enum RoleFlags {CLIENT=1, SERVER=2, INITIATOR=4, RESPONDER=8};
|
|
||||||
|
|
||||||
virtual bool IsValidRole(unsigned int role) =0;
|
|
||||||
virtual PasswordAuthenticatedKeyAgreementSession * CreateProtocolSession(unsigned int role) const =0;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation
|
//! BER Decode Exception Class, may be thrown during an ASN1 BER decode operation
|
||||||
class BERDecodeErr : public InvalidArgument
|
class BERDecodeErr : public InvalidArgument
|
||||||
{
|
{
|
||||||
@@ -1535,14 +1341,6 @@ public:
|
|||||||
virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);}
|
virtual void BEREncode(BufferedTransformation &bt) const {DEREncode(bt);}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
|
|
||||||
typedef PK_SignatureScheme PK_SignatureSystem
|
|
||||||
typedef PK_SignatureSchemeWithRecovery PK_SignatureSystemWithRecovery
|
|
||||||
typedef SimpleKeyAgreementDomain PK_SimpleKeyAgreementDomain
|
|
||||||
typedef AuthenticatedKeyAgreementDomain PK_AuthenticatedKeyAgreementDomain
|
|
||||||
typedef WithPrecomputation PK_WithPrecomputation
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NAMESPACE_END
|
NAMESPACE_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -39,9 +39,18 @@ void RSAFunction::DEREncodeKey(BufferedTransformation &bt) const
|
|||||||
|
|
||||||
Integer RSAFunction::ApplyFunction(const Integer &x) const
|
Integer RSAFunction::ApplyFunction(const Integer &x) const
|
||||||
{
|
{
|
||||||
|
DoQuickSanityCheck();
|
||||||
return a_exp_b_mod_c(x, m_e, m_n);
|
return a_exp_b_mod_c(x, m_e, m_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
|
||||||
|
{
|
||||||
|
bool pass = true;
|
||||||
|
pass = pass && m_n > Integer::One() && m_n.IsOdd();
|
||||||
|
pass = pass && m_e > Integer::One() && m_e.IsOdd() && m_e < m_n;
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
bool RSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
|
bool RSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
|
||||||
{
|
{
|
||||||
return GetValueHelper(this, name, valueType, pValue).Assignable()
|
return GetValueHelper(this, name, valueType, pValue).Assignable()
|
||||||
@@ -168,6 +177,7 @@ void InvertibleRSAFunction::DEREncodeKey(BufferedTransformation &bt) const
|
|||||||
|
|
||||||
Integer InvertibleRSAFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
|
Integer InvertibleRSAFunction::CalculateInverse(RandomNumberGenerator &rng, const Integer &x) const
|
||||||
{
|
{
|
||||||
|
DoQuickSanityCheck();
|
||||||
ModularArithmetic modn(m_n);
|
ModularArithmetic modn(m_n);
|
||||||
Integer r(rng, Integer::One(), m_n - Integer::One());
|
Integer r(rng, Integer::One(), m_n - Integer::One());
|
||||||
Integer re = modn.Exponentiate(r, m_e);
|
Integer re = modn.Exponentiate(r, m_e);
|
||||||
@@ -181,6 +191,27 @@ Integer InvertibleRSAFunction::CalculateInverse(RandomNumberGenerator &rng, cons
|
|||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool InvertibleRSAFunction::Validate(RandomNumberGenerator &rng, unsigned int level) const
|
||||||
|
{
|
||||||
|
bool pass = RSAFunction::Validate(rng, level);
|
||||||
|
pass = pass && m_p > Integer::One() && m_p.IsOdd() && m_p < m_n;
|
||||||
|
pass = pass && m_q > Integer::One() && m_q.IsOdd() && m_q < m_n;
|
||||||
|
pass = pass && m_d > Integer::One() && m_d.IsOdd() && m_d < m_n;
|
||||||
|
pass = pass && m_dp > Integer::One() && m_dp.IsOdd() && m_dp < m_p;
|
||||||
|
pass = pass && m_dq > Integer::One() && m_dq.IsOdd() && m_dq < m_q;
|
||||||
|
pass = pass && m_u.IsPositive() && m_u < m_p;
|
||||||
|
if (level >= 1)
|
||||||
|
{
|
||||||
|
pass = pass && m_p * m_q == m_n;
|
||||||
|
pass = pass && m_e*m_d % LCM(m_p-1, m_q-1) == 1;
|
||||||
|
pass = pass && m_dp == m_d%(m_p-1) && m_dq == m_d%(m_q-1);
|
||||||
|
pass = pass && m_u * m_q % m_p == 1;
|
||||||
|
}
|
||||||
|
if (level >= 2)
|
||||||
|
pass = pass && VerifyPrime(rng, m_p, level-2) && VerifyPrime(rng, m_q, level-2);
|
||||||
|
return pass;
|
||||||
|
}
|
||||||
|
|
||||||
bool InvertibleRSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
|
bool InvertibleRSAFunction::GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
|
||||||
{
|
{
|
||||||
return GetValueHelper<RSAFunction>(this, name, valueType, pValue).Assignable()
|
return GetValueHelper<RSAFunction>(this, name, valueType, pValue).Assignable()
|
||||||
|
|||||||
Reference in New Issue
Block a user