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

📄 asn.h

📁 crypt++ 3.2版本
💻 H
字号:
#ifndef CRYPTOPP_ASN_H
#define CRYPTOPP_ASN_H

#include "cryptlib.h"
#include "queue.h"
#include "misc.h"

NAMESPACE_BEGIN(CryptoPP)

// NOTE: these tags and flags are NOT COMPLETE!
enum ASNTag
{
	BOOLEAN 			= 0x01,
	INTEGER 			= 0x02,
	BIT_STRING			= 0x03,
	OCTET_STRING		= 0x04,
	NULL_VALUE			= 0x05,
	OBJECT_IDENTIFIER	= 0x06,
	OBJECT_DESCRIPTOR	= 0x07,
	EXTERNAL			= 0x08,
	REAL				= 0x09,
	ENUMERATED			= 0x0a,
	UTF8_STRING			= 0x0c,
	SEQUENCE			= 0x10,
	SET 				= 0x11,
	NUMERIC_STRING		= 0x12,
	PRINTABLE_STRING 	= 0x13,
	T61_STRING			= 0x14,
	VIDEOTEXT_STRING 	= 0x15,
	IA5_STRING			= 0x16,
	UTC_TIME 			= 0x17,
	GENERALIZED_TIME 	= 0x18,
	GRAPHIC_STRING		= 0x19,
	VISIBLE_STRING		= 0x1a,
	GENERAL_STRING		= 0x1b,
};

enum ASNIdFlag
{
	UNIVERSAL			= 0x00,
	DATA				= 0x01,
	HEADER				= 0x02,
	CONSTRUCTED 		= 0x20,
	APPLICATION 		= 0x40,
	CONTEXT_SPECIFIC	= 0x80,
	PRIVATE 			= 0xc0,
};

#define BERDecodeError() throw BERDecodeErr()

class BERDecodeErr : public Exception
{
public: 
	BERDecodeErr() : Exception("BER decode error") {}
	BERDecodeErr(const char *err) : Exception(err) {}
};

unsigned int DERLengthEncode(unsigned int length, byte *output=0);
unsigned int DERLengthEncode(unsigned int length, BufferedTransformation &);
// returns false if indefinite length
bool BERLengthDecode(BufferedTransformation &, unsigned int &length);
unsigned int BERExtractDefiniteLengthField(BufferedTransformation &input, BufferedTransformation &output);

unsigned int DEREncodeOctetString(const byte *str, unsigned int strLen, BufferedTransformation &bt);
unsigned int DEREncodeOctetString(const SecByteBlock &str, BufferedTransformation &bt);
unsigned int BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str);

// for UTF8_STRING, PRINTABLE_STRING, and IA5_STRING
unsigned int DEREncodeTextString(const std::string &str, BufferedTransformation &bt, byte asnTag);
unsigned int BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag);

unsigned int DEREncodeBitString(const byte *str, unsigned int strLen, BufferedTransformation &bt);
unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str);

class BERSequenceDecoder : public BufferedTransformation
{
public:
	BERSequenceDecoder(BufferedTransformation &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
	BERSequenceDecoder(BERSequenceDecoder &inQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
	~BERSequenceDecoder();

	bool IsDefiniteLength() const {return m_definiteLength;}
	unsigned int RemainingLength() const {assert(m_definiteLength); return m_length;}

	void Put(byte inByte) {}
	void Put(const byte *inString, unsigned int length) {}

	unsigned long MaxRetrieveable();

	unsigned int Get(byte &outByte);
	unsigned int Get(byte *outString, unsigned int getMax);

	unsigned int Peek(byte &outByte) const;
	unsigned int Peek(byte *outString, unsigned int peekMax) const;

	unsigned long CopyTo(BufferedTransformation &target) const;
	unsigned int CopyTo(BufferedTransformation &target, unsigned int copyMax) const;

	// call this to denote end of sequence
	void OutputFinished();

protected:
	BufferedTransformation &m_inQueue;
	bool m_finished, m_definiteLength;
	unsigned int m_length;

private:
	unsigned int ReduceLength(unsigned int delta);
};

class DERSequenceEncoder : public ByteQueue
{
public:
	DERSequenceEncoder(BufferedTransformation &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
	DERSequenceEncoder(DERSequenceEncoder &outQueue, byte asnTag = SEQUENCE | CONSTRUCTED);
	~DERSequenceEncoder();

	// call this to denote end of sequence
	void InputFinished();

private:
	BufferedTransformation &m_outQueue;
	bool m_finished;

	byte m_asnTag;
};

class BERSetDecoder : public BERSequenceDecoder
{
public:
	BERSetDecoder(BufferedTransformation &inQueue, byte asnTag = SET | CONSTRUCTED);
	BERSetDecoder(BERSetDecoder &inQueue, byte asnTag = SET | CONSTRUCTED);
};

class DERSetEncoder : public DERSequenceEncoder
{
public:
	DERSetEncoder(BufferedTransformation &outQueue, byte asnTag = SET | CONSTRUCTED);
	DERSetEncoder(DERSetEncoder &outQueue, byte asnTag = SET | CONSTRUCTED);
};

// ********************************************************

// for INTEGER, BOOLEAN, and ENUM
template <class T>
unsigned int DEREncodeUnsigned(T w, BufferedTransformation &bt, byte asnTag = INTEGER)
{
	byte buf[sizeof(w)];
	for (unsigned int i=0; i<sizeof(w); i++)
		buf[i] = byte(w >> (sizeof(w)-1-i)*8);
	unsigned int bc = sizeof(w);
	while (bc > 1 && buf[sizeof(w)-bc] == 0)
		bc--;
	bt.Put(asnTag);
	unsigned int lengthBytes = DERLengthEncode(bc, bt);
	bt.Put(buf+sizeof(w)-bc, bc);
	return 1+lengthBytes+bc;
}

// VC60 workaround: std::numeric_limits<T>::max conflicts with MFC max macro
// CW41 workaround: std::numeric_limits<T>::max causes a template error
template <class T>
void BERDecodeUnsigned(BufferedTransformation &bt, T &w, byte asnTag = INTEGER,
					   T minValue = 0, T maxValue = 0xffffffff)
{
	byte b;
	if (!bt.Get(b) || b != asnTag)
		BERDecodeError();

	unsigned int bc;
	BERLengthDecode(bt, bc);

	SecByteBlock buf(bc);

	if (bc != bt.Get(buf, bc))
		BERDecodeError();

	const byte *ptr = buf;
	while (bc > sizeof(w) && *ptr == 0)
	{
		bc--;
		ptr++;
	}
	if (bc > sizeof(w))
		BERDecodeError();

	w = 0;
	for (unsigned int i=0; i<bc; i++)
		w = (w << 8) | ptr[i];

	if (w < minValue || w > maxValue)
		BERDecodeError();
}

NAMESPACE_END

#endif

⌨️ 快捷键说明

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