使用openssl在X509证书中添加DN使用者替代名称扩展

使用openssl在X509证书中添加DN使用者替代名称扩展,openssl,ssl-certificate,x509,distinguishedname,Openssl,Ssl Certificate,X509,Distinguishedname,我一直在使用openssl API创建自己的证书实用程序。我目前面临的一个问题是在subject alternative name extension中添加可分辨名称。尽管已成功创建扩展,但在查看证书时,扩展的值被错误编码,例如使用windows证书实用程序: Basic Constraints Subject Type=CA, Path... Subject Alternative Name 74 53 19 00 00 00 3

我一直在使用openssl API创建自己的证书实用程序。我目前面临的一个问题是在subject alternative name extension中添加可分辨名称。尽管已成功创建扩展,但在查看证书时,扩展的值被错误编码,例如使用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
下面是一段相关源代码,重点介绍了关注点(可能存在一些语法错误):


我所做的几乎和我所看到的一样(见下文)。我看到的唯一增量是使用V_ASN1_IA5STRING或V_ASN1_UTF8STRING(如果需要)

德瓦


的确,编码是个问题,感谢您指出了正确的方向。问题在于使用i2d_GENERAL_NAMES函数转换为DER。我目前正在寻找一种替代方法。
    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;
}
+(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);
}