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

📄 pgpx509keys.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * X509 Key importing
 *
 * Copyright (C) 1996,1997,1998 Network Associates Inc. and affiliated companies.
 * All rights reserved
 *
 * $Id: pgpX509Keys.c,v 1.64 1999/05/19 22:34:03 hal Exp $
 */

#include "pgpConfig.h"

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

#include <string.h>
#include <ctype.h>

#include "pgpKDBInt.h"
#include "pgpTypes.h"
#include "pgpDebug.h"
#include "pgpMem.h"
#include "pgpRngPub.h"
#include "pgpRngPriv.h"
#include "pgpRngPars.h"
#include "pgpRngRead.h"
#include "pgpTrust.h"
#include "pgpTrstPkt.h"
#include "pgpContext.h"

#include "pgpX509Priv.h"
#include "pgpHashPriv.h"
#include "pgpPubKey.h"
#include "pgpOptionListPriv.h"
#include "pgpPktByte.h"
#include "pgpPipeline.h"
#include "pgpFileMod.h"
#include "pgpEncodePriv.h"
#include "pgpVMemMod.h"
#include "pgpAnnotate.h"
#include "pgpSigSpec.h"
#include "pgpTimeDate.h"

/* Use TIS ASN.1 compiler */
#include "pgpX509Cert_asn.h"

/* Whether or not to use short forms for X509 name conversions */
#ifndef PGP_X509SHORTNAMES
#define PGP_X509SHORTNAMES 1
#endif

#define CHKNONNULL(p,e)	if (IsNull(p)) { \
							(e) = kPGPError_OutOfMemory; \
							goto error; \
						}

#define CHKASNERR(e)	if ((e) != 0) { \
							if ((e) == kPGPASNError_ErrOutOfMemory) { \
								(e) = kPGPError_OutOfMemory; \
							} else { \
								(e) = k509Error_InvalidCertificateFormat; \
							} \
							goto error; \
						}

/* Error returns */
#define k509Error_NeededCertNotAvailable			-10
#define k509Error_SelfSignedCert					-20
#define k509Error_InvalidCertificateSignature		-30
#define k509Error_InvalidCertificateFormat			-40


/* Size limit on cert */
#define MAX_509_CERT_SIZE		65536

/* Commonly used tag values */
#define TAG_ZERO			0
#define TAG_INTEGER			2
#define TAG_BITSTRING		3
#define TAG_OCTETSTRING		4
#define TAG_NULL			5
#define TAG_OBJECT			6
#define TAG_SEQUENCE		16
#define	TAG_SET				17
#define TAG_PRINTABLE		19
#define TAG_T61STRING		20
#define TAG_IA5STRING		22
#define TAG_UTCTIME			23
#define TAG_GENERALIZEDTIME	24
#define TAG_CONSTRUCTED		32

/* Tagging values for CHOICE fields */
#define ASN_EXPLICIT		0x80|0x20
#define ASN_IMPLICIT		0x80
#define ASN_GENERALNAME_RFC822NAME		(1|ASN_EXPLICIT)
#define ASN_GENERALNAME_DNSNAME			(2|ASN_EXPLICIT)
#define ASN_GENERALNAME_DIRECTORYNAME	(4|ASN_EXPLICIT)
#define ASN_GENERALNAME_URI				(6|ASN_EXPLICIT)
#define ASN_GENERALNAME_IPADDRESS		(7|ASN_EXPLICIT)
#define ASN_GENERALNAME_REGISTEREDID	(8|ASN_EXPLICIT)
#define ASN_DPNAME_GENERALNAMES			(0|ASN_EXPLICIT)


#define elemsof(arr)  (sizeof(arr)/sizeof(arr[0]))

#define EXPECT(t, v)	if (t != v) { \
							err = kPGPError_X509InvalidCertificateFormat; \
							goto error; \
						}


/* Our inserted Description or OU value */
static char	s_pgpdescr[] = "PGPKeyCreation=0x";

/* RSA OID is (1, 2, 840, 113549, 1, 1, 1) */
static PGPByte const rsaoid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
							  0x0d, 0x01, 0x01, 0x01};
/* RSA with MD5 OID is (1, 2, 840, 113549, 1, 1, 4) */
static PGPByte const rsamd5oid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
							  0x0d, 0x01, 0x01, 0x04};
/* RSA with MD2 OID is (1, 2, 840, 113549, 1, 1, 2) */
static PGPByte const rsamd2oid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
							  0x0d, 0x01, 0x01, 0x02};
/* RSA with SHA OID is (1, 2, 840, 113549, 1, 1, 5) */
static PGPByte const rsashaoid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7,
							  0x0d, 0x01, 0x01, 0x05};

/* DSA OID is (1, 2, 840, 10040, 4, 1) */
static PGPByte const dsaoid[] = {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01};
/* DSA with SHA-1 OID is (1, 2, 840, 10040, 4, 3) */
static PGPByte const dsashaoid1[] = {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x03};
/* Another variant (1 3 14 3 2 27) */
static PGPByte const dsashaoid2[] = {0x2b, 0x0e, 0x03, 0x02, 0x1b};

/* ElG OID is (1, 2, 840, 10046, 2, 1) */
static PGPByte const elgoid[] = {0x2a, 0x86, 0x48, 0xce, 0x3e, 0x02, 0x01};

/* CN (common-name) OID is (2, 5, 4, 3) */
static PGPByte const cnoid[] = {0x55, 0x04, 0x03};
/* RSA's OID for email address in RDN's: (1, 2, 840, 113549, 1, 9, 1) */
static PGPByte const emailoid[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
									0x09, 0x01};
static const char emailname[] = "EMAIL";

/* Issuer, subject alternative names (2, 5, 29, 17) and (2, 5, 29, 18) */
static PGPByte const issaltnameoid[] = {0x55, 0x1d, 0x11};
static PGPByte const subaltnameoid[] = {0x55, 0x1d, 0x12};

/* Extensions */
/* Basic constraints (2, 5, 29, 19) */
static PGPByte const bconstraintsoid[] = {0x55, 0x1d, 0x13};
/* Key usage (2, 5, 29, 15) */
static PGPByte const keyusageoid[] = {0x55, 0x1d, 0x0f};
/* Issuer Distribution Point (2, 5, 29, 28) */
static PGPByte const issdistpoint[] = {0x55, 0x1d, 0x1c};
/* Certificate Distribution Point (2, 5, 29, 31) */
static PGPByte const certdistpoint[] = {0x55, 0x1d, 0x1f};

/* Need an OID for PGP extension */
/* PGP root is (1 3 6 1 4 1 3401 8), append (1 1) for us */
static PGPByte const pgpextensionoid[] = {0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
										 0x01, 0x9a, 0x49, 0x08, 0x01, 0x01};



/* Table to convert DN field OID's to letter codes per RFC2253 */
/* Indexed by the last value in a (2, 5, 4, X) OID */
static const char *dnnames[] = {
	NULL, NULL, NULL,
	"CN",			/* 3 == commonName */
	NULL, NULL,
	"C",			/* 6 == countryName */
	"L",			/* 7 == localityName */
	"ST",			/* 8 == stateOrProvinceName */
	"STREET",		/* 9 == streetAddress */
	"O",			/* 10 == organizationName */
	"OU",			/* 11 == organizationalUnitName */
};


#if PRINTDEBUG509
/* Used for debugging, to print out the tags as we see them */
static struct {
	int tag;
	char *name;
} const tagnames[] = {
	{TAG_INTEGER,		"Integer"},
	{TAG_BITSTRING,		"Bitstring"},
	{TAG_OCTETSTRING,	"Octetstring"},
	{TAG_NULL,			"Null"},
	{TAG_OBJECT,		"Object"},
	{TAG_SEQUENCE,		"Sequence"},
	{TAG_SET,			"Set"},
	{TAG_PRINTABLE,		"Printablestring"},
	{TAG_T61STRING,		"T61string"},
	{TAG_IA5STRING,		"IA5string"},
	{TAG_UTCTIME,		"UTCTime"}
	{TAG_GENERALIZEDTIME, "GeneralizedTime"}
};
#endif



#if PRINTDEBUG509
static void
printtagname (int tag)
{
	int i;
	int printed = 0;
	printf ("0x%02x", tag);
	for (i=0; i<sizeof(tagnames)/sizeof(tagnames[0]); ++i) {
		if (tagnames[i].tag == tag) {
			printf (" (%s)", tagnames[i].name);
			printed = 1;
			break;
		}
	}
	if (!printed)
		printf ("(<Unknown>)");
}
#endif


/* ASN memory management */

	static void *
sASNAlloc( PGPASN_MemoryMgr *asnmgr, size_t requestSize)
{
	PGPMemoryMgrRef mgr = asnmgr->customValue;
	return PGPNewData( mgr, (PGPSize)requestSize, 0);
}

	static int
sASNReAlloc( PGPASN_MemoryMgr *asnmgr, void **allocation,
			 size_t newAllocationSize )
{
	PGPMemoryMgrRef mgr = asnmgr->customValue;
	return (int)PGPReallocData( mgr, allocation, newAllocationSize, 0);
}

	static int
sASNDeAlloc( PGPASN_MemoryMgr *asnmgr, void *allocation )
{
	(void) asnmgr;
	return (int)PGPFreeData( allocation );
}

	static void
sSetupASNCONTEXT (PGPMemoryMgrRef mgr, PGPASN_CONTEXT *asnctx,
				  PGPASN_MemoryMgr *asnmgr)
{
	asnctx->customValue = NULL;
	asnctx->memMgr = asnmgr;
	asnmgr->customValue = (void *)mgr;
	asnmgr->allocProc = sASNAlloc;
	asnmgr->reallocProc = sASNReAlloc;
	asnmgr->deallocProc = sASNDeAlloc;
}



/* Return bit number of highest bit in byte */
static int
hibit(int n)
{
	int bit = 7;
	int val = 0x80;

	if (n == 0)
		return -1;
	while ((val & n) == 0) {
		val >>= 1;
		--bit;
	}
	return bit;
}

#if 0
/* Unused */
/* Return the length of the DER length field for the specified length */
static PGPUInt32
_lenlen (PGPUInt32 length)
{
	if (length < 0x80)
		return 1;
	if (length < 0x100)
		return 2;
	if (length < 0x10000)
		return 3;
	if (length < 0x1000000)
		return 4;
	return 5;
}
#endif

/* Read start of an X.509 object */
static int
dotaglen(PGPByte **buf, PGPSize *length)
{
	PGPByte tag = *(*buf)++ & 0x1f;
	PGPSize len = *(*buf)++;
	if (len & 0x80) {
		PGPByte lenlen = len & 0x7f;
		len = 0;
		while (lenlen--) {
			len <<= 8;
			len |= *(*buf)++;
		}
	}
	*length = len;
#if PRINTDEBUG509
printf ("tag ");
printtagname(tag);
printf (", length 0x%x\n", len);
#endif
	return tag;
}

/* Read a three byte value and skip past it */
static int
dolen3(PGPByte **buf)
{
	int len;
	len = *(*buf)++;
	len <<= 8;
	len |= *(*buf)++;
	len <<= 8;
	len |= *(*buf)++;
	return len;
}


#if 0
/*
 * Convert an RFC2253 LDAP-format string to an X.509 PGPASN_Name
 * structure in *dname.
 * Any quoting used in input must be double quotes around
 * the whole value, as in O="Network Associates, Inc.".
 */
	static PGPError
sEncodeDN (PGPMemoryMgrRef mgr, PGPASN_CONTEXT *asnctx, char const *str,
	PGPASN_Name **pname)
{
	PGPASN_Name *name = NULL;
	PGPASN_RDNSequence *rdns ;
	PGPASN_RelativeDistinguishedName *rdn;
	PGPASN_AttributeTypeAndValue *atv;
	PGPASN_PrintableString *ps = NULL;	/* May be IA5String */
	PGPByte *psbuf = NULL;
	PGPSize psbufsize;
	char *s;
	char *eq, *cq, *com = NULL;
	PGPUInt32 i = 0;
	PGPSize slen;
	char *scopy;
	PGPBoolean email;
	PGPError err = kPGPError_NoErr;
	PGPByte oid[sizeof(emailoid)];
	PGPSize oidsize;

	*pname = NULL;

	slen = strlen(str);
	scopy = PGPNewData( mgr, slen+1, 0 );
	pgpCopyMemory( str, scopy, slen+1 );
	s = scopy;

	name = pgpasn_NewName (asnctx);
	CHKNONNULL( name, err );
	rdns = pgpasn_NewRDNSequence (asnctx);
	CHKNONNULL( rdns, err );
	name->CHOICE_field_type = PGPASN_ID_RDNSequence;
	name->data = rdns;

	while (*s) {
		if ((eq = strchr(s, '=')) == NULL) {
			err = kPGPError_BadParams;
			goto error;
		}
		*eq = '\0';
		if( strcmp(emailname, s) == 0 ) {
			email = TRUE;
		} else {
			email = FALSE;
			for (i=0; i<elemsof(dnnames); ++i) {
				if (strcmp(dnnames[i], s) == 0)
					break;
			}
			if (i >= elemsof(dnnames)) {
				err = kPGPError_BadParams;
				goto error;
			}
		}
		s = eq + 1;
		if (*s == '"') {
			if ((cq = strchr(++s, '"')) == NULL) {
				err = kPGPError_BadParams;
				goto error;
			}
			*cq = '\0';
		} else {
			cq = NULL;
			if ((com = strchr(s, ',')) == NULL)
				com = s + strlen(s);
			*com = '\0';
		}
		/* At this point, s points at the value, null terminated. */
		/* i holds the index of the attribute, or email is true */

		++rdns->n;
		rdn = pgpasn_NewRelativeDistinguishedName (asnctx);
		CHKNONNULL( rdn, err );
		rdns->elt[rdns->n++] = rdn;
		atv = pgpasn_NewAttributeTypeAndValue (asnctx);
		CHKNONNULL( atv, err );
		rdn->elt[0] = atv;
		rdn->n = 1;

		/* Insert attribute OID */
		if( email ) {
			oidsize = sizeof(emailoid);
			pgpCopyMemory( emailoid, oid, oidsize );
		} else {
			oidsize = sizeof(cnoid);
			pgpCopyMemory( cnoid, oid, oidsize );
			oid[oidsize-1] = i;
		}
		pgpasn_PutOctVal (asnctx, &atv->type, oid, oidsize);

		/* Insert attribute value */
		ps = pgpasn_NewPrintableString (asnctx);
		CHKNONNULL( ps, err );
		pgpasn_PutOctVal (asnctx, ps, s, strlen(s));
		psbufsize = pgpasn_SizeofPrintableString (asnctx, ps, TRUE);
		psbuf = PGPNewData( mgr, psbufsize, 0 );
		CHKNONNULL( psbuf, err );
		if( email )
			pgpasn_PackIA5String( asnctx, psbuf, psbufsize, ps, &err );
		else
			pgpasn_PackPrintableString( asnctx, psbuf, psbufsize, ps, &err );
		CHKASNERR( err );
		pgpasn_PutOctVal (asnctx, &atv->value, psbuf, psbufsize);
		PGPFreeData( psbuf );
		psbuf = NULL;
		pgpasn_FreePrintableString( asnctx, ps );
		ps = NULL;

		if (cq) {
			s = cq+2;
			if (s[-1] != ',') {
				err = kPGPError_BadParams;
				goto error;
			}
		} else {
			s = com+1;
		}
	}

	PGPFreeData( scopy );
	*pname = name;

	return kPGPError_NoErr;

 error:
	if (scopy)
		PGPFreeData( scopy );
	if (ps)
		pgpasn_FreePrintableString( asnctx, ps );
	if (psbuf)
		PGPFreeData( psbuf );
	if (name)
		pgpasn_FreeName( asnctx, name );
	return err;

⌨️ 快捷键说明

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