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

📄 asn1_der_decode.c

📁 包含标准证书编/解码、哈希、MD5、SHA1等算法的实现源码
💻 C
字号:
/*------------------------------------------------------------------  Copyright  Sun Microsystems, Inc.  Copyright (C) 1994, 1995, 1996 Sun Microsystems, Inc.  All Rights  Reserved.  Permission is hereby granted, free of charge, to any person  obtaining a copy of this software and associated documentation  files (the "Software"), to deal in the Software without  restriction, including without limitation the rights to use,  copy, modify, merge, publish, distribute, sublicense, and/or sell  copies of the Software or derivatives of the Software, and to   permit persons to whom the Software or its derivatives is furnished   to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be  included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND  NONINFRINGEMENT.  IN NO EVENT SHALL SUN MICROSYSTEMS, INC., BE LIABLE  FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN  CONNECTION WITH THE SOFTWARE OR DERIVATES OF THIS SOFTWARE OR   THE USE OR OTHER DEALINGS IN THE SOFTWARE.  Except as contained in this notice, the name of Sun Microsystems, Inc.  shall not be used in advertising or otherwise to promote  the sale, use or other dealings in this Software or its derivatives   without prior written authorization from Sun Microsystems, Inc.*/#pragma ident "@(#)asn1_der_decode.C	1.5 96/01/29 Sun Microsystems"#include <sys/types.h>#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include "my_types.h"#include "Time.h"#include "Bigint.h"#include "Bstream.h"#include "asn1_der.h"#include "ObjId.h"/* * Encoding decoding routines for ASN.1 using * the Basic Encoding Rules subset DER */void asn1_perror(int errcode){	printf("ASN.1 decoding error: ");	switch(errcode) {	case E_DER_DECODE_LEN_TOO_LONG:		printf("length octets exceed length of buffer\n");		break;	case E_DER_DECODE_BAD_ID_OCTET:		printf("unexpected ID octet\n");		break;	case E_DER_DECODE_UNEXPECTED_EOS:		printf("unexpected end-of-stream\n");		break;	case E_DER_DECODE_BAD_BITSTRING:		printf("bad bitstring\n");		break;	case E_DER_DECODE_UNALIGNED_BS:		printf("bitsring not octet aligned\n");		break;	case E_DER_DECODE_BAD_OBJID_SUBID:		printf("bad sub-identifier of OBJECT-IDENTIFIER\n");		break;	case E_DER_DECODE_BAD_TIME_STRING:		printf("bad UTCTime string\n");		break;	case E_DER_DECODE_BAD_NULL_VALUE:		printf("bad null value, length not equal to zero\n");		break;	default:		printf("unknown error code %d\n", errcode);		break;	}	return;}int convert_bytes_to_int(byte *four_bytes){#if defined(sparc)	int val;	byte *bytep = (byte *)&val;	bytep[0] = four_bytes[3];	bytep[1] = four_bytes[2];	bytep[2] = four_bytes[1];	bytep[3] = four_bytes[0];	return (val);#else #if defined(i386)        int val;        byte *bytep = (byte *)&val;         bytep[0] = four_bytes[0];        bytep[1] = four_bytes[1];        bytep[2] = four_bytes[2];        bytep[3] = four_bytes[3];        return (val);#else	return "Architecture not supported";#endif /* i386 */#endif /* sparc */}/* * Do ASN.1 DER length octets processing. * We assume that the number of content * octets will never exceed 2**32 octets. */int asn1_der_get_length(Bstream& der_stream){	byte	tmp = 0;	int 	len;	const int MAXLENBYTES = 4; /*Greater than 32 bits should not be required*/	byte    lenbytes[MAXLENBYTES];	int 	i, ret;	ret = der_stream.fetchbyte(tmp);	if (ret == EOS)		return (E_DER_DECODE_UNEXPECTED_EOS);#ifdef __GNUC__	if ((tmp & 0x80) == 0 ) {#else	if ((tmp & 0x80) == NULL ) {#endif		len = tmp;	} else {		int  numbytes = tmp & 0x7f;		if (numbytes > MAXLENBYTES)			return (E_DER_DECODE_LEN_TOO_LONG);		if (numbytes > der_stream.getlength())			return (E_DER_DECODE_UNEXPECTED_EOS);		bzero(lenbytes, sizeof(lenbytes));		for (i = numbytes - 1; i >= 0; i--)			(void ) der_stream.fetchbyte(lenbytes[i]);		len = convert_bytes_to_int(lenbytes);	}	return (len);}/* * Decode an ASN.1 DER INTEGER */int asn1_der_decode_integer(Bstream& der_stream, Bigint& val){	byte tmp = 0;	int  len;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != INTEGER_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len < 0) return len;	if (len > der_stream.getlength()) 		return (E_DER_DECODE_UNEXPECTED_EOS);	Bigint tmpval((unsigned char *)der_stream.getdatap(), len);	der_stream.consume(len);		val = tmpval;	return (0);}/* * Decode the ID part of a SEQUENCE */int asn1_der_decode_sequence(Bstream& der_stream, int &len){	byte tmp = 0;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != SEQUENCE_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len > der_stream.getlength()) {		return (E_DER_DECODE_UNEXPECTED_EOS);	}	return (SUCCESS);}int asn1_der_decode_sequence_of(Bstream& der_stream, int &len){	return (asn1_der_decode_sequence(der_stream, len));}/* * Decode the ID part of a SET */int asn1_der_decode_set(Bstream& der_stream, int &len){	byte tmp = 0;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != SET_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len > der_stream.getlength()) {		return (E_DER_DECODE_UNEXPECTED_EOS);	}	return (SUCCESS);}/* * Decode NULL type */int asn1_der_decode_null(Bstream& der_stream){	byte tmp = 0;	int  len;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != NULL_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len != 0)		return(E_DER_DECODE_BAD_NULL_VALUE);	return (SUCCESS);}int asn1_der_decode_set_of(Bstream& der_stream, int &len){	return (asn1_der_decode_set(der_stream, len));}/* * Decode a BIT-STRING */int asn1_der_decode_bit_string(Bstream& der_stream, Bstream& bitstring){	byte tmp = 0;	int  len, ret;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != BIT_STRING_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len < 0) return len;	if (len == 0) return (E_DER_DECODE_BAD_BITSTRING);	if (len > der_stream.getlength()) 		return (E_DER_DECODE_UNEXPECTED_EOS);	ret = der_stream.fetchbyte(tmp);	if (ret == EOS)		return (SUCCESS);	if (len == 1) {		if (tmp == 0) return (SUCCESS);		else return (E_DER_DECODE_BAD_BITSTRING);	}	if (tmp > 7 ) 		return (E_DER_DECODE_BAD_BITSTRING);	// Special Hack for certificates, which	// are assumed to produce octet aligned quantities	if (tmp != 0)		return (E_DER_DECODE_UNALIGNED_BS);	Bstream tmpstr(len - 1, der_stream.getdatap());		der_stream.consume(len - 1);	bitstring = tmpstr;	return (SUCCESS);}/* * Decode an OCTET-STRING */int asn1_der_decode_octet_string(Bstream& der_stream, Bstream& octetstring){	byte tmp = 0;	int  len;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != OCTET_STRING_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len < 0) return len;	if (len > der_stream.getlength()) 		return (E_DER_DECODE_UNEXPECTED_EOS);	Bstream tmpstr(len, der_stream.getdatap());		der_stream.consume(len);	octetstring = tmpstr;	return (SUCCESS);}/* * Decode a PRINTABLE-STRING */int asn1_der_decode_printable_string(Bstream& der_stream, Bstream& prstring){	byte tmp = 0;	int  len;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != PRINTABLE_STRING_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len < 0) return len;	if (len > der_stream.getlength()) {		return (E_DER_DECODE_UNEXPECTED_EOS);	}	Bstream tmpstr(len, der_stream.getdatap());		der_stream.consume(len);	prstring = tmpstr;	return (SUCCESS);}/* * Decode a T61-STRING */int asn1_der_decode_T61_string(Bstream& der_stream, Bstream& prstring){	byte tmp = 0;	int  len;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != T61_STRING_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len < 0) return len;	if (len > der_stream.getlength()) 		return (E_DER_DECODE_UNEXPECTED_EOS);	Bstream tmpstr(len, der_stream.getdatap());		der_stream.consume(len);	prstring = tmpstr;	return (SUCCESS);}inline void  get_twodigits(Bstream& tmpstr, byte *two_digits){	(void) tmpstr.fetchbyte(two_digits[0]);	(void) tmpstr.fetchbyte(two_digits[1]);}/* * Decode a UTCTime */int asn1_der_decode_utctime(Bstream& der_stream, PCTime& time){	byte tmp = 0;	int  len;	byte two_digits[3];	char sign;	int year, month, day, hour, min, offhr, offmin;	int sec = 0;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	(void )der_stream.peekbyte(tmp);	if (tmp != UTCTime_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len < 0) return len;	if (len > der_stream.getlength()) 		return (E_DER_DECODE_UNEXPECTED_EOS);	Bstream tmpstr(len, der_stream.getdatap());	der_stream.consume(len);	// Parse the Time string	if (len < 11 || len > 17) {		return (E_DER_DECODE_BAD_TIME_STRING);	}	two_digits[2] = 0;	// null terminate 	get_twodigits(tmpstr, two_digits);	year = atoi((char *)two_digits);	// Convert last two digits to full year, including century.	// For this we assume that anything less than 80 is 20XX	// and anything more than or equal to 80 is 19XX.	// Is there a better way of doing this? XXXX	if (year < 80) {		year += 2000;	// Fix this piece of code after year 2080!!	} else {		year += 1900;	}	get_twodigits(tmpstr, two_digits);	month = atoi((char *)two_digits);	get_twodigits(tmpstr, two_digits);	day = atoi((char *)two_digits);	get_twodigits(tmpstr, two_digits);	hour = atoi((char *)two_digits);	get_twodigits(tmpstr, two_digits);	min = atoi((char *)two_digits);	if (len == 13 || len == 17) { // secs present		get_twodigits(tmpstr, two_digits);		sec = atoi((char *)two_digits);	}	(void)tmpstr.peekbyte(tmp);	if ((char)tmp != 'Z') {		tmpstr.fetchbyte(tmp);		sign = (char)tmp;		if (sign != '-' || sign != '+') {			return (E_DER_DECODE_BAD_TIME_STRING);		}		get_twodigits(tmpstr, two_digits);		offhr = atoi((char *)two_digits);		get_twodigits(tmpstr, two_digits);		offmin = atoi((char *)two_digits);		if (sign == '-') {			hour -= offhr;			min  -= offmin;		} else {			hour += offhr;			min  += offmin;		}	}	if ( (month > 12) || (day > 31) || (hour > 23) || (min > 59) ||	     (sec > 59) ) {		return (E_DER_DECODE_BAD_TIME_STRING);	}			PCTime tmptime(year, month, day, hour, min, sec);	time = tmptime;	return (SUCCESS);}byte num_to_mask(int i){	switch (i % 7) {	case 0:		return (0x80);	// shifted left seven, top 1 bit significant	case 1:		return (0xC0);	// shifted left six, top 2 bits significant	case 2:		return (0xE0);	// shifted left five, top 3 bits significant	case 3:		return (0xF0);	// shifted left four, top 4 bits	case 4:		return (0xF8);	// etc.	case 5:		return (0xFC);	case 6:		return (0xFE);	default:		printf("num_to_mask: unreachable code\n");		return (0);	}}/* * Decode an OBJECT-IDENTIFIER */int asn1_der_decode_obj_id(Bstream& der_stream, ObjId& objid){	byte tmp = 0;	byte tmp1 = 0;	int  len, tmp_len;	int  retval;	if (der_stream.getlength() < 2)		return (E_DER_DECODE_UNEXPECTED_EOS);	retval = der_stream.peekbyte(tmp);	if (tmp != OBJECT_IDENTIFIER_ID) {		return (E_DER_DECODE_BAD_ID_OCTET);	}	(void )der_stream.fetchbyte(tmp);	len = asn1_der_get_length(der_stream);	if (len < 0) return len;	if (len > der_stream.getlength()) 		return (E_DER_DECODE_UNEXPECTED_EOS);	int first_subid = TRUE;	while (len > 0) {		// For each sub id, figure out size by peeking		// into the stream.		int subid_len = 0;		for ( (void) der_stream.peekbyte(tmp); (tmp & 0x80) ; 					(void)der_stream.peekbyte(tmp)) {			len--; 			if (len < 0) 				return (E_DER_DECODE_BAD_OBJID_SUBID);			if (subid_len == 0 && tmp == 0x80)				return (E_DER_DECODE_BAD_OBJID_SUBID);			subid_len++;		}		subid_len++;			// account for last octet		len--; 		if (len < 0) 			return (E_DER_DECODE_BAD_OBJID_SUBID);		byte *subid_bits = new byte[subid_len];		tmp_len = subid_len;		while (tmp_len) {			der_stream.fetchbyte(subid_bits[tmp_len - 1]);			tmp_len--;		}		byte *subid_int = new byte[subid_len];		bzero(subid_int, subid_len);		tmp_len = subid_len;		for (int i = 0; i < tmp_len; i++) {			tmp = ((byte)(subid_bits[i] & 0x7f) >> (i % 7));			if ( i == (tmp_len - 1)) { // Most significant octet 				tmp1 = 0;			} else {				tmp1 = ((subid_bits[i+1] & 0x7f) << (7-(i%7)));				tmp1 &= num_to_mask(i);			}			tmp |= tmp1;			subid_int[tmp_len - (i+1)] = tmp;		}		Bigint I((unsigned char *)subid_int, subid_len);		delete subid_bits;		delete subid_int;		if (first_subid) {			Bigint X,Y;	// X, Y are 1st and 2nd subids rsp.			if (I < 80) {	// X == 0, or X == 1				if (I < 40)					X = (short)0;				else					X = 1;			} else {		// X == 2				X = 2;			} 			Y = I - X*40;			objid.add_element(X);			objid.add_element(Y);			first_subid = FALSE;		} else {			objid.add_element(I);		}	}	return (SUCCESS);}

⌨️ 快捷键说明

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