Question

I have been using openssl API to create my own certificate utility. I am currently facing an issue when adding a distinguished name in the subject alternative name extension. Although the extension is successfully created, the value of the extension is wrongly encoded when viewing the certificate, e.g with the windows certificate utility:

    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

Below is a snippet of the relevant source code focusing on the points of interest (there might be some syntax errors):

    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;
}
Was it helpful?

Solution

I am doing virtually the same as I can see (see below). The only delta I see is the use of V_ASN1_IA5STRING or a V_ASN1_UTF8STRING if needed.

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);
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top