From 40a5b80a4522a9b3ad3820b5a953bb4f3611e009 Mon Sep 17 00:00:00 2001 From: weidai Date: Sat, 19 Jun 2004 08:26:29 +0000 Subject: [PATCH] fix encoding/decoding of optional attributes --- asn.cpp | 43 ++++++++++++++++++++++++++++++++++++------- asn.h | 20 ++++++++++++++------ 2 files changed, 50 insertions(+), 13 deletions(-) diff --git a/asn.cpp b/asn.cpp index 41211ce2..272cec37 100644 --- a/asn.cpp +++ b/asn.cpp @@ -195,6 +195,23 @@ unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, u return bc-1; } +void DERReencode(BufferedTransformation &source, BufferedTransformation &dest) +{ + byte tag; + source.Peek(tag); + BERGeneralDecoder decoder(source, tag); + DERGeneralEncoder encoder(dest, tag); + if (decoder.IsDefiniteLength()) + decoder.TransferTo(encoder, decoder.RemainingLength()); + else + { + while (!decoder.EndReached()) + DERReencode(decoder, encoder); + } + decoder.MessageEnd(); + encoder.MessageEnd(); +} + void OID::EncodeValue(BufferedTransformation &bt, unsigned long v) { for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7) @@ -354,15 +371,16 @@ void EncodedObjectFilter::Put(const byte *inString, unsigned int length) BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag) : m_inQueue(inQueue), m_finished(false) { - byte b; - if (!m_inQueue.Get(b) || b != asnTag) - BERDecodeError(); - - m_definiteLength = BERLengthDecode(m_inQueue, m_length); + Init(asnTag); } BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag) : m_inQueue(inQueue), m_finished(false) +{ + Init(asnTag); +} + +void BERGeneralDecoder::Init(byte asnTag) { byte b; if (!m_inQueue.Get(b) || b != asnTag) @@ -370,7 +388,7 @@ BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag) m_definiteLength = BERLengthDecode(m_inQueue, m_length); if (!m_definiteLength && !(asnTag & CONSTRUCTED)) - BERDecodeError(); // cannot be primitive have indefinite length + BERDecodeError(); // cannot be primitive and have indefinite length } BERGeneralDecoder::~BERGeneralDecoder() @@ -534,7 +552,8 @@ void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt) BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.RemainingLength()); octetString.MessageEnd(); - BERDecodeOptionalAttributes(privateKeyInfo); + if (!privateKeyInfo.EndReached()) + BERDecodeOptionalAttributes(privateKeyInfo); privateKeyInfo.MessageEnd(); } @@ -556,6 +575,16 @@ void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const privateKeyInfo.MessageEnd(); } +void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt) +{ + DERReencode(bt, m_optionalAttributes); +} + +void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const +{ + m_optionalAttributes.CopyTo(bt); +} + NAMESPACE_END #endif diff --git a/asn.h b/asn.h index ff91f86e..b833d248 100644 --- a/asn.h +++ b/asn.h @@ -75,6 +75,9 @@ CRYPTOPP_DLL unsigned int BERDecodeTextString(BufferedTransformation &in, std::s CRYPTOPP_DLL unsigned int DEREncodeBitString(BufferedTransformation &out, const byte *str, unsigned int strLen, unsigned int unusedBits=0); CRYPTOPP_DLL unsigned int BERDecodeBitString(BufferedTransformation &in, SecByteBlock &str, unsigned int &unusedBits); +// BER decode from source and DER reencode into dest +CRYPTOPP_DLL void DERReencode(BufferedTransformation &source, BufferedTransformation &dest); + //! Object Identifier class CRYPTOPP_DLL OID { @@ -147,6 +150,7 @@ protected: unsigned int m_length; private: + void Init(byte asnTag); void StoreInitialize(const NameValuePairs ¶meters) {assert(false);} unsigned int ReduceLength(unsigned int delta); }; @@ -221,8 +225,8 @@ public: } void DEREncode(BufferedTransformation &out) { - if (get() != NULL) - get()->DEREncode(out); + if (this->get() != NULL) + this->get()->DEREncode(out); } }; @@ -259,10 +263,14 @@ public: void BERDecode(BufferedTransformation &bt); void DEREncode(BufferedTransformation &bt) const; - virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt) - {} // TODO: skip optional attributes if present - virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const - {} + //! decode optional attributes including context-specific tag + /*! /note default implementation stores attributes to be output in DEREncodeOptionalAttributes */ + virtual void BERDecodeOptionalAttributes(BufferedTransformation &bt); + //! encode optional attributes including context-specific tag + virtual void DEREncodeOptionalAttributes(BufferedTransformation &bt) const; + +private: + ByteQueue m_optionalAttributes; }; // ********************************************************