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



我一直在使用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;
}

我正在做与我所看到的几乎相同的事情(见下文)。我看到的唯一增量是使用V_ASN1_IA5STRING或V_ASN1_UTF8STRING(如果需要)。

图。

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

最新更新