Exemple #1
0
Blob
PrivateKey::decrypt(const Blob& cipher) const
{
    if (!key)
        throw CryptoException("Can't decrypt data without private key !");

    unsigned key_len = 0;
    int err = gnutls_privkey_get_pk_algorithm(key, &key_len);
    if (err < 0)
        throw CryptoException("Can't read public key length !");
    if (err != GNUTLS_PK_RSA)
        throw CryptoException("Must be an RSA key");

    unsigned cypher_block_sz = key_len / 8;
    if (cipher.size() % cypher_block_sz)
        throw CryptoException("Unexpected cipher length");

    Blob ret;
    for (auto cb = cipher.cbegin(), ce = cipher.cend(); cb < ce; cb += cypher_block_sz) {
        const gnutls_datum_t dat {(uint8_t*)(&(*cb)), cypher_block_sz};
        gnutls_datum_t out;
        int err = gnutls_privkey_decrypt_data(key, 0, &dat, &out);
        if (err != GNUTLS_E_SUCCESS)
            throw DhtException(std::string("Can't decrypt data: ") + gnutls_strerror(err));
        ret.insert(ret.end(), out.data, out.data+out.size);
        gnutls_free(out.data);
    }
    return ret;
}
Exemple #2
0
Blob
PublicKey::encrypt(const Blob& data) const
{
    if (!pk)
        throw CryptoException("Can't read public key !");

    unsigned key_len = 0;
    int err = gnutls_pubkey_get_pk_algorithm(pk, &key_len);
    if (err < 0)
        throw CryptoException("Can't read public key length !");
    if (err != GNUTLS_PK_RSA)
        throw CryptoException("Must be an RSA key");

    unsigned max_block_sz = key_len / 8 - 11;
    unsigned cypher_block_sz = key_len / 8;
    unsigned block_num = data.empty() ? 1 : 1 + (data.size() - 1) / max_block_sz;

    Blob ret;
    auto eb = data.cbegin();
    auto ee = data.cend();
    for (unsigned i=0; i<block_num; i++) {
        auto blk_sz = std::min<unsigned>(ee - eb, max_block_sz);
        const gnutls_datum_t dat {(uint8_t*)&(*eb), blk_sz};
        gnutls_datum_t encrypted;
        err = gnutls_pubkey_encrypt_data(pk, 0, &dat, &encrypted);
        if (err != GNUTLS_E_SUCCESS)
            throw CryptoException(std::string("Can't encrypt data: ") + gnutls_strerror(err));
        if (encrypted.size != cypher_block_sz)
            throw CryptoException("Unexpected cypherblock size");
        ret.insert(ret.end(), encrypted.data, encrypted.data+encrypted.size);
        eb += blk_sz;
        gnutls_free(encrypted.data);
    }

    return ret;
}