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

📄 name.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2004 - 2007 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  */#include "hx_locl.h"#include <wind.h>RCSID("$Id: name.c 22583 2008-02-11 20:46:21Z lha $");/** * @page page_name PKIX/X.509 Names * * There are several names in PKIX/X.509, GeneralName and Name. * * A Name consists of an ordered list of Relative Distinguished Names * (RDN). Each RDN consists of an unordered list of typed strings. The * types are defined by OID and have long and short description. For * example id-at-commonName (2.5.4.3) have the long name CommonName * and short name CN. The string itself can be of serveral encoding, * UTF8, UTF16, Teltex string, etc. The type limit what encoding * should be used. * * GeneralName is a broader nametype that can contains al kind of * stuff like Name, IP addresses, partial Name, etc. * * Name is mapped into a hx509_name object. * * Parse and string name into a hx509_name object with hx509_parse_name(), * make it back into string representation with hx509_name_to_string(). * * Name string are defined rfc2253, rfc1779 and X.501. * * See the library functions here: @ref hx509_name */static const struct {    const char *n;    const heim_oid *(*o)(void);    wind_profile_flags flags;} no[] = {    { "C", oid_id_at_countryName },    { "CN", oid_id_at_commonName },    { "DC", oid_id_domainComponent },    { "L", oid_id_at_localityName },    { "O", oid_id_at_organizationName },    { "OU", oid_id_at_organizationalUnitName },    { "S", oid_id_at_stateOrProvinceName },    { "STREET", oid_id_at_streetAddress },    { "UID", oid_id_Userid },    { "emailAddress", oid_id_pkcs9_emailAddress },    { "serialNumber", oid_id_at_serialNumber }};static char *quote_string(const char *f, size_t len, size_t *rlen){    size_t i, j, tolen;    const char *from = f;    char *to;    tolen = len * 3 + 1;    to = malloc(tolen);    if (to == NULL)	return NULL;    for (i = 0, j = 0; i < len; i++) {	if (from[i] == ' ' && i + 1 < len)	    to[j++] = from[i];	else if (from[i] == ',' || from[i] == '=' || from[i] == '+' ||		 from[i] == '<' || from[i] == '>' || from[i] == '#' ||		 from[i] == ';' || from[i] == ' ')	{	    to[j++] = '\\';	    to[j++] = from[i];	} else if (((unsigned char)from[i]) >= 32 && ((unsigned char)from[i]) <= 127) {	    to[j++] = from[i];	} else {	    int l = snprintf(&to[j], tolen - j - 1,			     "#%02x", (unsigned char)from[i]);	    j += l;	}    }    to[j] = '\0';    assert(j < tolen);    *rlen = j;    return to;}static intappend_string(char **str, size_t *total_len, const char *ss, 	      size_t len, int quote){    char *s, *qs;    if (quote)	qs = quote_string(ss, len, &len);    else	qs = rk_UNCONST(ss);    s = realloc(*str, len + *total_len + 1);    if (s == NULL)	_hx509_abort("allocation failure"); /* XXX */    memcpy(s + *total_len, qs, len);    if (qs != ss)	free(qs);    s[*total_len + len] = '\0';    *str = s;    *total_len += len;    return 0;}static char *oidtostring(const heim_oid *type){    char *s;    size_t i;        for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) {	if (der_heim_oid_cmp((*no[i].o)(), type) == 0)	    return strdup(no[i].n);    }    if (der_print_heim_oid(type, '.', &s) != 0)	return NULL;    return s;}static intstringtooid(const char *name, size_t len, heim_oid *oid){    int i, ret;    char *s;        memset(oid, 0, sizeof(*oid));    for (i = 0; i < sizeof(no)/sizeof(no[0]); i++) {	if (strncasecmp(no[i].n, name, len) == 0)	    return der_copy_oid((*no[i].o)(), oid);    }    s = malloc(len + 1);    if (s == NULL)	return ENOMEM;    memcpy(s, name, len);    s[len] = '\0';    ret = der_parse_heim_oid(s, ".", oid);    free(s);    return ret;}/** * Convert the hx509 name object into a printable string. * The resulting string should be freed with free(). * * @param name name to print * @param str the string to return * * @return An hx509 error code, see hx509_get_error_string(). * * @ingroup hx509_name */inthx509_name_to_string(const hx509_name name, char **str){    return _hx509_Name_to_string(&name->der_name, str);}int_hx509_Name_to_string(const Name *n, char **str){    size_t total_len = 0;    int i, j;    *str = strdup("");    if (*str == NULL)	return ENOMEM;    for (i = n->u.rdnSequence.len - 1 ; i >= 0 ; i--) {	int len;	for (j = 0; j < n->u.rdnSequence.val[i].len; j++) {	    DirectoryString *ds = &n->u.rdnSequence.val[i].val[j].value;	    char *oidname;	    char *ss;	    	    oidname = oidtostring(&n->u.rdnSequence.val[i].val[j].type);	    switch(ds->element) {	    case choice_DirectoryString_ia5String:		ss = ds->u.ia5String;		break;	    case choice_DirectoryString_printableString:		ss = ds->u.printableString;		break;	    case choice_DirectoryString_utf8String:		ss = ds->u.utf8String;		break;	    case choice_DirectoryString_bmpString: {		uint16_t *bmp = ds->u.bmpString.data;		size_t bmplen = ds->u.bmpString.length;		size_t k;		ss = malloc(bmplen + 1);		if (ss == NULL)		    _hx509_abort("allocation failure"); /* XXX */		for (k = 0; k < bmplen; k++)		    ss[k] = bmp[k] & 0xff; /* XXX */		ss[k] = '\0';		break;	    }	    case choice_DirectoryString_teletexString:		ss = malloc(ds->u.teletexString.length + 1);		if (ss == NULL)		    _hx509_abort("allocation failure"); /* XXX */		memcpy(ss, ds->u.teletexString.data, ds->u.teletexString.length);		ss[ds->u.teletexString.length] = '\0';		break;	    case choice_DirectoryString_universalString: {		uint32_t *uni = ds->u.universalString.data;		size_t unilen = ds->u.universalString.length;		size_t k;		ss = malloc(unilen + 1);		if (ss == NULL)		    _hx509_abort("allocation failure"); /* XXX */		for (k = 0; k < unilen; k++)		    ss[k] = uni[k] & 0xff; /* XXX */		ss[k] = '\0';		break;	    }	    default:		_hx509_abort("unknown directory type: %d", ds->element);		exit(1);	    }	    append_string(str, &total_len, oidname, strlen(oidname), 0);	    free(oidname);	    append_string(str, &total_len, "=", 1, 0);	    len = strlen(ss);	    append_string(str, &total_len, ss, len, 1);	    if (ds->element == choice_DirectoryString_universalString ||		ds->element == choice_DirectoryString_bmpString ||		ds->element == choice_DirectoryString_teletexString)	    {		free(ss);	    }	    if (j + 1 < n->u.rdnSequence.val[i].len)		append_string(str, &total_len, "+", 1, 0);	}	if (i > 0)	    append_string(str, &total_len, ",", 1, 0);    }    return 0;}#define COPYCHARARRAY(_ds,_el,_l,_n)		\        (_l) = strlen(_ds->u._el);		\	(_n) = malloc((_l) * sizeof((_n)[0]));	\	if ((_n) == NULL)			\	    return ENOMEM;			\	for (i = 0; i < (_l); i++)		\	    (_n)[i] = _ds->u._el[i]#define COPYVALARRAY(_ds,_el,_l,_n)		\        (_l) = _ds->u._el.length;		\	(_n) = malloc((_l) * sizeof((_n)[0]));	\	if ((_n) == NULL)			\	    return ENOMEM;			\	for (i = 0; i < (_l); i++)		\	    (_n)[i] = _ds->u._el.data[i]#define COPYVOIDARRAY(_ds,_el,_l,_n)		\        (_l) = _ds->u._el.length;		\	(_n) = malloc((_l) * sizeof((_n)[0]));	\	if ((_n) == NULL)			\	    return ENOMEM;			\	for (i = 0; i < (_l); i++)		\	    (_n)[i] = ((unsigned char *)_ds->u._el.data)[i]static intdsstringprep(const DirectoryString *ds, uint32_t **rname, size_t *rlen){    wind_profile_flags flags = 0;    size_t i, len;    int ret;    uint32_t *name;    *rname = NULL;    *rlen = 0;    switch(ds->element) {    case choice_DirectoryString_ia5String:	COPYCHARARRAY(ds, ia5String, len, name);	break;    case choice_DirectoryString_printableString:	flags = WIND_PROFILE_LDAP_CASE_EXACT_ATTRIBUTE;	COPYCHARARRAY(ds, printableString, len, name);	break;    case choice_DirectoryString_teletexString:	COPYVOIDARRAY(ds, teletexString, len, name);	break;    case choice_DirectoryString_bmpString:	COPYVALARRAY(ds, bmpString, len, name);	break;    case choice_DirectoryString_universalString:	COPYVALARRAY(ds, universalString, len, name);	break;    case choice_DirectoryString_utf8String:	ret = wind_utf8ucs4_length(ds->u.utf8String, &len);	if (ret)	    return ret;	name = malloc(len * sizeof(name[0]));	if (name == NULL)	    return ENOMEM;	ret = wind_utf8ucs4(ds->u.utf8String, name, &len);	if (ret)	    return ret;	break;    default:	_hx509_abort("unknown directory type: %d", ds->element);    }    *rlen = len;    /* try a couple of times to get the length right, XXX gross */    for (i = 0; i < 4; i++) {	*rlen = *rlen * 2;	*rname = malloc(*rlen * sizeof((*rname)[0]));	ret = wind_stringprep(name, len, *rname, rlen,			      WIND_PROFILE_LDAP|flags);	if (ret == WIND_ERR_OVERRUN) {	    free(*rname);	    *rname = NULL;	    continue;	} else	    break;    }    free(name);    if (ret) {	if (*rname)	    free(*rname);	*rname = NULL;	*rlen = 0;	return ret;    }    return 0;}int_hx509_name_ds_cmp(const DirectoryString *ds1,		   const DirectoryString *ds2,		   int *diff){    uint32_t *ds1lp, *ds2lp;    size_t ds1len, ds2len;    int ret;    ret = dsstringprep(ds1, &ds1lp, &ds1len);    if (ret)	return ret;    ret = dsstringprep(ds2, &ds2lp, &ds2len);    if (ret) {	free(ds1lp);	return ret;    }    if (ds1len != ds2len)	*diff = ds1len - ds2len;    else	*diff = memcmp(ds1lp, ds2lp, ds1len * sizeof(ds1lp[0]));    free(ds1lp);    free(ds2lp);    return 0;}int_hx509_name_cmp(const Name *n1, const Name *n2, int *c){    int ret, i, j;    *c = n1->u.rdnSequence.len - n2->u.rdnSequence.len;    if (*c)	return 0;    for (i = 0 ; i < n1->u.rdnSequence.len; i++) {	*c = n1->u.rdnSequence.val[i].len - n2->u.rdnSequence.val[i].len;	if (*c)	    return 0;	for (j = 0; j < n1->u.rdnSequence.val[i].len; j++) {	    *c = der_heim_oid_cmp(&n1->u.rdnSequence.val[i].val[j].type,				  &n1->u.rdnSequence.val[i].val[j].type);	    if (*c)		return 0;			     	    ret = _hx509_name_ds_cmp(&n1->u.rdnSequence.val[i].val[j].value,				     &n2->u.rdnSequence.val[i].val[j].value,				     c);	    if (ret)		return ret;	    if (*c)		return 0;	}    }    *c = 0;    return 0;}/** * Compare to hx509 name object, useful for sorting. * * @param n1 a hx509 name object. * @param n2 a hx509 name object. * * @return 0 the objects are the same, returns > 0 is n2 is "larger" * then n2, < 0 if n1 is "smaller" then n2. * * @ingroup hx509_name */inthx509_name_cmp(hx509_name n1, hx509_name n2){    int ret, diff;    ret = _hx509_name_cmp(&n1->der_name, &n2->der_name, &diff);    if (ret)	return ret;    return diff;}int_hx509_name_from_Name(const Name *n, hx509_name *name){    int ret;    *name = calloc(1, sizeof(**name));    if (*name == NULL)	return ENOMEM;    ret = copy_Name(n, &(*name)->der_name);    if (ret) {	free(*name);	*name = NULL;    }    return ret;}int_hx509_name_modify(hx509_context context,		   Name *name, 		   int append,		   const heim_oid *oid, 		   const char *str){    RelativeDistinguishedName *rdn;    int ret;    void *ptr;    ptr = realloc(name->u.rdnSequence.val, 		  sizeof(name->u.rdnSequence.val[0]) * 		  (name->u.rdnSequence.len + 1));    if (ptr == NULL) {	hx509_set_error_string(context, 0, ENOMEM, "Out of memory");

⌨️ 快捷键说明

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