2012-07-17 278 views
3

我一直在使用openssl API创建我自己的证书实用程序。在目标替代名称扩展中添加专有名称时,我目前遇到问题。虽然成功创建扩展,扩展的价值查看证书时的编码错误,例如用Windows证书效用:使用openssl在X509证书中添加DN主题备用名称扩展

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; 
} 

回答

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); 
} 
+0

事实上,编码是问题,谢谢指出正确的方向。问题是使用i2d_GENERAL_NAMES函数转换为DER。我目前正在寻找一种替代方法。 – telemahos 2012-07-23 10:57:29

相关问题