⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asn.cpp

📁 crypt++ 3.2版本
💻 CPP
字号:
// asn.cpp - written and placed in the public domain by Wei Dai

#include "pch.h"
#include "asn.h"

#include <strstream>
#include <iomanip>
#include <time.h>

NAMESPACE_BEGIN(CryptoPP)
USING_NAMESPACE(std)

/// DER Length
unsigned int DERLengthEncode(unsigned int length, byte *output)
{
	unsigned int i=0;
	if (output)
	{
		if (length <= 0x7f)
		{
			output[i++] = byte(length);
		}
		else
		{
			output[i++] = byte(BytePrecision(length) | 0x80);
			for (int j=BytePrecision(length); j; --j)
			{
				output[i++] = byte (length >> (j-1)*8);
			}
		}
	}
	else
	{
		if (length <= 0x7f)
			i++;
		else
		{
			i++;
			for (int j=BytePrecision(length); j; --j)
				i++;
		}
	}
	return i;
}

unsigned int DERLengthEncode(unsigned int length, BufferedTransformation &bt)
{
	byte buf[10];	// should be more than enough
	unsigned int i = DERLengthEncode(length, buf);
	assert(i <= 10);
	bt.Put(buf, i);
	return i;
}

bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length)
{
	byte b;

	if (!bt.Get(b))
		BERDecodeError();

	if (!(b & 0x80))
		length = b;
	else
	{
		unsigned int lengthBytes = b & 0x7f;

		if (lengthBytes == 0)
			return false;	// indefinite length

		length = 0;
		while (lengthBytes--)
		{
			if (length >> (8*(sizeof(length)-1)))
				BERDecodeError();	// length about to overflow

			if (!bt.Get(b))
				BERDecodeError();

			length = (length << 8) | b;
		}
	}
	return true;
}

unsigned int BERExtractDefiniteLengthField(BufferedTransformation &input, BufferedTransformation &output)
{
	unsigned int bc;
	byte tag;
	if (!input.Get(tag))
		BERDecodeError();
	output.Put(tag);
	if (!BERLengthDecode(input, bc))
		BERDecodeError();
	DERLengthEncode(bc, output);
	if (input.TransferTo(output, bc) != bc)
		BERDecodeError();
	return bc;
}

/// ASN Strings
unsigned int DEREncodeOctetString(const byte *str, unsigned int strLen, BufferedTransformation &bt)
{
	bt.Put(OCTET_STRING);
	unsigned int lengthBytes = DERLengthEncode(strLen, bt);
	bt.Put(str, strLen);
	return 1+lengthBytes+strLen;
}

unsigned int DEREncodeOctetString(const SecByteBlock &str, BufferedTransformation &bt)
{
	return DEREncodeOctetString(str.ptr, str.size, bt);
}

unsigned int BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str)
{
	byte b;
	if (!bt.Get(b) || b != OCTET_STRING)
		BERDecodeError();

	unsigned int bc;
	BERLengthDecode(bt, bc);

	str.Resize(bc);
	if (bc != bt.Get(str, bc))
		BERDecodeError();
	return bc;
}

unsigned int DEREncodeTextString(const std::string &str, BufferedTransformation &bt, byte asnTag)
{
	bt.Put(asnTag);
	unsigned int lengthBytes = DERLengthEncode(str.size(), bt);
	bt.Put((const byte *)str.data(), str.size());
	return 1+lengthBytes+str.size();
}

unsigned int BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag)
{
	byte b;
	if (!bt.Get(b) || b != asnTag)
		BERDecodeError();

	unsigned int bc;
	BERLengthDecode(bt, bc);

	SecByteBlock temp(bc);
	if (bc != bt.Get(temp, bc))
		BERDecodeError();
	str.assign((char *)temp.ptr, bc);
	return bc;
}

/// ASN BitString
unsigned int DEREncodeBitString(const byte *str, unsigned int strLen, BufferedTransformation &bt)
{
	bt.Put(BIT_STRING);
	unsigned int lengthBytes = DERLengthEncode(strLen+1, bt);
	bt.Put((byte)0);
	bt.Put(str, strLen);
	return 1+lengthBytes+strLen;
}

unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str)
{
	byte b;
	if (!bt.Get(b) || b != BIT_STRING)
		BERDecodeError();

	unsigned int bc;
	BERLengthDecode(bt, bc);

	byte unused;
	if (!bt.Get(unused) || unused != 0)
		BERDecodeError();
	str.Resize(bc-1);
	if ((bc-1) != bt.Get(str, bc-1))
		BERDecodeError();
	return bc;
}

/// ASN Sequence
BERSequenceDecoder::BERSequenceDecoder(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);
}

BERSequenceDecoder::BERSequenceDecoder(BERSequenceDecoder &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);
}

BERSequenceDecoder::~BERSequenceDecoder()
{
	try	// avoid throwing in constructor
	{
		OutputFinished();
	}
	catch (...)
	{
	}
}

void BERSequenceDecoder::OutputFinished()
{
	if (m_finished)
		return;
	else
		m_finished = true;

	if (!m_definiteLength)
	{	// remove end-of-content Octets
		word16 i;
		if (!m_inQueue.GetShort(i) || (i!=0))
			BERDecodeError();
	}
}

unsigned long BERSequenceDecoder::MaxRetrieveable()
{
	unsigned long maxRet = m_inQueue.MaxRetrieveable();

	if (m_definiteLength)
		return STDMIN(maxRet, (unsigned long)m_length);
	else
		return maxRet;
}

unsigned int BERSequenceDecoder::Get(byte &outByte)
{
	if (!m_definiteLength || m_length >= 1)
		return ReduceLength(m_inQueue.Get(outByte));
	else
		return 0;
}

unsigned int BERSequenceDecoder::Get(byte *outString, unsigned int getMax)
{
	return ReduceLength(m_inQueue.Get(outString, m_definiteLength ? STDMIN(getMax, m_length) : getMax));
}

unsigned int BERSequenceDecoder::Peek(byte &outByte) const
{
	if (!m_definiteLength || m_length >= 1)
		return m_inQueue.Peek(outByte);
	else
		return 0;
}

unsigned int BERSequenceDecoder::Peek(byte *outString, unsigned int peekMax) const
{
	return m_inQueue.Peek(outString, m_definiteLength ? STDMIN(peekMax, m_length) : peekMax);
}

unsigned long BERSequenceDecoder::CopyTo(BufferedTransformation &target) const
{
	return m_inQueue.CopyTo(target, m_definiteLength ? m_length : m_inQueue.MaxRetrieveable());
}

unsigned int BERSequenceDecoder::CopyTo(BufferedTransformation &target, unsigned int copyMax) const
{
	return m_inQueue.CopyTo(target, m_definiteLength ? STDMIN(copyMax, m_length) : copyMax);
}

unsigned int BERSequenceDecoder::ReduceLength(unsigned int delta)
{
	if (m_definiteLength)
	{
		assert(m_length >= delta);
		m_length -= delta;
	}
	return delta;
}

DERSequenceEncoder::DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag)
	: m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
{
}

DERSequenceEncoder::DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag)
	: m_outQueue(outQueue), m_asnTag(asnTag), m_finished(false)
{
}

DERSequenceEncoder::~DERSequenceEncoder()
{
	try	// avoid throwing in constructor
	{
		InputFinished();
	}
	catch (...)
	{
	}
}

void DERSequenceEncoder::InputFinished()
{
	if (m_finished)
		return;
	else
		m_finished = true;

	unsigned int length = (unsigned int)CurrentSize();
	m_outQueue.Put(m_asnTag);
	DERLengthEncode(length, m_outQueue);
	TransferTo(m_outQueue);
}

/// ASN Set
DERSetEncoder::DERSetEncoder(BufferedTransformation &outQueue, byte asnTag)
	: DERSequenceEncoder(outQueue, asnTag)
{
}

DERSetEncoder::DERSetEncoder(DERSetEncoder &outQueue, byte asnTag)
	: DERSequenceEncoder(outQueue, asnTag)
{
}

BERSetDecoder::BERSetDecoder(BufferedTransformation &inQueue, byte asnTag)
	: BERSequenceDecoder(inQueue, asnTag)
{
}

BERSetDecoder::BERSetDecoder(BERSetDecoder &inQueue, byte asnTag)
	: BERSequenceDecoder(inQueue, asnTag)
{
}


NAMESPACE_END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -