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

📄 dname.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
 *
 * Copyright (c) 1998, Network Associates, Inc. and its affiliated Companies
 *
 ****************************************************************************/

#include <string.h>

/* we don't want strings.h for WIN32, but for PGP use we should really check
   PGP_WIN32, so we have the extra check in the #if */
#if !PGP_WIN32 && !defined(WIN32)
#include <strings.h>
#endif

#include "tc.h"
#include "cms.h"

#include "cms_proto.h"

typedef struct OIDentifier {
    int oid_nelem;               /* number of sub-identifiers */
    unsigned long *oid_elements; /* the (ordered) list of sub-identifiers */
} OID_T, *OID_P;

/*****
*  prototypes 
*****/
static int HexStringToUchar(
	unsigned char **der,
	size_t *derlen,
	const char *hexstr,
	TC_MemoryMgr *mgr);

static int HexCharsToUchar(unsigned char *hex, char *string);

static char *AVAToString(
     PKIAttributeTypeAndValue *ava,
     TC_CONTEXT *context);

static int ParseStringRDNSeq(
    PKIRDNSequence *rdnSeq,
    const char *name,
    TC_CONTEXT *context);

static int ParseStringAVA(
	PKIAttributeTypeAndValue *ava,
	const char *name,
	TC_CONTEXT *context);

static int UndelimitString(
        unsigned char **converted, size_t *length, const char *orig,
	TC_MemoryMgr *mgr);

static int CreateAVADERFromString(
        unsigned char *string, 
	size_t strLen,
	TC_AVA_ENTRY *avaInfo,
	unsigned char **der,
	size_t *derLen,
	TC_CONTEXT *context);

/*****
*
* Table to define the default printable tag value, the DER OID, and 
* the value's data type for a distinguised name AVA.  Some values
* for non-string types are currently commented out until we can
* handle them.
*
* Values for printable tags are based on the values in:
*  RFC2256, "A Summary of the X.500(96) User Schema for use with LDAPv3"
*
* Values for DC came from:
*  RFC2247, "Using Domains in LDAP/X.500"
*
* Values for email address, unstructured name, and unstructured address
* came from:
*  PKCS #9 "Selected Attribute Types"
*
* Note: I have seen values for the following in print, but have not yet
* found the OID/type definitions
*	userid
*
*****/
static struct {
  const char *type;	/* the attribute type for a name */
  unsigned char oid[11];
  int oidlen;
  int  tag;	/* the base ASN.1 type (the default character set) */
} Types[] = {

/* common name */
{ "CN", { 0x55, 0x04, 0x03 }, 3, PKIID_PrintableString  },

/* surname */ 
{ "SN",  { 0x55, 0x04, 0x04 }, 3, PKIID_PrintableString },

{ "SerialNumber", { 0x55, 0x04, 0x05 }, 3, PKIID_PrintableString  },

/* country name */
{ "C",	{ 0x55, 0x04, 0x06 }, 3, PKIID_PrintableString  },

/* locality name */
{ "L",	{ 0x55, 0x04, 0x07 }, 3, PKIID_PrintableString },

/* state/province name */
{ "ST", { 0x55, 0x04, 0x08 }, 3, PKIID_PrintableString  },

/* street address */
{ "STREET", { 0x55, 0x04, 0x09 }, 3, PKIID_PrintableString  },

/* organization */
{ "O",  { 0x55, 0x04, 0x0a }, 3, PKIID_PrintableString  },

/* organization unit name */
{ "OU", { 0x55, 0x04, 0x0b }, 3, PKIID_PrintableString  },

{ "title",  { 0x55, 0x04, 0x0c }, 3, PKIID_PrintableString  },

{ "description", { 0x55, 0x04, 0x0d }, 3, PKIID_PrintableString  },

{ "businessCategory", { 55, 0x04, 0x0f }, 3, PKIID_PrintableString  },

/* postal address */
/* SEQ OF { "PA",  { 0x55, 0x04, 0x10 }, 3, ??? }, */

{ "postalCode", { 0x55, 0x04, 0x11 }, 3, PKIID_PrintableString  },

/* postOfficebox */
{ "POBOX", { 0x55, 0x04, 0x12 }, 3, PKIID_PrintableString  },

{ "physicalDeliveryOfficeName", { 0x55, 0x04, 0x13 }, 3, PKIID_PrintableString },

/* telephoneNumber */
{ "TN", { 0x55, 0x04, 0x14 }, 3, PKIID_PrintableString  },

/*  fax number */
/* SEQ { "FAX", { 0x55, 0x04, 0x17 }, 3, ???  }, */

{ "x121Address", { 0x55, 0x04, 0x18 }, 3, PKIID_NumericString  },

/* international ISDN number */
{ "ISDN", { 0x55, 0x04, 0x19 }, 3, PKIID_NumericString  },

{ "destinationIndicator", { 0x55, 0x04, 0x1b }, 3, PKIID_PrintableString  },

/* BIT STRING { "userPassword", { 0x55, 0x04, 0x23 }, 3, ??? },*/

{ "name", { 0x55, 0x04, 0x29 }, 3, PKIID_PrintableString  },

{ "givenName", { 0x55, 0x04, 0x2a }, 3, PKIID_PrintableString  },

{ "initials",  { 0x55, 0x04, 0x2b }, 3, PKIID_PrintableString  },

/* eg., 3rd */
{ "generationQualifier",  { 0x55, 0x04, 0x2c }, 3, PKIID_PrintableString  },

/*{ "x500UniqueIdentifier", { 0x55, 0x04, 0x2d }, 3, PKIID_BIT_STRING },*/

/* distinquished name qualifier */
{ "dnQualifier", { 0x55, 0x04, 0x2e }, 3, PKIID_PrintableString },

{ "houseIdentifier", { 0x55, 0x04, 0x33 }, 3, PKIID_PrintableString  },

/* directory management domain */
{ "dmdName", { 0x55, 0x04, 0x36 }, 3, PKIID_PrintableString  },

/* domain component, 0.9.2342.19200300.100.1.25 */
{ "DC", { 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19 }, 10, PKIID_IA5String },

/* e-mail name from pkcs-9 */
{ "emailAddress",  { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01 }, 9, PKIID_IA5String },

/* unstructued name from pkcs-9 */
{ "unstructuredName", { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x02 }, 9, PKIID_IA5String },

/* unstructed address from pkcs-9 */
{ "unstructuredAddress", { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x08 }, 9, PKIID_PrintableString },

{ NULL, { 0 }, 1, PKIID_NULL }

};

static int ValidASNType(int type)
{
    switch(type) {
    case TC_ASN_BOOLEAN:
    case TC_ASN_INTEGER:
    case TC_ASN_BIT_STRING :
    case TC_ASN_OCTET_STRING :
    case TC_ASN_NULL :
    case TC_ASN_OBJECT_ID :
    case TC_ASN_SEQUENCE :
    case TC_ASN_SET :
    case TC_ASN_NumericString :
    case TC_ASN_PrintableString :
    case TC_ASN_T61String :
    case TC_ASN_VideotexString :
    case TC_ASN_IA5String :
    case TC_ASN_UTCTime :
    case TC_ASN_GeneralizedTime :
    case TC_ASN_GraphicString :
    case TC_ASN_VisibleString :
    case TC_ASN_GeneralString :
    case TC_ASN_CHOICE :
        return 0;

    default:
        return -1;
    }
}


/*****
*
* InitAVAList
*
* Internal routine to set the default Dname AVA values in the
* context.
*
****/
int InitAVAList(TC_AVA_ENTRY **list, TC_MemoryMgr *memMgr)
{
    TC_AVA_ENTRY *entry;
    int i;

    if (list == NULL)
        return TC_E_INVARGS;
    *list = NULL;

    for (i = 0; Types[i].type; i++) {

        entry = TC_Alloc(memMgr, sizeof(TC_AVA_ENTRY));
        if (entry == NULL)
            return TC_E_NOMEMORY;

	entry->attributeType = TC_Alloc(memMgr, strlen(Types[i].type)+1 );
	if (entry->attributeType == NULL) {
	    TC_Free(memMgr, entry);
	    return TC_E_NOMEMORY;
	}
	strcpy(entry->attributeType, Types[i].type);

        entry->oid = TC_Alloc(memMgr, Types[i].oidlen);
        if (entry->oid == NULL) {
            /* TODO free whole list? */
	    TC_Free(memMgr, entry->attributeType);
	    TC_Free(memMgr, entry);
            return TC_E_NOMEMORY;
        }
        memcpy(entry->oid, Types[i].oid, Types[i].oidlen);
        entry->oidlen = Types[i].oidlen;
        entry->asnType = Types[i].tag;
        entry->next = *list;
        *list = entry;
    }

    return 0;

} /* InitAVAList */

void FreeAVAList(TC_AVA_ENTRY *list, TC_MemoryMgr *memMgr)
{
    TC_AVA_ENTRY *entry = list;
    TC_AVA_ENTRY *tmp;

    while (entry != NULL) {
	if (entry->attributeType != NULL)
	    TC_Free(memMgr, entry->attributeType);
	if (entry->oid != NULL)
	    TC_Free(memMgr, entry->oid);
	tmp = entry->next;
	TC_Free(memMgr, entry);
	entry = tmp;
    }

    return;
} /* FreeAVAList */

/*****
*
* tc_change_ava_entry
*
* Allows the user to update the default ASN type for an AVA
* in the context's list.
*
* parameters
*   input
*       oid - the AVA's oid
*       oidlen - length of above
*       newASNType - the new type for the AVA
*       context - pointer to an initialized context
*
* returns
*   TC_E_INVARGS
*   -1 (the provided oid is not in the list)
*   0
*****/
int tc_change_ava_entry(
        unsigned char *oid,
        size_t oidlen,
        int newASNType,
        TC_CONTEXT *context)
{
    TC_AVA_ENTRY *listentry = NULL;

    if (context == NULL || oid == NULL)
        return TC_E_INVARGS;

    if ( ValidASNType(newASNType) != 0)
        return TC_E_INVARGS;

    listentry = context->avaList;
    while(listentry) {

        if ((listentry->oidlen == oidlen) &&
            (memcmp(listentry->oid, oid, oidlen) == 0))
            break;

        listentry = listentry->next;
    }

    if (listentry == NULL)
        return  -1;

    listentry->asnType = newASNType;

    return 0;

} /* tc_change_ava_entry */


/*****
*
* tc_add_avatype
*
* Allows the user to add a new AVA definition to the list in the context.
* Then the user can provide string representations of a Dname with
* that AVA when using tc_make_dname_fromstring.  Also, Dname's containing
* that AVA will print successfully when using tc_extract_dname.
*
* parameters
*   input
*       oid - the oid for the AVA
*       oidlen - length of above
*       printableAttrName - the name to use for printable versions
*                   of this AVA (eg., "CN" or "unstructuredName")
*       asnType - the ASN.1 type for this AVA
*       context - pointer to an initialized context
*
* returns
*   TC_E_INVARGS
*   0
*****/
int tc_add_avatype(
        unsigned char *oid,
        size_t oidlen,
        const char *printableAttrName,
        int asnType,
        TC_CONTEXT *context)
{
    TC_AVA_ENTRY *entry;
    
    if (context == NULL || oid == NULL || oidlen == 0 ||
        printableAttrName == NULL)
        return TC_E_INVARGS;

    if ( ValidASNType(asnType) != 0)
        return TC_E_INVARGS;

    entry = TC_Alloc(context->memMgr, sizeof(TC_AVA_ENTRY));
    if (entry == NULL)
       return TC_E_NOMEMORY;

    entry->attributeType =
	TC_Alloc(context->memMgr, strlen(printableAttrName)+1 );
    if (entry->attributeType == NULL) {
	TC_Free(context->memMgr, entry);
	return TC_E_NOMEMORY;
    }
    strcpy(entry->attributeType, printableAttrName);

    entry->oid = TC_Alloc(context->memMgr, oidlen);
    if (entry->oid == NULL) {
	TC_Free(context->memMgr, entry->attributeType);
	TC_Free(context->memMgr, entry);
        return TC_E_NOMEMORY;
    }
    memcpy(entry->oid, oid, oidlen);
    entry->oidlen = oidlen;
    entry->asnType = asnType;
    entry->next = context->avaList;
    context->avaList = entry;

    return 0;

} /* tc_add_ava */


/*****
*
* Find the AVA entry in the context that has the printable
* name provided
*****/
static TC_AVA_ENTRY *lookupASNtype(
    const char *name,
    TC_CONTEXT *context)
{
  TC_AVA_ENTRY *avaEntry = context->avaList;

    while (avaEntry) {
        if (strcasecmp (name, avaEntry->attributeType) == 0)
            return avaEntry;
        avaEntry = avaEntry->next;
  }

  return NULL;
}

/*****
 *
 * Find an AVA entry in the context give the OID
 *
 *****/
static TC_AVA_ENTRY *lookupAVAByOID(
     PKIAttributeTypeAndValue *ava,
     TC_CONTEXT *context)
{
    TC_AVA_ENTRY *avaEntry = context->avaList;

    while(avaEntry) {
	if (ava->type.len == avaEntry->oidlen &&
	    memcmp(ava->type.val, avaEntry->oid, avaEntry->oidlen) == 0) 
	    return avaEntry;
	avaEntry = avaEntry->next;
    }
    return NULL;
} /* lookupAVAByOID */

/*****
 *
 * DERToOID
 *
 * a routine to convert from DER encoding to a list of integers 
 *
 *****/
static OID_T *DERToOID(
     unsigned char *derOid,
     size_t derOidLen,
     TC_MemoryMgr *mgr)
{
    unsigned long i;
    unsigned long *intElements;
    unsigned char *dataPtr, *endPtr;
    OID_T *oid = NULL;

    dataPtr = derOid;
    endPtr = dataPtr + derOidLen;

    /* Count the number of integer elements are in the OID,
       the first element will never be more than one byte
       so start with second DER value */
    for (i = 1; dataPtr < endPtr; i++) {
        if (*dataPtr == 0x80) /* incorrect format */
            return(oid);

        while (*dataPtr++ & 0x80)
            if (dataPtr > endPtr)
                return(oid);
    }

    oid = TC_Alloc(mgr, sizeof(OID_T));
    if (oid == NULL)
	return NULL;
    intElements = TC_Alloc(mgr, (i+1)*sizeof(unsigned long));
    if (intElements == NULL) {
	TC_Free(mgr, oid);
	return NULL;
    }

    oid->oid_elements = intElements;
    oid->oid_nelem = i;

    for (dataPtr = derOid; dataPtr < endPtr; ) {
        i = 0;
        do {
            i <<= 7;
            i |= *dataPtr & 0x7f;
        } while (*dataPtr++ & 0x80);
        if (intElements == oid->oid_elements) {
            *intElements++ = i / 40;
	    *intElements++ = i % 40;
	}
        else
            *intElements++ = i;
    }

    return oid;

} /* DERToOID */

/*****
 *
 * OidToString
 *
 * Convert a DER (hex) representation of an OID into a dotted
 * decimal string representataion.  It's assumed that the provided
 * string buffer is large enough.
 *
 *****/
static int OidToString(char *string, unsigned char *oid, size_t oidlen,
		       TC_MemoryMgr *mgr)
{
    int i;
    char temp[256];
    OID_T *intOID;

    if (!string)
	return -1;
    string[0] = '\0';

    intOID = DERToOID(oid, oidlen, mgr);
    if (intOID == NULL)
	return -1;

    for (i = 0; i < intOID->oid_nelem; i++) {

	if (i == intOID->oid_nelem-1)
	    sprintf(temp, "%ld", intOID->oid_elements[i]);

⌨️ 快捷键说明

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