Добавление альтернативного расширения имени субъекта DN в сертификат X509 с использованием openssl

Я использовал 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;
}

1 ответ

Решение

Я делаю практически то же, что вижу (см. Ниже). Единственная дельта, которую я вижу, - это использование 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);
}
Другие вопросы по тегам