| RSA BSAFE Cert-C |
Certificate Components for C |
| Crypto-C 6.2.1 Developer's Guide | ||
| Search |
/* $Id: extnhlp.c,v 1.7 2005/02/25 06:09:30 alockwoo Exp $ */ /* extnhlp.c ** Copyright (c) 1999-2003, RSA Security Inc. ** ** This file is used to demonstrate how to interface to an RSA Security ** licensed development product. You have a royalty-free right to use, ** modify, reproduce and distribute this demonstration file (including ** any modified version), provided that you agree that RSA Security has ** no warranty, implied or otherwise, or liability for this demonstration ** file or any modified version. ** ** This file contains routines used by extnutil.c to print and read ** information from various certificate extension structures. */ #ifdef _MSC_VER # pragma warning (disable: 171) /* invalid type conversion (often of very similar ptrs) */ #endif #include "extnhlp.h" #include "nameutil.h" #include "timeutil.h" int PrintBasicConstraintsInfo (POINTER info) { int status = 0; BASIC_CONSTRAINTS *bcInfo = (BASIC_CONSTRAINTS *)NULL_PTR; bcInfo = (BASIC_CONSTRAINTS *)info; switch (bcInfo->subjectType) { case SUBJECT_TYPE_END_ENTITY: RSA_PrintMessage (" SUBJECT_TYPE_END_ENTITY\n"); break; case SUBJECT_TYPE_CA: RSA_PrintMessage (" SUBJECT_TYPE_CA\n"); break; default: RSA_PrintMessage (" Unrecognized value for subject type = %u\n", bcInfo->subjectType); } switch (bcInfo->pathLenConstraint) { case NOT_IN_USE: /* if the cert is for an end entity, pathLenConstraint does not apply */ break; case UNLIMITED_PATH_LEN: RSA_PrintMessage (" Certification path length unlimited\n"); break; default: RSA_PrintMessage (" Certification path length = %i\n", bcInfo->pathLenConstraint); } return status; } /* end PrintBasicConstraintsInfo */ int BasicConstraintsInfoPrompt (POINTER info) { int status = 0; /* Set up menu information for subject type */ RSA_DEMO_TABLE_ENTRY stTable[2]; RSA_DEMO_TABLE_ENTRY *choice = (RSA_DEMO_TABLE_ENTRY *)NULL_PTR; BASIC_CONSTRAINTS *bcInfo = (BASIC_CONSTRAINTS *)NULL_PTR; bcInfo = (BASIC_CONSTRAINTS *)info; stTable[0].description = "End Entity"; stTable[0].val.value = SUBJECT_TYPE_END_ENTITY; stTable[1].description = "Certificate Authority"; stTable[1].val.value = SUBJECT_TYPE_CA; RSA_PrintMessage ("Choices for Subject Type\n"); status = ChooseTableEntryPrompt (stTable, sizeof (stTable) / sizeof (RSA_DEMO_TABLE_ENTRY), &choice); if (status != 0) goto CLEANUP; bcInfo->subjectType = choice->val.value; if (bcInfo->subjectType == SUBJECT_TYPE_END_ENTITY) bcInfo->pathLenConstraint = NOT_IN_USE; else status = RSA_GetInteger (&bcInfo->pathLenConstraint, "Enter a value for \ the path length constraint (blank for unlimited)"); if (status == RSA_DEMO_E_CANCEL) { bcInfo->pathLenConstraint = UNLIMITED_PATH_LEN; status = 0; } else if (status != 0) goto CLEANUP; CLEANUP: if (status != 0) RSA_PrintError ("GetBasicConstraintsInfo", status); return status; } /* end GetBasicConstraintsInfo */ int PrintKeyUsageValue (POINTER info) { int status = 0; UINT4 keyUsageValue; keyUsageValue = *(UINT4 *)info; if (keyUsageValue & CF_DIGITAL_SIGNATURE) RSA_PrintMessage (" CF_DIGITAL_SIGNATURE\n"); if (keyUsageValue & CF_NON_REPUDIATION) RSA_PrintMessage (" CF_NON_REPUDIATION\n"); if (keyUsageValue & CF_KEY_ENCIPHERMENT) RSA_PrintMessage (" CF_KEY_ENCIPHERMENT\n"); if (keyUsageValue & CF_DATA_ENCIPHERMENT) RSA_PrintMessage (" CF_DATA_ENCIPHERMENT\n"); if (keyUsageValue & CF_KEY_AGREEMENT) RSA_PrintMessage (" CF_KEY_AGREEMENT\n"); if (keyUsageValue & CF_KEY_CERT_SIGN) RSA_PrintMessage (" CF_KEY_CERT_SIGN\n"); if (keyUsageValue & CF_CRL_SIGN) RSA_PrintMessage (" CF_CRL_SIGN\n"); if (keyUsageValue & CF_ENCIPHER_ONLY) RSA_PrintMessage (" CF_ENCIPHER_ONLY\n"); if (keyUsageValue & CF_DECIPHER_ONLY) RSA_PrintMessage (" CF_DECIPHER_ONLY\n"); return status; } /* end PrintKeyUsageValue */ int KeyUsageValuePrompt (POINTER info) { int status = 0; /* Set up menu information for key usage information */ RSA_DEMO_TABLE_ENTRY kuTable[9]; RSA_DEMO_TABLE_ENTRY *choice = (RSA_DEMO_TABLE_ENTRY *)NULL_PTR; UINT4 *kuInfo = (UINT4 *)NULL_PTR; kuInfo = (UINT4 *)info; *kuInfo = 0; kuTable[0].description = "digital signature"; kuTable[0].val.value = CF_DIGITAL_SIGNATURE; kuTable[1].description = "nonrepudiation"; kuTable[1].val.value = CF_NON_REPUDIATION; kuTable[2].description = "key encipherment"; kuTable[2].val.value = CF_KEY_ENCIPHERMENT; kuTable[3].description = "data encipherment"; kuTable[3].val.value = CF_DATA_ENCIPHERMENT; kuTable[4].description = "key agreement"; kuTable[4].val.value = CF_KEY_AGREEMENT; kuTable[5].description = "key cert sign"; kuTable[5].val.value = CF_KEY_CERT_SIGN; kuTable[6].description = "CRL sign"; kuTable[6].val.value = CF_CRL_SIGN; kuTable[7].description = "encipher only"; kuTable[7].val.value = CF_ENCIPHER_ONLY; kuTable[8].description = "decipher only"; kuTable[8].val.value = CF_DECIPHER_ONLY; RSA_PrintMessage ("Choices for Key Usage Value\n"); /* Get one or more key usage values */ for (;;) { status = ChooseTableEntryPrompt (kuTable, sizeof (kuTable) / sizeof (kuTable[0]), &choice); if (status != 0) break; *kuInfo |= choice->val.value; } if (status == RSA_DEMO_E_CANCEL) status = 0; if (status != 0) RSA_PrintError ("KeyUsageValuePrompt", status); return status; } /* end KeyUsageValuePrompt */ /* Given a pointer to an extended key usage OID, contained in an * EXTENDED_KEY_USAGE structure, print out the information in a meaningful * way. */ int PrintExtendedKeyUsageValue (POINTER info) { int status = 0, i = 0; /* Set up menu information for extended key usage information */ RSA_DEMO_TABLE_ENTRY ekuTable[9]; EXTENDED_KEY_USAGE *ekuInfo = (EXTENDED_KEY_USAGE *)info; ekuTable[0].description = "TLS Web server authentication"; ekuTable[0].val.item.data = KP_SERVERAUTH; ekuTable[0].val.item.len = KP_SERVERAUTH_LEN; ekuTable[1].description = "TLS Web client authentication"; ekuTable[1].val.item.data = KP_CLIENTAUTH; ekuTable[1].val.item.len = KP_CLIENTAUTH_LEN; ekuTable[2].description = "Signing of downloadable executable code"; ekuTable[2].val.item.data = KP_CODESIGNING; ekuTable[2].val.item.len = KP_CODESIGNING_LEN; ekuTable[3].description = "E-mail protection"; ekuTable[3].val.item.data = KP_EMAILPROTECTION; ekuTable[3].val.item.len = KP_EMAILPROTECTION_LEN; ekuTable[4].description = "IPSec End System"; ekuTable[4].val.item.data = KP_IPSECENDSYSTEM; ekuTable[4].val.item.len = KP_IPSECENDSYSTEM_LEN; ekuTable[5].description = "IPSec Tunnel"; ekuTable[5].val.item.data = KP_IPSECTUNNEL; ekuTable[5].val.item.len = KP_IPSECTUNNEL_LEN; ekuTable[6].description = "IPSec User"; ekuTable[6].val.item.data = KP_IPSECUSER; ekuTable[6].val.item.len = KP_IPSECUSER_LEN; ekuTable[7].description = "Timestamping"; ekuTable[7].val.item.data = KP_TIMESTAMPING; ekuTable[7].val.item.len = KP_TIMESTAMPING_LEN; ekuTable[8].description = "OCSP Signing"; ekuTable[8].val.item.data = KP_OCSPSIGNING; ekuTable[8].val.item.len = KP_OCSPSIGNING_LEN; for (i = 0; i < sizeof (ekuTable) / sizeof (ekuTable[0]); i++) if (T_memcmp (ekuInfo->keyUsagePurpose.data, ekuTable[i].val.item.data, ekuTable[i].val.item.len) == 0 && ekuTable[i].val.at.len == ekuInfo->keyUsagePurpose.len) { RSA_PrintMessage (" %s\n", ekuTable[i].description); break; } return status; } /* end PrintExtendedKeyUsageValue */ int ExtendedKeyUsageValuePrompt (POINTER info) { int status = 0; /* Set up menu information for extended key usage information */ RSA_DEMO_TABLE_ENTRY ekuTable[8]; RSA_DEMO_TABLE_ENTRY *choice = (RSA_DEMO_TABLE_ENTRY *)NULL_PTR; EXTENDED_KEY_USAGE *ekuInfo = (EXTENDED_KEY_USAGE *)info; ekuTable[0].description = "TLS Web server authentication"; ekuTable[0].val.item.data = KP_SERVERAUTH; ekuTable[0].val.item.len = KP_SERVERAUTH_LEN; ekuTable[1].description = "TLS Web client authentication"; ekuTable[1].val.item.data = KP_CLIENTAUTH; ekuTable[1].val.item.len = KP_CLIENTAUTH_LEN; ekuTable[2].description = "Signing of downloadable executable code"; ekuTable[2].val.item.data = KP_CODESIGNING; ekuTable[2].val.item.len = KP_CODESIGNING_LEN; ekuTable[3].description = "E-mail protection"; ekuTable[3].val.item.data = KP_EMAILPROTECTION; ekuTable[3].val.item.len = KP_EMAILPROTECTION_LEN; ekuTable[4].description = "IPSec End System"; ekuTable[4].val.item.data = KP_IPSECENDSYSTEM; ekuTable[4].val.item.len = KP_IPSECENDSYSTEM_LEN; ekuTable[5].description = "IPSec Tunnel"; ekuTable[5].val.item.data = KP_IPSECTUNNEL; ekuTable[5].val.item.len = KP_IPSECTUNNEL_LEN; ekuTable[6].description = "IPSec User"; ekuTable[6].val.item.data = KP_IPSECUSER; ekuTable[6].val.item.len = KP_IPSECUSER_LEN; ekuTable[7].description = "Timestamping"; ekuTable[7].val.item.data = KP_TIMESTAMPING; ekuTable[7].val.item.len = KP_TIMESTAMPING_LEN; RSA_PrintMessage ("Choices for Extended Key Usage Value\n"); status = ChooseTableEntryPrompt (ekuTable, sizeof (ekuTable) / sizeof (ekuTable[0]), &choice); if (status != 0) goto CLEANUP; ekuInfo->keyUsagePurpose.data = choice->val.item.data; ekuInfo->keyUsagePurpose.len = choice->val.item.len; CLEANUP: if (status != 0) RSA_PrintError ("ExtendedKeyUsageValuePrompt", status); return status; } /* end ExtendedKeyUsageValuePrompt */ int PrintCertPolicyValue (POINTER info) { int status = 0; POLICY_INFO *policyInfo = (POLICY_INFO *)info; QualifierInfo *qualifierInfo = (QualifierInfo *)NULL_PTR; unsigned int i; RSA_PrintBuf ("Policy ID", policyInfo->policyID.data, policyInfo->policyID.len); for (i = 0; i < policyInfo->qualifierInfoCount; i++) { RSA_PrintMessage ("Qualifier #%u\n", i+1); qualifierInfo = policyInfo->qualifierInfo + i; RSA_PrintBuf ("Qualifier ID", qualifierInfo->qualifierID.data, qualifierInfo->qualifierID.len); if (qualifierInfo->qualifier.len == 0) RSA_PrintMessage ("Qualifier omitted.\n"); else RSA_PrintBuf ("Qualifier", qualifierInfo->qualifier.data, qualifierInfo->qualifier.len); } if (status != 0) RSA_PrintError ("PrintCertPolicyValue", status); return status; } /* end PrintCertPolicyValue */ int CertPolicyValuePrompt (POINTER info) { int status = 0, i = 0; POLICY_INFO *policyInfo = (POLICY_INFO *)info; QualifierInfo *currentQualifierInfo = (QualifierInfo *)NULL_PTR; ITEM qualifierId = {NULL, 0}; POINTER ptr; T_memset ((POINTER)policyInfo, 0, sizeof (POLICY_INFO)); status = RSA_GetItem (&policyInfo->policyID, "Enter hex-ascii Policy ID OID value"); if (status != 0) goto CLEANUP; for (i = 0; /* no max number of QualifierInfos */; i++) { status = RSA_GetItem (&qualifierId, "Enter hex-ascii Qualifier ID OID value (blank to finish)"); if (status != 0) { status = 0; /* no more qualifier infos, which is okay */ break; } /* At this point, we know we have a qualifier info */ policyInfo->qualifierInfoCount++; ptr = T_realloc ((POINTER)policyInfo->qualifierInfo, sizeof (QualifierInfo) * policyInfo->qualifierInfoCount); if (ptr == NULL_PTR) { status = RSA_DEMO_E_ALLOC; goto CLEANUP; } policyInfo->qualifierInfo = (QualifierInfo *) ptr; currentQualifierInfo = policyInfo->qualifierInfo + i; /* This is allocated by RSA_GetItem and must be freed in DestroyPolicyValueInternals */ currentQualifierInfo->qualifierID.data = qualifierId.data; currentQualifierInfo->qualifierID.len = qualifierId.len; /* currentQualifierInfo->qualifier.data must also be freed by DestroyPolicyValueInternals */ status = RSA_GetItem (¤tQualifierInfo->qualifier, "Enter hex-ascii Policy Qualifier value (blank to omit)"); if (status == RSA_DEMO_E_CANCEL) status = 0; /* this is an optional field */ else if (status != 0) goto CLEANUP; } CLEANUP: if (status != 0) { DestroyPolicyValueInternals (info); RSA_PrintError ("CertPolicyValuePrompt", status); } return status; } /* end CertPolicyValuePrompt */ int DestroyPolicyValueInternals (POINTER info) { unsigned int i = 0; POLICY_INFO *policyInfo = (POLICY_INFO *)info; QualifierInfo *currentQualifierInfo = (QualifierInfo *)NULL_PTR; T_free (policyInfo->policyID.data); policyInfo->policyID.data = NULL; for (i = 0; i < policyInfo->qualifierInfoCount; i++) { currentQualifierInfo = policyInfo->qualifierInfo + i; T_free (currentQualifierInfo->qualifierID.data); currentQualifierInfo->qualifierID.data = NULL; T_free (currentQualifierInfo->qualifier.data); currentQualifierInfo->qualifier.data = NULL; } T_free ((POINTER)policyInfo->qualifierInfo); policyInfo->qualifierInfo = NULL; return 0; } /* end DestroyPolicyValueInternals */ int PrintPrivateKeyUsagePeriodValue (POINTER info) { int status = 0; PRIVATE_KEY_USAGE_PERIOD *privateKeyUsagePeriod = (PRIVATE_KEY_USAGE_PERIOD *)info; RSA_PrintGeneralizedTime ("Validity Start", &privateKeyUsagePeriod->start); RSA_PrintGeneralizedTime ("Validity End", &privateKeyUsagePeriod->end); return status; } /* end PrintPrivateKeyUsagePeriodValue */ int PrivateKeyUsagePeriodValuePrompt (POINTER info) { int status = 0; PRIVATE_KEY_USAGE_PERIOD *privateKeyUsagePeriod = (PRIVATE_KEY_USAGE_PERIOD *)info; /* Actually, RFC 2459 says that one of the two must be included. We could let Cert-C catch the error when the extension value is added, in the case where the user omits both. However, let's just require users to supply both, since RSA_GetInputToGeneralizedTime takes a blank to mean the current time. Unless there is reason to modify this to allow users to treat these fields as optional, we'll leave it as an exercise to the reader if it is desired. */ status = RSA_GetInputToGeneralizedTime (&privateKeyUsagePeriod->start, "Validity Start"); if (status != 0) goto CLEANUP; status = RSA_GetInputToGeneralizedTime (&privateKeyUsagePeriod->end, "Validity End"); if (status != 0) goto CLEANUP; CLEANUP: return status; } /* end PrivateKeyUsagePeriodValuePrompt */ int PrintCrlDistributionPointsValue (POINTER info) { int status = 0; unsigned int i, nameCount; DISTRIBUTION_POINT *distributionPoint = (DISTRIBUTION_POINT *)info; GENERAL_NAME *generalNamePtr; RSA_PrintMessage ("[TODO] Make this more general\n"); RSA_PrintMessage ("Distribution Point Name\n"); if (distributionPoint->distPointName->nameType == DPN_FULL_NAME) { RSA_PrintMessage (" Info contained in a GENERAL_NAMES structure\n"); /* [TODO] Make an RSA_PrintGeneralNames... */ nameCount = distributionPoint->distPointName->name.fullNames.nameCount; for (i = 0; i < nameCount; i++) { RSA_PrintMessage (" GENERAL_NAME #%u\n", i+1); generalNamePtr = distributionPoint->distPointName->name.fullNames.names + i; if (generalNamePtr->altNameType == CN_DIRECTORY_NAME) RSA_PrintNameObject ("Directory Name", generalNamePtr->altName.directoryName); else /* need to implement pretty print */ RSA_PrintMessage (" Not a directory name.\n"); } } else if (distributionPoint->distPointName->nameType == DPN_RELATIVE_NAME) RSA_PrintNameObject ((char *)NULL_PTR, distributionPoint->distPointName->name.nameRelativeToCRLIssuer); else RSA_PrintMessage (" Unrecognized DIST_POINT_NAME format\n"); RSA_PrintMessage ("Reasons:\n"); if (distributionPoint->reasons == DPR_NO_REASONS) RSA_PrintMessage (" Field Omitted\n"); else RSA_PrintMessage (" Other...\n"); RSA_PrintMessage ("CRL issuers:\n"); if (distributionPoint->cRLIssuers == (GENERAL_NAMES *)NULL_PTR) RSA_PrintMessage (" Field Omitted\n"); else RSA_PrintMessage (" There are CRL issuers.\n"); return status; } /* end PrintCrlDistributionPointsValue */ int CrlDistributionPointsValuePrompt (POINTER info) { int status; UNUSED_ARG (info); /* still need to implement this feature */ status = RSA_DEMO_E_NOT_IMPLEMENTED; return status; } /* end CrlDistributionPointsValuePrompt */ int DestroyCrlDistributionPointInternals (POINTER info) { int status = 0; UNUSED_ARG (info); return status; } /* end DestroyCrlDistributionPointInternals */ int PrintCrlNumberValue (POINTER info) { ITEM *crlNumberItem=(ITEM *)info; RSA_PrintBuf (" Base CRL Number = ", crlNumberItem->data, crlNumberItem->len); return 0; } /* end PrintCrlNumberValue */ int CrlNumberValuePrompt (POINTER info) { ITEM *crlNumberItem, input; int status; crlNumberItem = (ITEM *)info; status = RSA_GetItem (&input, "Enter CRL Number in hexadecimal (blank to cancel)"); if (status == 0) *crlNumberItem = input; return status; } /* end CrlNumberValuePrompt */ int PrintDeltaCrlValue (POINTER info) { ITEM *crlNumberItem=(ITEM *)info; RSA_PrintBuf (" Base CRL Number = ", crlNumberItem->data, crlNumberItem->len); return 0; } /* end PrintDeltaCrlValue */ int DeltaCrlValuePrompt (POINTER info) { ITEM *crlNumberItem, input; int status; crlNumberItem = (ITEM *)info; status = RSA_GetItem (&input, "Enter base CRL number in hexadecimal (blank to cancel)"); if (status == 0) *crlNumberItem = input; return status; } /* end DeltaCrlValuePrompt */ int PrintReasonCodeValue (POINTER info) { unsigned int reasonCodeValue; reasonCodeValue = *(unsigned int *)info; switch (reasonCodeValue) { case CR_UNSPECIFIED: RSA_PrintMessage (" CR_UNSPECIFIED\n"); break; case CR_KEY_COMPROMISE: RSA_PrintMessage (" CR_KEY_COMPROMISE\n"); break; case CR_CA_COMPROMISE: RSA_PrintMessage (" CR_CA_COMPROMISE\n"); break; case CR_AFFILIATION_CHANGED: RSA_PrintMessage (" CR_AFFILIATION_CHANGED\n"); break; case CR_SUPERSEDED: RSA_PrintMessage (" CR_SUPERSECED\n"); break; case CR_CESSATION_OF_OPERATION: RSA_PrintMessage (" CR_CESSATION_OF_OPERATION\n"); break; case CR_CERTIFICATE_HOLD: RSA_PrintMessage (" CR_CERTIFICATE_HOLD\n"); break; case CR_REMOVE_FROM_CRL: RSA_PrintMessage (" CR_REMOVE_FROM_CRL\n"); break; case CR_PRIVILEGE_WITHDRAWN: RSA_PrintMessage (" CR_PRIVILEGE_WITHDRAWN\n"); break; case CR_AA_COMPROMISE: RSA_PrintMessage (" CR_AA_COMPROMISE\n"); break; default: RSA_PrintMessage (" Unrecognized reason code value = %u\n", reasonCodeValue); } return 0; } /* end PrintReasonCodeValue */ int ReasonCodeValuePrompt (POINTER info) { int status = 0; /* Set up menu information for reason code value information */ RSA_DEMO_TABLE_ENTRY rcTable[10]; RSA_DEMO_TABLE_ENTRY *choice = (RSA_DEMO_TABLE_ENTRY *)NULL_PTR; unsigned int *rcInfo = (unsigned int *)NULL_PTR; rcInfo = (unsigned int *)info; *rcInfo = 0; rcTable[0].description = "unspecified"; rcTable[0].val.value = CR_UNSPECIFIED; rcTable[1].description = "key compromise"; rcTable[1].val.value = CR_KEY_COMPROMISE; rcTable[2].description = "CA compromise"; rcTable[2].val.value = CR_CA_COMPROMISE; rcTable[3].description = "affiliation changed"; rcTable[3].val.value = CR_AFFILIATION_CHANGED; rcTable[4].description = "superseded"; rcTable[4].val.value = CR_SUPERSEDED; rcTable[5].description = "cessation of operation"; rcTable[5].val.value = CR_CESSATION_OF_OPERATION; rcTable[6].description = "certificate hold"; rcTable[6].val.value = CR_CERTIFICATE_HOLD; rcTable[7].description = "remove from CRL"; rcTable[7].val.value = CR_REMOVE_FROM_CRL; rcTable[8].description = "privilege withdrawn from CRL"; rcTable[8].val.value = CR_PRIVILEGE_WITHDRAWN; rcTable[9].description = "AA compromise"; rcTable[9].val.value = CR_AA_COMPROMISE; RSA_PrintMessage ("Choices for Reason Code Value\n"); status = ChooseTableEntryPrompt (rcTable, sizeof (rcTable) / sizeof (rcTable[0]), &choice); if (status != 0) goto CLEANUP; *rcInfo = choice->val.value; CLEANUP: if (status != 0) RSA_PrintError ("ReasonCodeValuePrompt", status); return status; } /* end ReasonCodeValuePrompt */ int PrintGenericExtenValue (POINTER info) { int status = 0; ITEM *value = (ITEM *)info; RSA_PrintBuf ("Value", value->data, value->len); return status; } /* end PrintGenericExtenValue */