Программный пример создания заявки на сертификат в формате PKCS#10 , реализованный на OpenSSL. Генерация ключа ГОСТ Р 34.10-2001 и подпись заявки происходят "на борту" Рутокен ЭЦП
Для сборки примера под платформу Win32 с помощью cl.exe требуются заголовочные файлы OpenSSL и статическая библиотека libeay32.lib. Полный комплект OpenSSL для win32 с нужными либами и заголовочными файлами можно скачать по ссылке http://www.slproweb.com/download/Win32O … 1_0_0e.exe.
Приложение следует собирать с опцией /MT.
Для работы собранного приложения в environment следует добавить переменную окружения OPENSSL_ENGINES, в которой указать путь к папке, в которой располагаются библиотеки pkcs11_gost.dll и gost.dll. Кроме того, библиотеки libeay32.dll, libp11.dll  и libltdl3.dll должны находиться либо в текущей директории приложения, либо в директории, прописанной в переменной окружения PATH.
Приложение имеет параметры командной строки SLOT токена:ID ключа и PIN-код. 
Пример запуска приложения:
request_pkcs10 100 12345678
Получить тестовый сертификат по созданной заявке можно, например, здесь http://www.cryptopro.ru/certsrv/certrqxt.asp. Для этого заявку следует сохранить в файл командой
request_pkcs10 101 12345678 > req.csr
а затем содержимое файла вставить в форму на сайте. ВНИМАНИЕ, ниже на форуме представлен пример записи сертификата на токен. Для его работы требуется сертификат в формате PEM. Поэтому рекомендуется при получении сертификата выбрать формат хранения Base64.
#include <windows.h>
#include <openssl/lhash.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/crypto.h> /* for CRYPTO_* and SSLeay_version */
#include <openssl/rand.h>
#include <openssl/md4.h>
#include <openssl/des.h>
#include <openssl/engine.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#define CMD_MODULE_PATH                 (ENGINE_CMD_BASE+1)
#define CMD_PIN                                   (ENGINE_CMD_BASE+2)
#define CMD_LOAD_CERT_CTRL            (ENGINE_CMD_BASE+5)
#define CMD_SAVE_CERT_CTRL             (ENGINE_CMD_BASE+6)
#define GOST2001_KEY_TYPE                 811
ENGINE* LoadEngine(const char* engine_name, const char* pkcs11_provider, const char* pin) 
{
    ENGINE* engine_pkcs11=NULL;
    engine_pkcs11=ENGINE_by_id(
        engine_name);
    if(!engine_pkcs11) 
        return NULL;    
    
    if(!ENGINE_ctrl(engine_pkcs11, CMD_MODULE_PATH, 0, 
            (void*)pkcs11_provider, NULL)) {
        ENGINE_free(engine_pkcs11);                
        return NULL;
    }
    if(pin) {
        if(!ENGINE_ctrl(engine_pkcs11, CMD_PIN, 0, 
                (void*)pin, NULL)) {
            ENGINE_free(engine_pkcs11);                    
            return NULL;
        }
    }
    if(!ENGINE_init(engine_pkcs11)) {
        ENGINE_free(engine_pkcs11);        
        return NULL;
    }    
    if(!ENGINE_set_default(engine_pkcs11, ENGINE_METHOD_ALL)) {
        ENGINE_free(engine_pkcs11);        
        return NULL;
    }
    return engine_pkcs11;
}
void UnloadEngine(ENGINE* engine_pkcs11) 
{
    ENGINE_finish(engine_pkcs11);
    ENGINE_free(engine_pkcs11);
}
/* создает объект расширения сертификата */ 
X509_EXTENSION* 
create_X509_extension
(
        char* name, 
        char *value
)
{
    X509_EXTENSION *ex;
    ex = X509V3_EXT_conf(NULL, NULL, name, value);
    if (!ex)
        return NULL;
    return ex;    
 }
X509_REQ* create_request(
    EVP_PKEY*    pKey,
    const char* common_name,        /* понятное имя субъекта */
    const char* org,                /* организация */
    const char* org_unit,            /* подразделение организации */
    const char* city,                /* город */
    const char* region,                /* регион */
    const char* country,            /* страна */
    const char* email,                /* почтовый адрес */
    const char* keyUsages,            /* способы использования ключа, через , */
    const char* extendedKeyUsages    /* расширенные способы использования ключа, через ; */    
)
{
    X509_REQ*    req            =    NULL;
    X509_NAME*    subject        =    NULL;    
    BOOL        bGoodEmail    =    TRUE;
    subject    = X509_NAME_new();    
    
    /* добавляем CN */
    if(common_name && strlen(common_name)>0) {    
        if(!X509_NAME_add_entry_by_NID(
                subject, NID_commonName, 
                MBSTRING_UTF8, (unsigned char*)common_name, 
                -1, -1, 0)) {
            X509_NAME_free(subject);
            return NULL;    
        }
    }
    /* добавляем название организации */
    if(org && strlen(org)>0) 
        if(!X509_NAME_add_entry_by_NID(
                subject, NID_organizationName, 
                MBSTRING_UTF8, (unsigned char*)org, 
                -1, -1, 0)) {
            X509_NAME_free(subject);
            return NULL;    
        }
    /* добавляем название подразделения */
    if(org_unit && strlen(org_unit)>0) 
        if(!X509_NAME_add_entry_by_NID(
                subject, NID_organizationalUnitName, 
                MBSTRING_UTF8, (unsigned char*)org_unit, 
                -1, -1, 0)) {
            X509_NAME_free(subject);
            return NULL;
        }
    /* добавляем locality */
    if(city && strlen(city)>0) 
        if(!X509_NAME_add_entry_by_NID(
                subject, NID_localityName, 
                MBSTRING_UTF8, (unsigned char*)city, 
                -1, -1, 0)) {
            X509_NAME_free(subject);
            return NULL;
        }
    
    if(region && strlen(region)>0) 
        if(!X509_NAME_add_entry_by_NID(
                subject, NID_stateOrProvinceName, 
                MBSTRING_UTF8, (unsigned char*)region, 
                -1, -1, 0)) {
            X509_NAME_free(subject);
            return NULL;
        }
    if(country && strlen(country)>0) 
        if(!X509_NAME_add_entry_by_NID(
                subject, NID_countryName, 
                MBSTRING_UTF8, (unsigned char*)country, 
                -1, -1, 0)) {
            X509_NAME_free(subject);
            return NULL;
        }
    if(email && strlen(email)>0) {
        for (int i=0; i<strlen(email); i++) 
            if (email[i]&0x80) {            
                bGoodEmail=FALSE;
                break;        
            }    
    
        if(bGoodEmail) {
            if(!X509_NAME_add_entry_by_NID(
                    subject, NID_pkcs9_emailAddress, 
                    MBSTRING_UTF8, (unsigned char*)email, 
                    -1, -1, 0)) {
                X509_NAME_free(subject);
                return NULL;
            }
        }
    }
            
    req=X509_REQ_new();
    if(!req) {
        X509_NAME_free(subject);
        return NULL;
    }
    
    /* установка версии */
    if(!X509_REQ_set_version(req, 0)) {
        X509_REQ_free(req);
        X509_NAME_free(subject);
        return NULL;
    }
    /* установка subject */    
    if(!X509_REQ_set_subject_name(req, subject)) {        
        X509_REQ_free(req);        
        X509_NAME_free(subject);                
        return NULL;
    }
    /* установка открытого ключа */
    if(!X509_REQ_set_pubkey(req, pKey)) {
        X509_REQ_free(req);
        X509_NAME_free(subject);
        return NULL;    
    }
    /* установка keyUsage */
    X509_EXTENSION* keyUsageExt = 
        create_X509_extension("keyUsage", (char*)keyUsages); 
    if(!keyUsageExt) {
        X509_REQ_free(req);
        X509_NAME_free(subject);
        return NULL;    
    }
        
    /* установка extendedkeyUsage */                                                   
    X509_EXTENSION* extendedKeyUsageExt = 
        create_X509_extension("extendedKeyUsage", (char*)extendedKeyUsages); 
    if(!extendedKeyUsageExt) {
        X509_EXTENSION_free(keyUsageExt);
        X509_REQ_free(req);
        X509_NAME_free(subject);
        return NULL;
    }
    STACK_OF(X509_EXTENSION)* extension_stack = 
        sk_X509_EXTENSION_new_null();
    if(!extension_stack) {
        X509_EXTENSION_free(extendedKeyUsageExt);
        X509_EXTENSION_free(keyUsageExt);
        X509_REQ_free(req);
        X509_NAME_free(subject);
        return NULL;
    }
    sk_X509_EXTENSION_push(extension_stack, keyUsageExt);
    sk_X509_EXTENSION_push(extension_stack, extendedKeyUsageExt);
    if(!X509_REQ_add_extensions(req, extension_stack)) {
        X509_EXTENSION_free(extendedKeyUsageExt);
        X509_EXTENSION_free(keyUsageExt);
        X509_REQ_free(req);
        X509_NAME_free(subject);
        return NULL;
    }
    /* подпись заявки закрытым ключом */
    if(!X509_REQ_sign(req, pKey, EVP_get_digestbyname("md_gost94"))) {
        X509_EXTENSION_free(extendedKeyUsageExt);
        X509_EXTENSION_free(keyUsageExt);
        X509_REQ_free(req);
        X509_NAME_free(subject);
        return NULL;
    }
    sk_X509_EXTENSION_pop_free
        (extension_stack,X509_EXTENSION_free);    
    X509_NAME_free(subject);
    
    return req;    
    
}
int main(int argc, char* argv[])
{
    BIO*            bio_req=NULL;
    BIO*            bio_key=NULL;
    X509_REQ*        pRequest=NULL;    
    BUF_MEM*        pbmReq;
    char*            cRequest=NULL;    
    UI_METHOD*        uim=NULL;
    int                reason=0;    
    EVP_PKEY*        key1=NULL;    
    EVP_PKEY*        newkey=NULL;
    EVP_PKEY_CTX*    ctx=NULL;    
    ENGINE*            engine_pkcs11=NULL;
        
    if(!argv[1] || !argv[2]) {
    fprintf(stderr, "Bad parameters!");
    return 1;
    }
    /* инициализируем OpenSSL */    
    ENGINE_load_builtin_engines();                    
    OPENSSL_add_all_algorithms_noconf();    
    /* загружаем engine, реализующую работу с 
        Рутокен ЭЦП через библиотеку PKCS#11 */
    engine_pkcs11=LoadEngine(
        "pkcs11_gost", 
        "rtPKCS11ECP.dll", 
        NULL);
    if(!engine_pkcs11)         
        return 1;    
    key1=EVP_PKEY_new();
    if(!key1) {
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
        
    /* тип ключа ГОСТ Р 34.10-2001 */
    if(!EVP_PKEY_set_type(key1, GOST2001_KEY_TYPE)) {
        EVP_PKEY_free(key1);
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
    ctx=EVP_PKEY_CTX_new(key1, NULL);    
    if(!ctx) {
        EVP_PKEY_free(key1);
        UnloadEngine(engine_pkcs11);            
        return 1;
    }
    if(!EVP_PKEY_keygen_init(ctx)) {        
        EVP_PKEY_CTX_free(ctx);
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
    /* параметры ключа */
    if(!EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A")) {
        EVP_PKEY_CTX_free(ctx);
        UnloadEngine(engine_pkcs11);                
        return 1;
    }
    /* ID ключа */
    if(!EVP_PKEY_CTX_ctrl_str(ctx, "slot_key_id", argv[1])) {        
        EVP_PKEY_CTX_free(ctx);
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
    /* PIN-код токена */
    if(!EVP_PKEY_CTX_ctrl_str(ctx, "pin", argv[2])) {        
        EVP_PKEY_CTX_free(ctx);
        UnloadEngine(engine_pkcs11);        
        return 1;
    }        
    /* генерация ключа */
    if(!EVP_PKEY_keygen(ctx,&newkey)) {
        EVP_PKEY_CTX_free(ctx);
        UnloadEngine(engine_pkcs11);        
        return 1;
    }    
    /* создание запроса на сертификат */
    pRequest=create_request(
        newkey, 
        "tester", 
        "rutoken",
        "development", 
        "Moscow", 
        "Moscow", 
        "ru", 
        "tester@rutoken.ru",     
        "digitalSignature,keyEncipherment", 
        "clientAuth,emailProtection");
    
    if(!pRequest) {        
        EVP_PKEY_free(newkey);
        EVP_PKEY_CTX_free(ctx);            
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
    bio_req=BIO_new(BIO_s_mem());
    if(!bio_req) {        
        X509_REQ_free(pRequest);
        EVP_PKEY_free(newkey);
        EVP_PKEY_CTX_free(ctx);            
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
    if(!PEM_write_bio_X509_REQ(bio_req, pRequest)) {        
        BIO_free(bio_req);
        X509_REQ_free(pRequest);        
        EVP_PKEY_free(newkey);
        EVP_PKEY_CTX_free(ctx);            
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
    
    BIO_get_mem_ptr(bio_req, &pbmReq);    
    if(!pbmReq) {        
        BIO_free(bio_req);
        X509_REQ_free(pRequest);        
        EVP_PKEY_free(newkey);
        EVP_PKEY_CTX_free(ctx);            
        UnloadEngine(engine_pkcs11);        
        return 1;
    }
    pbmReq->data[pbmReq->length]='\0';
    fprintf(stdout, "%s", pbmReq->data);    
    
    BIO_free(bio_req);
    bio_req=NULL;
    
        
    X509_REQ_free(pRequest);    
    EVP_PKEY_free(newkey);
    EVP_PKEY_CTX_free(ctx);            
    UnloadEngine(engine_pkcs11);
        
    return 0;
}