I started learning cryptopp by porting some old test
code (written by somebody else) from Cryptopp library
version 4.2 to version 5.1. This test program had GUI
interface to display results, to load keys and other
types of test files, which made it somewhat easier for
me to learn what is in the library, play and perform
various tests.
While porting I found out that 5.1 has backward
compatible template only for DL_PublicKey_GFP
gfpcrypt.h:
template <class BASE>
class DL_PublicKey_GFP_OldFormat : public BASE
In hope that it may be useful to somebody, here are
corresponding classes for EC and RSA keys:
template <class EC, class BASECLASS>
class DL_PublicKey_EC_OldFormat : public BASECLASS
{
public:
void BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder seq(bt);
BERSequenceDecoder algorithm(seq);
byte b;
if ( OID(algorithm) != ASN1::id_ecPublicKey() )
BERDecodeError();
BERSequenceDecoder groupparam(algorithm);
if (!groupparam.Peek(b))
BERDecodeError();
if (b == OBJECT_IDENTIFIER)
AccessGroupParameters().Initialize(OID(groupparam));
else
{
typename EC ec(groupparam);
typename EC::Point G =
ec.BERDecodePoint(groupparam);
Integer n(groupparam);
Integer k;
bool cofactorPresent = !groupparam.EndReached();
if (cofactorPresent)
k.BERDecode(groupparam);
else
k = Integer::Zero();
groupparam.MessageEnd();
AccessGroupParameters().Initialize( ec, G, n, k );
}
algorithm.MessageEnd();
SecByteBlock subjectPublicKey;
unsigned int unusedBits;
BERDecodeBitString(seq, subjectPublicKey,
unusedBits);
typename EC::Point P;
if ( !(unusedBits==0 &&
AccessGroupParameters().GetCurve().DecodePoint(P,subjectPublicKey,subjectPublicKey.size())))
BERDecodeError();
seq.MessageEnd();
SetPublicElement(P);
}
};
template <class EC, class BASECLASS>
class DL_PrivateKey_EC_OldFormat : public BASECLASS
{
public:
void BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder privateKeyInfo(bt);
word32 version;
BERDecodeUnsigned<word32>(privateKeyInfo, version,
INTEGER, 0, 1); // check version
if (version == 1)
{
OldFormatRawDecode(privateKeyInfo, true); // for
backwards compatibility
}
else
{
BERSequenceDecoder algorithm(privateKeyInfo);
ASN1::id_ecPublicKey().BERDecodeAndCheck(algorithm);
bool noParameters = algorithm.PeekByte() ==
TAG_NULL;
if (noParameters)
BERDecodeNull(algorithm);
else
{
byte b;
BERSequenceDecoder groupparam(algorithm);
if (!groupparam.Peek(b))
BERDecodeError();
if (b == OBJECT_IDENTIFIER)
AccessGroupParameters().Initialize(OID(groupparam));
else
{
typename EC ec(groupparam);
typename EC::Point G =
ec.BERDecodePoint(groupparam);
Integer n(groupparam);
Integer k;
bool cofactorPresent =
!groupparam.EndReached();
if (cofactorPresent)
k.BERDecode(groupparam);
else
k = Integer::Zero();
groupparam.MessageEnd();
AccessGroupParameters().Initialize( ec, G, n, k
);
}
}
algorithm.MessageEnd();
BERGeneralDecoder octetString(privateKeyInfo,
OCTET_STRING);
BERSequenceDecoder privateKey(octetString);
BERDecodeUnsigned<word32>(privateKey, version,
INTEGER, 1, 1); // check version
OldFormatRawDecode(privateKey, noParameters);
privateKey.MessageEnd();
octetString.MessageEnd();
}
privateKeyInfo.MessageEnd();
}
void OldFormatRawDecode(BERSequenceDecoder &seq, bool
parametersPresent)
{
BERGeneralDecoder dec(seq, OCTET_STRING);
if (!dec.IsDefiniteLength())
BERDecodeError();
Integer x;
x.Decode(dec, dec.RemainingLength());
dec.MessageEnd();
if (parametersPresent && seq.PeekByte() !=
(CONTEXT_SPECIFIC | CONSTRUCTED | 0))
BERDecodeError();
if (!seq.EndReached() && seq.PeekByte() ==
(CONTEXT_SPECIFIC | CONSTRUCTED | 0))
{
BERGeneralDecoder parameters(seq, CONTEXT_SPECIFIC
| CONSTRUCTED | 0);
AccessGroupParameters().BERDecode(parameters);
parameters.MessageEnd();
}
if (!seq.EndReached())
{
// skip over the public element
SecByteBlock subjectPublicKey;
unsigned int unusedBits;
BERGeneralDecoder publicKey(seq, CONTEXT_SPECIFIC |
CONSTRUCTED | 1);
BERDecodeBitString(publicKey, subjectPublicKey,
unusedBits);
publicKey.MessageEnd();
Element Q;
if (!(unusedBits == 0 &&
GetGroupParameters().GetCurve().DecodePoint(Q,
subjectPublicKey, subjectPublicKey.size())))
BERDecodeError();
// SetPrivateElement(Q);
}
SetPrivateExponent(x);
}
};
template <class BASECLASS>
class RSA_PublicKey_OldFormat : public BASECLASS
{
public:
void BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder subjectPublicKeyInfo(bt);
if (subjectPublicKeyInfo.PeekByte() == INTEGER)
{
// for backwards compatibility
m_n.BERDecode(subjectPublicKeyInfo);
m_e.BERDecode(subjectPublicKeyInfo);
}
else
{
BERSequenceDecoder algorithm(subjectPublicKeyInfo);
ASN1::rsaEncryption().BERDecodeAndCheck(algorithm);
BERDecodeNull(algorithm);
algorithm.MessageEnd();
BERSequenceDecoder
subjectPublicKey(subjectPublicKeyInfo, BIT_STRING);
subjectPublicKey.CheckByte(0); // unused bits
BERSequenceDecoder seq(subjectPublicKey);
m_n.BERDecode(seq);
m_e.BERDecode(seq);
seq.MessageEnd();
subjectPublicKey.MessageEnd();
}
subjectPublicKeyInfo.MessageEnd();
}
};
template <class BASECLASS>
class RSA_PrivateKey_OldFormat : public BASECLASS
{
public:
void BERDecode(BufferedTransformation &bt)
{
BERSequenceDecoder privateKeyInfo(bt);
word32 version;
BERDecodeUnsigned<word32>(privateKeyInfo, version,
INTEGER, 0, 0); // check version
if (privateKeyInfo.PeekByte() == INTEGER)
{
// for backwards compatibility
m_n.BERDecode(privateKeyInfo);
m_e.BERDecode(privateKeyInfo);
m_d.BERDecode(privateKeyInfo);
m_p.BERDecode(privateKeyInfo);
m_q.BERDecode(privateKeyInfo);
m_dp.BERDecode(privateKeyInfo);
m_dq.BERDecode(privateKeyInfo);
m_u.BERDecode(privateKeyInfo);
}
else
{
BERSequenceDecoder algorithm(privateKeyInfo);
ASN1::rsaEncryption().BERDecodeAndCheck(algorithm);
BERDecodeNull(algorithm);
algorithm.MessageEnd();
BERGeneralDecoder octetString(privateKeyInfo,
OCTET_STRING);
BERSequenceDecoder privateKey(octetString);
BERDecodeUnsigned<word32>(privateKey, version,
INTEGER, 0, 0); // check version
m_n.BERDecode(privateKey);
m_e.BERDecode(privateKey);
m_d.BERDecode(privateKey);
m_p.BERDecode(privateKey);
m_q.BERDecode(privateKey);
m_dp.BERDecode(privateKey);
m_dq.BERDecode(privateKey);
m_u.BERDecode(privateKey);
privateKey.MessageEnd();
octetString.MessageEnd();
}
privateKeyInfo.MessageEnd();
}
};
// example use
RSA_PrivateKey_OldFormat<RSA::PrivateKey> privateKey;
privateKey.Load(somebuffer);
RSASSA_PKCS1v15_SHA_Signer RSASigner=new
RSASSA_PKCS1v15_SHA_Signer(privateKey);
Tony
__________________________________
Do you Yahoo!?
SBC Yahoo! DSL - Now only $29.95 per month!
http://sbc.yahoo.com