void openssl_evp_asycrypt() { RSA *rkey; BIGNUM *bne; EVP_PKEY *pubkey[2]; EVP_CIPHER_CTX ctx1, ctx2; int i, ekl[2], len1 = 0, len2 = 0, len3 = 0; unsigned char ins[] = "openssl asymmetric encrypt test"; unsigned char iv[8], pen[MAX1_LEN], *ek[2], sde[MAX1_LEN]; ek[0] = (unsigned char *)malloc(MAX1_LEN); ek[1] = (unsigned char *)malloc(MAX1_LEN); memset(pen, 0, MAX1_LEN); memset(sde, 0, MAX1_LEN); memset(ek[0], 0, MAX1_LEN); memset(ek[1], 0, MAX1_LEN); bne = BN_new(); BN_set_word(bne, RSA_3); rkey = RSA_new(); RSA_generate_key_ex(rkey, MAX1_LEN, bne, NULL); pubkey[0] = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pubkey[0], rkey); EVP_CIPHER_CTX_init(&ctx1); EVP_SealInit(&ctx1, EVP_des_ede3_cbc(), ek, ekl, iv, pubkey, 1); EVP_SealUpdate(&ctx1, pen, &len1, ins, strlen((char *)ins)); EVP_SealFinal(&ctx1, pen + len1, &len3); len1 += len3; printf("\nEVP_ASYEncry(%s) = ", ins); for (i = 0; i < len1; i++) printf("0x%.02x ", pen[i]); printf("\n"); EVP_CIPHER_CTX_cleanup(&ctx1); len3 = 0; EVP_CIPHER_CTX_init(&ctx2); EVP_OpenInit(&ctx2, EVP_des_ede3_cbc(), ek[0], ekl[0], iv, pubkey[0]); EVP_OpenUpdate(&ctx2, sde, &len2, pen, len1); EVP_OpenFinal(&ctx2, sde + len2, &len3); len2 += len3; printf("EVP_ASYDecry("); for (i = 0; i < len1; i++) printf("0x%.02x ", pen[i]); printf(") = %s\n", sde); EVP_CIPHER_CTX_cleanup(&ctx2); free(ek[0]); free(ek[1]); EVP_PKEY_free(pubkey[0]); BN_free(bne); }
/* {{{ proto opendata openssl_open(string data, string ekey, mixed privkey, [, cipher enc|string md_alg=RC4]) Opens data */ LUA_API LUA_FUNCTION(openssl_open) { size_t data_len, ekey_len; const char * data = luaL_checklstring(L, 1, &data_len); const char * ekey = luaL_checklstring(L, 2, &ekey_len); EVP_PKEY *pkey = CHECK_OBJECT(3,EVP_PKEY, "openssl.evp_pkey"); int top = lua_gettop(L); int len1, len2 = 0; unsigned char *buf; EVP_CIPHER_CTX ctx; const EVP_CIPHER *cipher = NULL; if(top>3) { if(lua_isstring(L,4)) cipher = EVP_get_cipherbyname(lua_tostring(L,4)); else if(lua_isuserdata(L,4)) cipher = CHECK_OBJECT(4,EVP_CIPHER,"openssl.evp_cipher"); else luaL_error(L, "#4 argument must be nil, string, or openssl.evp_cipher object"); } if(!cipher) cipher = EVP_rc4(); len1 = data_len + 1; buf = malloc(len1); if (EVP_OpenInit(&ctx, cipher, (unsigned char *)ekey, ekey_len, NULL, pkey) && EVP_OpenUpdate(&ctx, buf, &len1, (unsigned char *)data, data_len)) { len2 = data_len - len1; if (!EVP_OpenFinal(&ctx, buf + len1, &len2) || (len1 + len2 == 0)) { luaL_error(L,"EVP_OpenFinal() failed."); free(buf); return 0; } } else { luaL_error(L,"EVP_OpenInit() failed."); free(buf); return 0; } buf[len1 + len2] = '\0'; lua_pushlstring(L, (const char*)buf, len1 + len2); free(buf); return 1; }
void cipher_context::open_initialize(const cipher_algorithm& _algorithm, const void* key, size_t key_len, const void* iv, size_t iv_len, pkey::pkey pkey) { assert(key); if (key_len != _algorithm.key_length()) { throw std::runtime_error("key_len"); } if (iv_len != _algorithm.iv_length()) { throw std::runtime_error("iv_len"); } error::throw_error_if_not(EVP_OpenInit(&m_ctx, _algorithm.raw(), static_cast<const unsigned char*>(key), static_cast<int>(key_len), static_cast<const unsigned char*>(iv), pkey.raw()) != 0); }
void openssl_evp_rsacripher() { RSA *rkey; BIGNUM *bne; EVP_PKEY *pubkey[2]; const EVP_CIPHER *type; EVP_CIPHER_CTX ctx1, ctx2; int i, ekl[2], total = 0, len1 = 0, len2 = 0; const unsigned char ins[COMM_LEN] = "openssl evp"; unsigned char outs[LINE_LEN], iv[8], *ek[2], de[LINE_LEN]; bne = BN_new(); BN_set_word(bne, RSA_3); rkey = RSA_new(); RSA_generate_key_ex(rkey, MAX1_LEN, bne, NULL); pubkey[0] = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pubkey[0], rkey); type = EVP_des_cbc(); ek[0] = malloc(LINE_LEN); ek[1] = malloc(LINE_LEN); EVP_CIPHER_CTX_init(&ctx1); EVP_SealInit(&ctx1, type, ek, ekl, iv, pubkey, 1); EVP_SealUpdate(&ctx1, outs, &total, ins, 11); EVP_SealFinal(&ctx1, outs + total, &len1); total += len1; printf("\nEVP_RSASEAL(%s) = ", ins); for (i = 0; i < total; i++) printf("0x%.02x ", outs[i]); EVP_CIPHER_CTX_cleanup(&ctx1); memset(de, 0, LINE_LEN); EVP_CIPHER_CTX_init(&ctx2); EVP_OpenInit(&ctx2, EVP_des_cbc(), ek[0], ekl[0], iv, pubkey[0]); EVP_OpenUpdate(&ctx2, de, &len2, outs, total); EVP_OpenFinal(&ctx2, de + len2, &len1); len2 += len1; printf("= %s\n", de); EVP_CIPHER_CTX_cleanup(&ctx2); free(ek[0]); free(ek[1]); EVP_PKEY_free(pubkey[0]); BN_free(bne); }
static int test_EVP_Enveloped(void) { int ret = 0; EVP_CIPHER_CTX *ctx = NULL; EVP_PKEY *keypair = NULL; unsigned char *kek = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; static const unsigned char msg[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; int len, kek_len, ciphertext_len, plaintext_len; unsigned char ciphertext[32], plaintext[16]; const EVP_CIPHER *type = EVP_aes_256_cbc(); if (!TEST_ptr(keypair = load_example_rsa_key()) || !TEST_ptr(kek = OPENSSL_zalloc(EVP_PKEY_size(keypair))) || !TEST_ptr(ctx = EVP_CIPHER_CTX_new()) || !TEST_true(EVP_SealInit(ctx, type, &kek, &kek_len, iv, &keypair, 1)) || !TEST_true(EVP_SealUpdate(ctx, ciphertext, &ciphertext_len, msg, sizeof(msg))) || !TEST_true(EVP_SealFinal(ctx, ciphertext + ciphertext_len, &len))) goto err; ciphertext_len += len; if (!TEST_true(EVP_OpenInit(ctx, type, kek, kek_len, iv, keypair)) || !TEST_true(EVP_OpenUpdate(ctx, plaintext, &plaintext_len, ciphertext, ciphertext_len)) || !TEST_true(EVP_OpenFinal(ctx, plaintext + plaintext_len, &len))) goto err; plaintext_len += len; if (!TEST_mem_eq(msg, sizeof(msg), plaintext, plaintext_len)) goto err; ret = 1; err: OPENSSL_free(kek); EVP_PKEY_free(keypair); EVP_CIPHER_CTX_free(ctx); return ret; }
/// 使用加密密钥和初始向量解开数字信封,得到明文 int do_unseal(const EVP_CIPHER * cipher, unsigned char * ebuf,int ebuflen, unsigned char * iv, unsigned char * kbuf,int klen, unsigned char * dbuf,int * dlen) { EVP_CIPHER_CTX ectx; unsigned char *ekey[1]; int tmp_len; int ret = 0; int fd; ekey[0] = NULL; if (!g_prv_key) return ERR_ENV_KEY_INVALID; EVP_CIPHER_CTX_init(&ectx); do{ ekey[0] = _alloca(klen); if(ekey[0] == NULL) { ret = ERR_ENV_MEMORY; break; } memcpy(ekey[0],kbuf,klen); if(1 != EVP_OpenInit(&ectx,cipher,ekey[0],klen,iv,g_prv_key)) { /* if(ebuflen == 24) { fd = open("/hqdata/24err.ek",O_RDWR|O_CREAT|O_TRUNC); write(fd,kbuf,klen); close(fd); } if(ebuflen == 32) { fd = open("/hqdata/32err.ek",O_RDWR|O_CREAT|O_TRUNC); write(fd,kbuf,klen); close(fd); } */ printf("EVP_OpenInit err!\n"); ret = ERR_ENV_DECRYPT_FAILED; break; } /* if(ebuflen == 24) { fd = open("/hqdata/24noerr.ek",O_RDWR|O_CREAT|O_TRUNC); write(fd,kbuf,klen); close(fd); } if(ebuflen == 32) { fd = open("/hqdata/32noerr.ek",O_RDWR|O_CREAT|O_TRUNC); write(fd,kbuf,klen); close(fd); } */ *dlen = 0; if(1 != EVP_OpenUpdate(&ectx, dbuf + *dlen, &tmp_len, ebuf, ebuflen)) { printf("EVP_OpenUpdate err!\n"); ret = ERR_ENV_DECRYPT_FAILED; break; } *dlen = *dlen + tmp_len; if(1 != EVP_OpenFinal(&ectx, dbuf+*dlen,&tmp_len)) { printf("EVP_OpenFinal err!\n"); ret = ERR_ENV_DECRYPT_FAILED; break; } *dlen = *dlen + tmp_len; dbuf[*dlen] = 0x0; }while(0); EVP_CIPHER_CTX_cleanup(&ectx); return ret; }
bool OTEnvelope::Open(const OTPseudonym & theRecipient, OTString & theContents) { bool retval = false; EVP_CIPHER_CTX ctx; unsigned char buffer[4096]; unsigned char buffer_out[4096 + EVP_MAX_IV_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH]; size_t len = 0; int len_out = 0; unsigned char * ek = NULL; int eklen = 0; uint32_t eklen_n = 0; memset(buffer, 0, 4096); memset(buffer_out, 0, 4096 + EVP_MAX_IV_LENGTH); memset(iv, 0, EVP_MAX_IV_LENGTH); OTAsymmetricKey & privateKey = (OTAsymmetricKey &)theRecipient.GetPrivateKey(); EVP_PKEY * pkey = (EVP_PKEY *)privateKey.GetKey(); if (NULL == pkey) { OTLog::Error("Null private key in OTEnvelope::Open\n"); return false; } EVP_CIPHER_CTX_init(&ctx); ek = (unsigned char*)malloc(EVP_PKEY_size(pkey)); // I assume this is for the AES key OT_ASSERT(NULL != ek); memset(ek, 0, EVP_PKEY_size(pkey)); eklen = EVP_PKEY_size(pkey); //int EVP_OpenInit(EVP_CIPHER_CTX *ctx, //EVP_CIPHER *type, //unsigned char *ek, //int ekl, //unsigned char *iv, //EVP_PKEY *priv); //EVP_OpenInit() initializes a cipher context ctx for decryption with cipher type. It decrypts the encrypted // symmetric key of length ekl bytes passed in the ek parameter using the private key priv. The IV is supplied // in the iv parameter. theContents.Release(); // This is where we'll put the decrypted data. m_dataContents.reset(); // reset the fread position on this object. int nReadLength = 0; int nReadKey = 0; int nReadIV = 0; // First we read the encrypted key size. if (0 == (nReadLength = m_dataContents.OTfread((char*)&eklen_n, sizeof(eklen_n)))) { OTLog::Error("Error reading encrypted key size in OTEnvelope::Open\n"); free(ek); ek = NULL; return false; } // convert it from network to host endian. eklen = ntohl(eklen_n); // Next we read the encrypted key itself. if (0 == (nReadKey = m_dataContents.OTfread((char*)ek, eklen))) { OTLog::Error("Error reading encrypted key size in OTEnvelope::Open\n"); free(ek); ek = NULL; return false; } // Next we read the initialization vector. if (0 == (nReadIV = m_dataContents.OTfread((char*)iv, EVP_CIPHER_iv_length(EVP_aes_128_cbc())))) { OTLog::Error("Error reading initialization vector in OTEnvelope::Open\n"); free(ek); ek = NULL; return false; } OTData ciphertext((const void*)((unsigned char *)m_dataContents.GetPointer() + nReadLength + nReadKey + nReadIV), m_dataContents.GetSize() - nReadLength - nReadKey - nReadIV); // Now we process ciphertext and write the decrypted data to plaintext. OTData plaintext; if (!EVP_OpenInit(&ctx, EVP_aes_128_cbc(), ek, eklen, iv, pkey)) { OTLog::Error("EVP_OpenInit: failed.\n"); free(ek); ek = NULL; return false; } while ((len = ciphertext.OTfread((char*)buffer, sizeof(buffer))) > 0) { if (!EVP_OpenUpdate(&ctx, buffer_out, &len_out, buffer, len)) { OTLog::Error("EVP_OpenUpdate: failed.\n"); free(ek); ek = NULL; return false; } OTData dataOpenUpdate(buffer_out, len_out); plaintext += dataOpenUpdate; } if (!EVP_OpenFinal(&ctx, buffer_out, &len_out)) { OTLog::Error("EVP_OpenFinal: failed.\n"); free(ek); ek = NULL; return false; } OTData dataOpenFinal(buffer_out, len_out); plaintext += dataOpenFinal; // Make sure it's null terminated int nIndex = plaintext.GetSize()-1; ((unsigned char*)plaintext.GetPointer())[nIndex] = 0; // Set it into theContents (to return the plaintext to the caller) theContents.Set((const char *)plaintext.GetPointer()); retval = true; free(ek); ek = NULL; return retval; }
void main_decrypt(void) { char buf[512]; char ebuf[512]; unsigned int buflen; EVP_CIPHER_CTX ectx; unsigned char iv[8]; unsigned char *encryptKey; unsigned int ekeylen; EVP_PKEY *privateKey; memset(iv, '\0', sizeof(iv)); privateKey = ReadPrivateKey(PRIVFILE); if (!privateKey) { fprintf(stderr, "Error: can't load private key"); exit(1); } read(STDIN, &ekeylen, sizeof(ekeylen)); ekeylen = ntohl(ekeylen); if (ekeylen != EVP_PKEY_size(privateKey)) { EVP_PKEY_free(privateKey); fprintf(stderr, "keylength mismatch"); exit(1); } encryptKey = malloc(sizeof(char) * ekeylen); if (!encryptKey) { EVP_PKEY_free(privateKey); perror("malloc"); exit(1); } read(STDIN, encryptKey, ekeylen); read(STDIN, iv, sizeof(iv)); EVP_OpenInit(&ectx, EVP_des_ede3_cbc(), encryptKey, ekeylen, iv, privateKey); while(1) { int readlen = read(STDIN, ebuf, sizeof(ebuf)); if (readlen <= 0) { if (readlen < 0) perror("read"); break; } EVP_OpenUpdate(&ectx, buf, &buflen, ebuf, readlen); write(STDOUT, buf, buflen); } EVP_OpenFinal(&ectx, buf, &buflen); write(STDOUT, buf, buflen); EVP_PKEY_free(privateKey); free(encryptKey); }
uint8_t* decrypt(const char* keypath, const uint8_t* c, const size_t clen, size_t* plen, uint8_t* iv, uint8_t* ek, size_t ekl){ // Context and key EVP_CIPHER_CTX *decctx; FILE* dkeyfh; EVP_PKEY *dkey=NULL; // Return codes and errors unsigned long decerr; /* The buffer with the plaintext */ uint8_t* p; /* envelope related */ int outl; int plenint; const EVP_CIPHER* type = EVP_aes_256_cbc(); /* * Open a private key for decryption */ dkeyfh = fopen(keypath,"r"); if (!dkeyfh) { fprintf(stderr, "%s: Cannot open key file\n", __func__); p = NULL; goto exit_decrypt; } dkey = PEM_read_PrivateKey(dkeyfh, &dkey, NULL, NULL); if (!dkey){ fprintf(stderr,"Cannot read decryption key from file %s\n", keypath); p = NULL; fclose(dkeyfh); goto exit_decrypt; } decctx = malloc(sizeof(EVP_CIPHER_CTX)); if (decctx == NULL) { fprintf(stderr, "%s: Out of memory\n", __func__); p = NULL; fclose(dkeyfh); goto exit_decrypt; } EVP_CIPHER_CTX_init(decctx); if (!decctx){ fprintf(stderr,"Cannot initialize an decryption context\n"); p = NULL; goto cleanup_decrypt; } p = malloc(clen + EVP_CIPHER_block_size(type)); if (p == NULL) { fprintf(stderr,"%s: Out of memory\n", __func__); goto cleanup_decrypt; } if (EVP_OpenInit(decctx, type, ek, ekl, iv, dkey) != 1){ ERR_load_crypto_strings(); decerr = ERR_get_error(); fprintf(stderr,"Decrypt failed\n"); printf("%s\n", ERR_error_string(decerr, NULL)); ERR_free_strings(); p = NULL; goto cleanup_decrypt; } if (EVP_OpenUpdate( decctx, p, &plenint, c, clen) != 1){ ERR_load_crypto_strings(); decerr = ERR_get_error(); fprintf(stderr,"Decrypt failed\n"); printf("%s\n", ERR_error_string(decerr, NULL)); ERR_free_strings(); p = NULL; goto cleanup_decrypt; } if(EVP_OpenFinal(decctx, p, &outl) != 1){ ERR_load_crypto_strings(); decerr = ERR_get_error(); fprintf(stderr,"Decrypt failed\n"); printf("%s\n", ERR_error_string(decerr, NULL)); ERR_free_strings(); p = NULL; } *plen = outl + plenint; cleanup_decrypt: EVP_CIPHER_CTX_cleanup(decctx); free(decctx); EVP_PKEY_free(dkey); exit_decrypt: return p; }
unsigned char *rsa_decrypt(unsigned char *ciphertext, int *len) { EVP_CIPHER_CTX ctx; EVP_CIPHER_CTX_init(&ctx); EVP_PKEY *pkey; unsigned char *encrypted_key; unsigned int encrypted_key_length; uint32_t eklen_n; unsigned char iv[EVP_MAX_IV_LENGTH]; pkey = load_privkey("private.pem"); encrypted_key = malloc(EVP_PKEY_size(pkey)); // plaintext will always be equal to or lesser than length of ciphertext int plaintext_len = *len; // the length of ciphertest is at most plaintext + ciphers block size. int ciphertext_len = plaintext_len + EVP_CIPHER_block_size(EVP_des_ede_cbc()); unsigned char *plaintext = (unsigned char *)malloc(ciphertext_len); /* First need to fetch the encrypted key length, encrypted key and IV */ int pos = 0; memcpy(&eklen_n, ciphertext + pos, sizeof(eklen_n)); pos += sizeof(eklen_n); encrypted_key_length = ntohl(eklen_n); memcpy(encrypted_key, ciphertext + pos, encrypted_key_length); pos += encrypted_key_length; memcpy(iv, ciphertext + pos, EVP_CIPHER_iv_length(EVP_des_ede_cbc())); pos += EVP_CIPHER_iv_length(EVP_des_ede_cbc()); // Now we have our encrypted_key and the iv we can decrypt the reamining // data if (!EVP_OpenInit(&ctx, EVP_des_ede_cbc(), encrypted_key, encrypted_key_length, iv, pkey)) { fprintf(stderr, "EVP_OpenInit: failed.\n"); goto out_free; } if (!EVP_OpenUpdate(&ctx, plaintext, &plaintext_len, ciphertext + pos, ciphertext_len)) { fprintf(stderr, "EVP_OpenUpdate: failed.\n"); goto out_free; } int total_len = plaintext_len; if (!EVP_OpenFinal(&ctx, plaintext + total_len, &plaintext_len)) { fprintf(stderr, "EVP_OpenFinal warning: failed.\n"); } out_free: EVP_PKEY_free(pkey); free(encrypted_key); EVP_CIPHER_CTX_cleanup(&ctx); *len = plaintext_len + total_len; return plaintext; }
/* * RSA public decryption function. * Dencrypt 'in_len' bytes from 'envelope' buffer with the private key contained in 'priv_key_file' * Parameter 'outlen' is the size of output buffer * It returns the received plaintext or NULL if an error occurs. */ unsigned char* asym_decrypt(unsigned char* envelope, int in_len, int* out_len, char* priv_key_file){ EVP_PKEY* priv_key; int ret; EVP_CIPHER_CTX* ctx; unsigned char* encrypted_key; int encrypted_key_len; unsigned char* iv; int iv_len; unsigned char* ciphertext; int ciphertext_len; unsigned char* output; int output_len; int app; if(ciphertext == NULL || in_len < 0 || out_len == NULL || priv_key_file == NULL) return NULL; //Reads the receiver's public key for its file priv_key = read_priv_key(priv_key_file); //Note: envelope format -> <IV><Dim_Key><Ecrypt_KEY><Ciphertext> //Set to the head the iv pointer iv = envelope; iv_len = EVP_CIPHER_iv_length(SYM_CIPHER); //Read from the envelop the encrypted_key_len memcpy(&encrypted_key_len, envelope + iv_len, sizeof(int)); //Set the encrypted_key pointer encrypted_key = envelope + iv_len + sizeof(int); //Set the ciphertext pointer ciphertext = envelope + iv_len + sizeof(int) + encrypted_key_len; ciphertext_len = in_len - iv_len - sizeof(int) - encrypted_key_len; //Instantiate and initialize the context ctx = (EVP_CIPHER_CTX*)malloc(sizeof(EVP_CIPHER_CTX)); EVP_CIPHER_CTX_init(ctx); ret = EVP_OpenInit(ctx, SYM_CIPHER, encrypted_key, encrypted_key_len, iv, priv_key); if(ret == 0) goto error; //Decrypt the ciphertext output_len = ciphertext_len; output = malloc(output_len); output_len = 0; ret = EVP_OpenUpdate(ctx, output, &app, ciphertext, ciphertext_len); if(ret == 0) goto error; output_len += app; ret = EVP_OpenFinal(ctx, output + app, &app); if(ret == 0) goto error; output_len += app; *out_len = output_len; //Cleanup EVP_CIPHER_CTX_cleanup(ctx); free(ctx); free(priv_key); return output; error: if(ctx != NULL){ EVP_CIPHER_CTX_cleanup(ctx); free(ctx); } if(encrypted_key != NULL) free(ciphertext); if(priv_key != NULL) free(priv_key); if(iv != NULL) free(iv); if(ciphertext != NULL) free(ciphertext); if(output != NULL) free(output); return NULL; }
/** Decrypt some data. * \param key Key to use for decryption. Use gale_crypto_target() to find the * keys you can use, pick one you own, and supply private key data. * \param data Encrypted group. Will be replaced by decrypted group. * \return Nonzero iff the operation succeeded. * \sa gale_crypto_seal(), gale_crypto_target() */ int gale_crypto_open(struct gale_group key,struct gale_group *cipher) { struct gale_fragment frag; struct gale_data data; unsigned char iv[IV_LEN]; u32 i,key_count; EVP_PKEY *private_key = NULL; RSA *rsa; struct gale_text raw_name; struct gale_data session_key,plain; EVP_CIPHER_CTX *context = EVP_CIPHER_CTX_new(); int length,is_successful = 0; if (gale_group_null(*cipher)) goto cleanup; frag = gale_group_first(*cipher); if (gale_text_compare(G_("security/encryption"),frag.name) || frag_data != frag.type) { gale_alert(GALE_WARNING,G_("can't decrypt unencrypted data"),0); goto cleanup; } data = frag.value.data; if (!gale_unpack_compare(&data,magic2,sizeof(magic2)) || !gale_unpack_copy(&data,iv,sizeof(iv)) || !gale_unpack_u32(&data,&key_count)) goto cleanup; private_key = EVP_PKEY_new(); EVP_PKEY_assign_RSA(private_key,RSA_new()); rsa = EVP_PKEY_get0_RSA(private_key); raw_name = key_i_swizzle(crypto_i_rsa(key,rsa)); if (!crypto_i_private_valid(rsa)) { gale_alert(GALE_WARNING,G_("invalid private key"),0); goto cleanup; } session_key = null_data; for (i = 0; i < key_count; ++i) { struct gale_text name; if (!gale_unpack_text(&data,&name)) goto cleanup; if (gale_text_compare(raw_name,name)) { if (!gale_unpack_skip(&data)) goto cleanup; continue; } if (!gale_unpack_u32(&data,&session_key.l)) goto cleanup; session_key.p = gale_malloc(session_key.l); if (!gale_unpack_copy(&data,session_key.p,session_key.l)) goto cleanup; } if (0 == session_key.l) { gale_alert(GALE_WARNING,G_("key doesn't fit encrypted data"),0); goto cleanup; } if (!EVP_OpenInit(context,EVP_des_ede3_cbc(), session_key.p,session_key.l,iv,private_key)) { crypto_i_error(); goto cleanup; } plain.p = gale_malloc(data.l); plain.l = 0; EVP_OpenUpdate(context,plain.p + plain.l,&length,data.p,data.l); plain.l += length; EVP_OpenFinal(context,plain.p + plain.l,&length); plain.l += length; if (!gale_unpack_u32(&plain,&i) || 0 != i || !gale_unpack_group(&plain,cipher)) { gale_alert(GALE_WARNING,G_("invalid encrypted data"),0); goto cleanup; } is_successful = 1; cleanup: if (NULL != private_key) EVP_PKEY_free(private_key); return is_successful; }