我一直在使用openssl API创建自己的证书实用程序。我在主题备用名称扩展名中添加专有名称时遇到问题。虽然成功创建了扩展,但在查看证书时错误地编码了扩展的值,例如使用Windows证书实用程序:
Basic Constraints Subject Type=CA, Path...
Subject Alternative Name
74 53 19 00 00 00 38 27 tS....8'
ac 0b 88 ae ac 0b 00 00 ........
00 00 00 00 00 00 6f 72 ......or
20 53 21 00 00 00 02 00 S!.....
00 00 13 00 00 00 d0 d7 ........
ac 0b 00 00 00 00 0a 00 ........
00 00 00 00 00 00 20 00 ...... .
00 00 19 00 00 00 b8 5d .......]
a4 0b
Thumbprint algorithm sha1
以下是关注兴趣点的相关源代码片段(可能存在一些语法错误):
GENERAL_NAME * genn = NULL;
STACK_OF(GENERAL_NAME) * sk_genn;
ASN1_OCTET_STRING *asn1OctetStr=NULL;
X509_EXTENSION* tmpEXT;
X509_NAME* tmpDIRNAME;
char* extSAN_str=(char *) "C=CR, O=OU, D=DR";
/*..*/
case DISTINGUISHED_NAME:
// Initialization of ASN.1 structures
genn = GENERAL_NAME_new();
asn1OctetStr = M_ASN1_OCTET_STRING_new();
sk_genn = GENERAL_NAMES_new();
// Create the X509 extension
tmpDIRNAME=CharToX509_NAME(extSAN_str);
// This GeneralName is an directoryName
genn->type=GEN_DIRNAME;
genn->d.directoryName=tmpDIRNAME;
// Using the stack to create a sequence
sk_GENERAL_NAME_push(sk_genn,genn);
ext_len = i2d_GENERAL_NAMES(sk_genn, NULL);
ext_der = OPENSSL_malloc(ext_len); /* allocate that much memory */
i2d_GENERAL_NAMES(sk_genn, &ext_der);
asn1OctetStr->data = ext_der;
/* fill in the value of the SubjectAltName extension */
asn1OctetStr->length = ext_len;
sanNID = OBJ_txt2nid("subjAltName");
if (!(tmpEXT = X509_EXTENSION_create_by_NID(NULL, sanNID, 0, asn1OctetStr)))
{
ERR_error_string(ERR_get_error(), NULL), ERR_get_error());
}
// Adding the certificate to the X509 structure
if(!X509_add_ext(tmpCert, tmpEXT, -1))
{
ERR_error_string(ERR_get_error(), NULL), ERR_get_error());
}
/*..*/
X509_NAME* CharToX509_NAME(char* SubjectName)
{
X509_NAME *tempSubjectName=NULL;
char name[128];
char value[128];
char* equal;
char* comma;
char* field;
memset(name, 0, 128);
memset(value, 0, 128);
if(!(tempSubjectName = X509_NAME_new()))
{
return 0;
}
if (NULL != SubjectName)
{
field = SubjectName;
do
{
equal=strchr(field, '=');
comma=strchr(field, ',');
if(comma == 0)
comma = field + strlen(field);
strncpy(name, field, (unsigned)(equal-field));
name[equal-field]=0;
strncpy(value, equal+1, (unsigned)(comma-equal-1));
value[comma-equal-1]=0;
field=comma+1;
if(!X509_NAME_add_entry_by_txt(tempSubjectName,name, MBSTRING_ASC, value, -1, -1, 0))
return 0;
}while(*comma != 0);
}
return tempSubjectName;
}
答案 0 :(得分:2)
我做的几乎和我看到的一样(见下文)。我看到的唯一增量是使用V_ASN1_IA5STRING或V_ASN1_UTF8STRING(如果需要)。
DW传递。
+(X509_NAME_ENTRY *) x509nameEntryFromDict:(NSDictionary *)entry {
X509_NAME_ENTRY * nameEntry = NULL;
int nid = [self nidFromDict:entry];
if (nid == NID_undef) {
NSLog(@"x509nameFromDictArray: Unknown entry - ignored: %@", entry);
return NULL;
}
NSString * val = [entry objectForKey:kOpenSSLNameValueKey];
const char * buff;
int valType;
if ([val dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:NO]) {
valType = V_ASN1_IA5STRING;
buff = [val cStringUsingEncoding:NSASCIIStringEncoding];
} else {
valType = V_ASN1_UTF8STRING;
buff = [val cStringUsingEncoding:NSUTF8StringEncoding];
}
int len = strlen(buff);
return X509_NAME_ENTRY_create_by_NID(&nameEntry, nid, valType, (unsigned char*)buff, len);
}