📄 dname.c
字号:
else
sprintf(temp, "%ld.", intOID->oid_elements[i]);
strcat(string, temp);
}
if (intOID->oid_elements != NULL)
TC_Free(mgr, intOID->oid_elements);
TC_Free(mgr, intOID);
return 0;
} /* OidToString */
/*****
*
* CreateAVADERFromString
*
* Given the string value provided by the user and the AVA ASN.1 type it
* should be, create the DER for the AVA's type field. This uses the
* compiler generated code for creating the DER, so that if the provided
* string does not meet the requirements for the ASN.1 type, an error
* will be reported. For instance, if you provide an e-mail address for
* a PrintableString type it will fail.
*
* TODO: a future version of this code should be able to dynamically change
* the ASN.1 type used if the provided string is not allowed for the default
* ASN.1 type in avaInfo. So, following PKIX, if PrintableString doesn't
* work, next try BMPString and finally use UTF8String.
*
* Parameters
* input
* string - the character data to use in the DER
* strLen
* avaInfo - contains the ASN.1 type for the AVA
* context -
*
* output
* der - filled in with the DER for the type field of the AVA or NULL
* if error
* derLen
*
* return
* 0
* TC_E_INVARGS
* TC_E_NOMEMORY
* TC_E_BADNUMERICSTRING
* TC_E_BADPRINTABLESTRING
* TC_E_PARSE
* TC_E_BADDNAMESTRINGTYPE
*****/
static int CreateAVADERFromString(
unsigned char *string,
size_t strLen,
TC_AVA_ENTRY *avaInfo,
unsigned char **der,
size_t *derLen,
TC_CONTEXT *context)
{
int ret = 0;
if (der == NULL || derLen == NULL || avaInfo == NULL || string == NULL)
return TC_E_INVARGS;
switch (avaInfo->asnType) {
case PKIID_PrintableString:
{
PKIPrintableString *asnstruct;
asnstruct = PKINewPrintableString(context->certasnctx);
if (asnstruct == NULL) {
ret = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(context->certasnctx, asnstruct,
string, strLen);
*derLen = PKISizeofPrintableString(context->certasnctx,
asnstruct, 1);
*der = TC_Alloc(context->memMgr, *derLen);
if (*der == NULL) {
PKIFreePrintableString(context->certasnctx, asnstruct);
ret = TC_E_NOMEMORY;
break;
}
(void)PKIPackPrintableString(context->certasnctx, *der, *derLen,
asnstruct, &ret);
if (ret != 0)
ret = compiler2tc_error(ret);
PKIFreePrintableString(context->certasnctx, asnstruct);
break;
}
case PKIID_NumericString:
{
PKINumericString *asnstruct;
asnstruct = PKINewNumericString(context->certasnctx);
if (asnstruct == NULL) {
ret = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(context->certasnctx, asnstruct,
string, strLen);
*derLen = PKISizeofNumericString(context->certasnctx,
asnstruct, 1);
*der = TC_Alloc(context->memMgr, *derLen);
if (*der == NULL) {
PKIFreeNumericString(context->certasnctx, asnstruct);
ret = TC_E_NOMEMORY;
break;
}
(void)PKIPackNumericString(context->certasnctx, *der, *derLen,
asnstruct, &ret);
if (ret != 0)
ret = compiler2tc_error(ret);
PKIFreeNumericString(context->certasnctx, asnstruct);
break;
}
case PKIID_IA5String:
{
PKIIA5String *asnstruct;
asnstruct = PKINewIA5String(context->certasnctx);
if (asnstruct == NULL) {
ret = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(context->certasnctx, asnstruct,
string, strLen);
*derLen = PKISizeofIA5String(context->certasnctx,
asnstruct, 1);
*der = TC_Alloc(context->memMgr, *derLen);
if (*der == NULL) {
PKIFreeIA5String(context->certasnctx, asnstruct);
ret = TC_E_NOMEMORY;
break;
}
(void)PKIPackIA5String(context->certasnctx, *der, *derLen,
asnstruct, &ret);
if (ret != 0)
ret = compiler2tc_error(ret);
PKIFreeIA5String(context->certasnctx, asnstruct);
break;
}
case PKIID_T61String:
{
PKIT61String *asnstruct;
asnstruct = PKINewT61String(context->certasnctx);
if (asnstruct == NULL) {
ret = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(context->certasnctx, asnstruct,
string, strLen);
*derLen = PKISizeofT61String(context->certasnctx,
asnstruct, 1);
*der = TC_Alloc(context->memMgr, *derLen);
if (*der == NULL) {
PKIFreeT61String(context->certasnctx, asnstruct);
ret = TC_E_NOMEMORY;
break;
}
(void)PKIPackT61String(context->certasnctx, *der, *derLen,
asnstruct, &ret);
if (ret != 0)
ret = compiler2tc_error(ret);
PKIFreeT61String(context->certasnctx, asnstruct);
break;
}
case PKIID_VisibleString:
{
PKIVisibleString *asnstruct;
asnstruct = PKINewVisibleString(context->certasnctx);
if (asnstruct == NULL) {
ret = TC_E_NOMEMORY;
break;
}
PKIPutOctVal(context->certasnctx, asnstruct,
string, strLen);
*derLen = PKISizeofVisibleString(context->certasnctx,
asnstruct, 1);
*der = TC_Alloc(context->memMgr, *derLen);
if (*der == NULL) {
PKIFreeVisibleString(context->certasnctx, asnstruct);
ret = TC_E_NOMEMORY;
break;
}
(void)PKIPackVisibleString(context->certasnctx, *der, *derLen,
asnstruct, &ret);
if (ret != 0)
ret = compiler2tc_error(ret);
PKIFreeVisibleString(context->certasnctx, asnstruct);
break;
}
/* the reset are currently not supported */
default:
ret = TC_E_BADDNAMESTRINGTYPE;
break;
} /* switch */
if (ret != 0) {
if (*der != NULL) {
TC_Free(context->memMgr, *der);
*der = NULL;
}
*derLen = 0;
}
return ret;
} /* CreateAVADERFromString */
/*****
*
* tc_create_dname
*
* Initialize a Name structure for Dname creation
*
* parameters
* output
* name - pointer to a Name pointer
*
* return
* 0 - okay
* TC_E_INVARGS
* TC_E_NOMEMORY
*****/
int tc_create_dname(TC_Name **dname, TC_CONTEXT *ctx)
{
PKIName *localname;
if (dname == NULL)
return TC_E_INVARGS;
*dname = NULL;
localname = PKINewName(ctx->certasnctx);
if (localname == NULL)
return TC_E_NOMEMORY;
localname->CHOICE_field_type = PKIID_RDNSequence;
localname->data = TC_Alloc(ctx->memMgr, sizeof (PKIRDNSequence) );
if (localname->data == NULL) {
PKIFreeName(ctx->certasnctx, localname);
return TC_E_NOMEMORY;
}
memset(localname->data, 0, sizeof (PKIRDNSequence) );
*dname = localname;
return 0;
} /* tc_create_dname */
int tc_free_dname(TC_Name *dname, TC_CONTEXT *ctx)
{
if (dname == NULL)
return TC_E_INVARGS;
PKIFreeName(ctx->certasnctx, dname);
return 0;
} /* tc_free_dname */
#define MEB_BUF_SIZE 1024
/*****
*
* tc_addAVAto_dname
*
* Add an AVA (attribute type and value) entry to a Dname. Currently
* this only supports one AVA per Relative Distinguished Name.
* The AVA will be added to the end of the current dname's RDN list.
* To add multiple AVA's use tc_make_dname_fromstring().
*
* This assumes that the correct DER value for the AVA is being
* provided (as defined by the attributes OID). It is the user's
* responsibility to make sure the correct (or allowed) ASN data
* types have been used. (eg., do not use SEQUENCE for country name,
* rather use PrintableString). If incorrect DER data is provided,
* the DER created for the Dname may not parse.
*
* parameters
* input
* oid - the oid of the AVA to add
* oidlen - length of above
* der - the attribute's value
* derlen - length of above
*
* output
* dname - the dname list to add the AVA entry to, updated
* with provided data
*
* returns
* 0 - okay
* TC_E_NOMEMORY
* TC_E_INVARGS
*****/
int tc_addAVAto_dname(
TC_Name *dname,
unsigned char *oid,
size_t oidlen,
unsigned char *der,
size_t derlen,
TC_CONTEXT *ctx)
{
PKIRDNSequence *rdnSeq;
PKIRelativeDistinguishedName *rdnName;
if (dname == NULL || oid == NULL || oidlen == 0 ||
der == NULL || derlen == 0)
return TC_E_INVARGS;
rdnSeq = (PKIRDNSequence *)dname->data;
if (rdnSeq->n == PKIMAX_RDNSequence)
return TC_E_OTHER;
rdnSeq->elt[rdnSeq->n] =
TC_Alloc(ctx->memMgr,
sizeof(PKIRelativeDistinguishedName));
if (rdnSeq->elt[rdnSeq->n] == NULL)
return TC_E_NOMEMORY;
rdnName = (PKIRelativeDistinguishedName *)rdnSeq->elt[rdnSeq->n];
/* TODO: fix, assumes only 1 ava */
rdnName->n = 1;
rdnName->elt[0] = TC_Alloc(ctx->memMgr, sizeof(PKIAttributeTypeAndValue) );
if (rdnName->elt[0] == NULL) {
TC_Free(ctx->memMgr, rdnSeq->elt[rdnSeq->n]);
return TC_E_NOMEMORY;
}
memset(rdnName->elt[0], 0, sizeof(PKIAttributeTypeAndValue));
(void)tc_set_avader(rdnName->elt[0],
oid,
oidlen,
der,
derlen,
ctx);
rdnSeq->n++;
return 0;
} /* tc_addAVAto_dname */
static void ReverseAVAOrder(PKIRDNSequence *seq)
{
int i, j;
void *temp;
i = 0;
j = seq->n - 1;
for ( ; i < j; i++, j-- ) {
temp = seq->elt[i];
seq->elt[i] = seq->elt[j];
seq->elt[j] = temp;
}
return;
}
void TrimWS(char *c)
{
char *end;
end = c + strlen(c) - 1;
while (isspace((int) (*end))) {
/* check to see if there is a delimited space at the end, don't
trim in this case and we're done */
if (*(end-1) == '\\')
return;
*end = '\0';
end--;
}
return;
}
/*****
* tc_make_dname_fromstring
*
* Given a string, create a DNAME held in a list of entries.
* The provided string basically follows the syntax defined in
* RFC 2253. The implementation does NOT support the quoted
* string syntax described in the RFC.
*
* examples:
* OU=Test Certificate Authority , O=NETA\, Inc. , L=Internet
* 1.2.3.4=#0306020133020144, OU=CA+OU=BE, CN=John Doe
*
* The created list will be in the reverse order of the provided string.
* This assumes folks are used to the leaf->root, left->right
* ordering common with written LDAP dnames and DNS.
*
* If the value provided for the attribute type is a string, then the
* attribute OID and ASN data type used for the AVA in the dname
* will be based on the values in the provided context. See
* tc_change_ava_entry and tc_add_ava for details on modifying the
* default list.
*
* If the value provided for the attribute type is
* a dotted decimal OID, then it is assmed the data after the "="
* is "#" followed by a hex representation of valid DER data.
* Note that if the data is not DER, then the created Dname's DER
* will probably not successfully parse.
*
* If there is a failure in any particular RDN portion, the processing
* will stop. All the RDN portions before the problem will be left in
* the dname object. You must call tc_free_dname() to clean up the dname
* object.
*
* The call also allows one to call it multiple times with the same dname
* object. The string values will be entered into the dname object (in the
* order given) at the end, then the whole list will be reversed. Not
* a very nice effect... Maybe this can be changed so this call be use used
* with individual RDNs as the provided string???
*
* parameters
* input
* name - the original string name
* context - a pointer to a valid context
*
* output
* dname - pointer to Name structure (created with tc_create_dname)
* filled in
*
* return
* 0 - okay
* TC_E_DNAMEPARSE
* TC_E_NAMETOOLONG
*
*****/
int tc_make_dname_fromstring (
TC_Name *dname,
const char *name,
TC_CONTEXT *context)
{
PKIRDNSequence *rdnSeq;
int status;
if (!dname || !name || !context)
return TC_E_INVARGS;
/* TODO: can probably get rid of this, tc_create_cert was
changed and doesn't call this anymore... */
/* If this wasn't a Name object created with tc_create_dname
then we need to initialize it. This happens, for example,
internal to tc_create_cert. */
if (dname->data == NULL) {
dname->CHOICE_field_type = PKIID_RDNSequence;
dname->data = TC_Alloc(context->memMgr, sizeof(PKIRDNSequence) );
if (dname->data == NULL)
return TC_E_NOMEMORY;
memset(dname->data, 0, sizeof(PKIRDNSequence) );
}
rdnSeq = (PKIRDNSequence *)dname->data;
/* no error, just no name */
if (name[0] == '\0')
return 0;
if ((status = ParseStringRDNSeq(rdnSeq, name, context)) != 0) {
PKIDropInPlaceRDNSequence(context->certasnctx, rdnSeq);
rdnSeq->n = 0;
return status;
}
/* the list is created in reverse order of provided names */
ReverseAVAOrder(rdnSeq);
return 0;
} /* tc_make_dname_fromstring */
static int ParseStringRDNSeq(
PKIRDNSequence *rdnSeq,
const char *name,
TC_CONTEXT *context)
{
PKIRelativeDistinguishedName *rdnName;
char *namePos, *rdnStart, *comma;
char *buf;
int status;
if (!rdnSeq)
return TC_E_INVARGS;
/* see if the structure is already full */
if (rdnSeq->n == PKIMAX_RDNSequence) {
return TC_E_NAMETOOLONG;
}
buf = TC_Alloc(context->memMgr, strlen(name)+1);
if (buf == NULL)
return TC_E_NOMEMORY;
strcpy(buf, name);
namePos = buf;
while(namePos != '\0' && rdnSeq->n < PKIMAX_RDNSequence) {
SKIPWS(namePos);
rdnStart = namePos;
for(;;) {
comma = strchr(namePos, ',');
/* last RDN in string */
if (comma == NULL) {
TrimWS(rdnStart);
namePos = '\0';
break;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -