Открытый ключ сервера OpenSSL из буфера в EVP_PKEY - PullRequest
0 голосов
/ 23 октября 2019

Я программирую клиента, который участвует в рукопожатии TLS 1.2, отправляя сообщения через TCP-сокет, подключенный к серверу Google. Я использую метод обмена ключами ECDH.

Я пытаюсь получить общий секрет, используя этот код.

Я получил ключ через сообщение serverKeyExchange и сохранилэто в буфере, поэтому мой вопрос: как мне сгенерировать EVP_PKEY из буфера? Я нашел возможное решение в этом посте и попробовал с:

i2d_PublicKey(peerkey, (unsigned char **) &server_pub_key)

но когда я запускаю код, я получаю сообщение об ошибке на этом шаге:

/* Provide the peer public key */
    if(1 != EVP_PKEY_derive_set_peer(ctx, peerkey)) handleErrors();

Что заставляет меня думать, что мне не удалось получить открытый ключ сервера.

Любые предложения? Как мне узнать, был ли ключ успешно закодирован?

1 Ответ

0 голосов
/ 24 октября 2019

Если у вас есть необработанный открытый ключ, вы должны создать EC_Key с правильными параметрами.

EVP_PKEY * get_peerkey(const unsigned char * buffer, size_t buffer_len)
{
    EC_KEY *tempEcKey = NULL;
    EVP_PKEY *peerkey = NULL;

    // change this if another curve is required
    tempEcKey = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
    if(tempEcKey == NULL) {
        handleErrors();
    }

    if(EC_KEY_oct2key(tempEcKey, buffer, buffer_len, NULL) != 1)  {
        handleErrors();
    }

    if(EC_KEY_check_key(tempEcKey) != 1) {
        handleErrors();
    }

    peerkey = EVP_PKEY_new();
    if(peerkey == NULL) {
        handleErrors();
    }

    if(EVP_PKEY_assign_EC_KEY(peerkey, tempEcKey)!= 1) {
        handleErrors();
    }

    return peerkey;
}

Если у вас есть открытый ключ в качестве последовательности ASN.1, вы можете использовать внутренние методы преобразования:

EVP_PKEY* get_peerkey(const unsigned char *buffer, size_t buffer_len)
{
    EVP_PKEY *peerkey = NULL;       
    const unsigned char *helper = buffer;

    // from "openssl/x509.h"
    peerkey = d2i_PUBKEY(NULL, &helper, buffer_len);
    if (!peerkey) {
        handleErrors();
        return NULL;
    }

    return peerkey;
}
...