void RSAKey::Sign( const CString &data, CString &out ) const { Bignum in; { unsigned char hash[20]; SHA_Simple(data.data(), data.size(), hash); int nbytes = (bignum_bitcount(this->modulus) - 1) / 8; unsigned char *bytes = new unsigned char[nbytes]; memset( bytes, 0xFF, nbytes ); bytes[0] = 1; memcpy( bytes + nbytes - 20, hash, 20 ); in = bignum_from_bytes(bytes, nbytes); delete [] bytes; } Bignum outnum = rsa_privkey_op(in, this); delete [] in; int siglen; unsigned char *bytes = bignum_to_bytes( outnum, &siglen ); delete [] outnum; out = CString( (const char *) bytes, siglen ); delete [] bytes; }
bool RSAKey::Decrypt( CString &buf ) const { Bignum bn = bignum_from_buffer( (unsigned char *) buf.data(), buf.size() ); if( bn == NULL ) return false; Bignum decrypted_bn = Decrypt( bn ); delete [] bn; int len; unsigned char *bytes = bignum_to_bytes( decrypted_bn, &len ); buf = CString( (const char *) bytes, len ); delete [] decrypted_bn; return true; }
soter_status_t soter_engine_specific_to_rsa_priv_key(const soter_engine_specific_rsa_key_t *engine_key, soter_container_hdr_t *key, size_t* key_length) { EVP_PKEY *pkey = (EVP_PKEY *)engine_key; RSA *rsa; soter_status_t res; int rsa_mod_size; size_t output_length; uint32_t *pub_exp; unsigned char *curr_bn = (unsigned char *)(key + 1); if (!key_length) { return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_RSA != EVP_PKEY_id(pkey)) { return SOTER_INVALID_PARAMETER; } rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); if (NULL == rsa) { return SOTER_FAIL; } rsa_mod_size = RSA_size(rsa); if (!is_mod_size_supported(rsa_mod_size)) { res = SOTER_INVALID_PARAMETER; goto err; } output_length = rsa_priv_key_size(rsa_mod_size); if ((!key) || (output_length > *key_length)) { *key_length = output_length; res = SOTER_BUFFER_TOO_SMALL; goto err; } pub_exp = (uint32_t *)(curr_bn + ((rsa_mod_size * 4) + (rsa_mod_size / 2))); if (BN_is_word(rsa->e, RSA_F4)) { *pub_exp = htonl(RSA_F4); } else if (BN_is_word(rsa->e, RSA_3)) { *pub_exp = htonl(RSA_3); } else { res = SOTER_INVALID_PARAMETER; goto err; } /* Private exponent */ res = bignum_to_bytes(rsa->d, curr_bn, rsa_mod_size); if (SOTER_SUCCESS != res) { goto err; } curr_bn += rsa_mod_size; /* p */ res = bignum_to_bytes(rsa->p, curr_bn, rsa_mod_size / 2); if (SOTER_SUCCESS != res) { goto err; } curr_bn += rsa_mod_size / 2; /* q */ res = bignum_to_bytes(rsa->q, curr_bn, rsa_mod_size / 2); if (SOTER_SUCCESS != res) { goto err; } curr_bn += rsa_mod_size / 2; /* dp */ res = bignum_to_bytes(rsa->dmp1, curr_bn, rsa_mod_size / 2); if (SOTER_SUCCESS != res) { goto err; } curr_bn += rsa_mod_size / 2; /* dq */ res = bignum_to_bytes(rsa->dmq1, curr_bn, rsa_mod_size / 2); if (SOTER_SUCCESS != res) { goto err; } curr_bn += rsa_mod_size / 2; /* qp */ res = bignum_to_bytes(rsa->iqmp, curr_bn, rsa_mod_size / 2); if (SOTER_SUCCESS != res) { goto err; } curr_bn += rsa_mod_size / 2; /* modulus */ res = bignum_to_bytes(rsa->n, curr_bn, rsa_mod_size); if (SOTER_SUCCESS != res) { goto err; } memcpy(key->tag, rsa_priv_key_tag(rsa_mod_size), SOTER_CONTAINER_TAG_LENGTH); key->size = htonl(output_length); soter_update_container_checksum(key); *key_length = output_length; res = SOTER_SUCCESS; err: /* Free extra reference on RSA object provided by EVP_PKEY_get1_RSA */ RSA_free(rsa); // if (SOTER_SUCCESS != res) // { // /* Zero output memory to avoid leaking private key information */ // memset(key, 0, *key_length); // } return res; }
soter_status_t soter_engine_specific_to_rsa_pub_key(const soter_engine_specific_rsa_key_t *engine_key, soter_container_hdr_t *key, size_t* key_length) { EVP_PKEY *pkey = (EVP_PKEY *)engine_key; RSA *rsa; soter_status_t res; int rsa_mod_size; size_t output_length; uint32_t *pub_exp; if (!key_length) { return SOTER_INVALID_PARAMETER; } if (EVP_PKEY_RSA != EVP_PKEY_id(pkey)) { return SOTER_INVALID_PARAMETER; } rsa = EVP_PKEY_get1_RSA((EVP_PKEY *)pkey); if (NULL == rsa) { return SOTER_FAIL; } rsa_mod_size = RSA_size(rsa); if (!is_mod_size_supported(rsa_mod_size)) { res = SOTER_INVALID_PARAMETER; goto err; } output_length = rsa_pub_key_size(rsa_mod_size); if ((!key) || (output_length > *key_length)) { *key_length = output_length; res = SOTER_BUFFER_TOO_SMALL; goto err; } pub_exp = (uint32_t *)((unsigned char *)(key + 1) + rsa_mod_size); if (BN_is_word(rsa->e, RSA_F4)) { *pub_exp = htonl(RSA_F4); } else if (BN_is_word(rsa->e, RSA_3)) { *pub_exp = htonl(RSA_3); } else { res = SOTER_INVALID_PARAMETER; goto err; } res = bignum_to_bytes(rsa->n, (unsigned char *)(key + 1), rsa_mod_size); if (SOTER_SUCCESS != res) { goto err; } memcpy(key->tag, rsa_pub_key_tag(rsa_mod_size), SOTER_CONTAINER_TAG_LENGTH); key->size = htonl(output_length); soter_update_container_checksum(key); *key_length = output_length; res = SOTER_SUCCESS; err: /* Free extra reference on RSA object provided by EVP_PKEY_get1_RSA */ RSA_free(rsa); return res; }