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

Reply via email to