themis_status_t themis_secure_message_ec_decrypter_proceed(themis_secure_message_ec_t* ctx, const uint8_t* wrapped_message, const size_t wrapped_message_length, uint8_t* message, size_t* message_length){ THEMIS_CHECK_PARAM(ctx!=NULL); THEMIS_CHECK_PARAM(wrapped_message_length>sizeof(themis_secure_encrypted_message_hdr_t)); themis_secure_encrypted_message_hdr_t* hdr=(themis_secure_encrypted_message_hdr_t*)wrapped_message; THEMIS_CHECK_PARAM(hdr->message_hdr.message_type==THEMIS_SECURE_MESSAGE_EC_ENCRYPTED && wrapped_message_length==hdr->message_hdr.message_length); size_t computed_length=0; THEMIS_CHECK(themis_secure_cell_decrypt_seal(ctx->shared_secret, ctx->shared_secret_length, NULL,0,wrapped_message+sizeof(themis_secure_encrypted_message_hdr_t), wrapped_message_length-sizeof(themis_secure_encrypted_message_hdr_t), NULL, &computed_length)); if(message==NULL || (*message_length)<computed_length){ (*message_length)=computed_length; return THEMIS_BUFFER_TOO_SMALL; } THEMIS_CHECK(themis_secure_cell_decrypt_seal(ctx->shared_secret, ctx->shared_secret_length, NULL,0,wrapped_message+sizeof(themis_secure_encrypted_message_hdr_t), wrapped_message_length-sizeof(themis_secure_encrypted_message_hdr_t), message, message_length)==THEMIS_SUCCESS); return THEMIS_SUCCESS; }
themis_status_t themis_secure_message_rsa_encrypter_destroy(themis_secure_message_rsa_encrypter_t* ctx){ THEMIS_CHECK_PARAM(ctx!=NULL); if(ctx->asym_cipher!=NULL){ soter_asym_cipher_destroy(ctx->asym_cipher); } free(ctx); return THEMIS_SUCCESS; }
themis_status_t themis_secure_message_wrap(const uint8_t* private_key, const size_t private_key_length, const uint8_t* public_key, const size_t public_key_length, const uint8_t* message, const size_t message_length, uint8_t* wrapped_message, size_t* wrapped_message_length){ THEMIS_CHECK_PARAM(private_key!=NULL); THEMIS_CHECK_PARAM(private_key_length!=0); THEMIS_CHECK_PARAM(message!=NULL); THEMIS_CHECK_PARAM(message_length!=0); THEMIS_CHECK_PARAM(wrapped_message_length!=NULL); if(public_key==NULL && public_key_length==0){ themis_secure_message_signer_t* ctx=NULL; ctx = themis_secure_message_signer_init(private_key, private_key_length); THEMIS_CHECK(ctx!=NULL); themis_status_t res=themis_secure_message_signer_proceed(ctx, message, message_length, wrapped_message, wrapped_message_length); themis_secure_message_signer_destroy(ctx); return res; } else { THEMIS_CHECK_PARAM(public_key!=NULL); THEMIS_CHECK_PARAM(public_key_length!=0); themis_secure_message_encrypter_t* ctx=NULL; ctx = themis_secure_message_encrypter_init(private_key, private_key_length, public_key, public_key_length); THEMIS_CHECK(ctx!=NULL); themis_status_t res=themis_secure_message_encrypter_proceed(ctx, message, message_length, wrapped_message, wrapped_message_length); themis_secure_message_encrypter_destroy(ctx); return res; } return THEMIS_INVALID_PARAMETER; }
themis_status_t themis_secure_message_rsa_decrypter_proceed(themis_secure_message_rsa_decrypter_t* ctx, const uint8_t* wrapped_message, const size_t wrapped_message_length, uint8_t* message, size_t* message_length){ THEMIS_CHECK_PARAM(wrapped_message_length>sizeof(themis_secure_rsa_encrypted_message_hdr_t)); THEMIS_CHECK_PARAM(((const themis_secure_encrypted_message_hdr_t*)wrapped_message)->message_hdr.message_type==THEMIS_SECURE_MESSAGE_RSA_ENCRYPTED); THEMIS_CHECK_PARAM(((const themis_secure_encrypted_message_hdr_t*)wrapped_message)->message_hdr.message_length==wrapped_message_length); size_t ml=0; THEMIS_CHECK(themis_secure_cell_decrypt_seal((const uint8_t*)"123",3,NULL,0,wrapped_message+sizeof(themis_secure_rsa_encrypted_message_hdr_t)+((const themis_secure_rsa_encrypted_message_hdr_t*)wrapped_message)->encrypted_passwd_length, wrapped_message_length-sizeof(themis_secure_rsa_encrypted_message_hdr_t)-((const themis_secure_rsa_encrypted_message_hdr_t*)wrapped_message)->encrypted_passwd_length, NULL, &ml)==THEMIS_BUFFER_TOO_SMALL); if((message==NULL)||((*message_length)<ml)){ (*message_length)=ml; return THEMIS_BUFFER_TOO_SMALL; } uint8_t sym_ctx_buffer[1024]; size_t sym_ctx_length_=sizeof(sym_ctx_buffer); const uint8_t* wrapped_message_=wrapped_message; wrapped_message_+=sizeof(themis_secure_rsa_encrypted_message_hdr_t); size_t wrapped_message_length_=wrapped_message_length; wrapped_message_length_-=sizeof(themis_secure_rsa_encrypted_message_hdr_t); THEMIS_CHECK(soter_asym_cipher_decrypt(ctx->asym_cipher, wrapped_message_, ((const themis_secure_rsa_encrypted_message_hdr_t*)wrapped_message)->encrypted_passwd_length, sym_ctx_buffer, &sym_ctx_length_)==THEMIS_SUCCESS); wrapped_message_+=((const themis_secure_rsa_encrypted_message_hdr_t*)wrapped_message)->encrypted_passwd_length; wrapped_message_length_-=((const themis_secure_rsa_encrypted_message_hdr_t*)wrapped_message)->encrypted_passwd_length; THEMIS_CHECK(themis_secure_cell_decrypt_seal(sym_ctx_buffer,sym_ctx_length_,NULL,0,wrapped_message_, wrapped_message_length_, message, message_length)==THEMIS_SUCCESS); return THEMIS_SUCCESS; }
themis_status_t themis_secure_message_ec_encrypter_proceed(themis_secure_message_ec_t* ctx, const uint8_t* message, const size_t message_length, uint8_t* wrapped_message, size_t* wrapped_message_length){ THEMIS_CHECK_PARAM(ctx!=NULL); size_t encrypted_message_length=0; THEMIS_CHECK(themis_secure_cell_encrypt_seal(ctx->shared_secret, ctx->shared_secret_length, NULL, 0, message, message_length, NULL, &encrypted_message_length)==THEMIS_BUFFER_TOO_SMALL && encrypted_message_length!=0); if(wrapped_message==NULL || (*wrapped_message_length)<(sizeof(themis_secure_encrypted_message_hdr_t)+encrypted_message_length)){ (*wrapped_message_length)=(sizeof(themis_secure_encrypted_message_hdr_t)+encrypted_message_length); return THEMIS_BUFFER_TOO_SMALL; } themis_secure_encrypted_message_hdr_t* hdr=(themis_secure_encrypted_message_hdr_t*)wrapped_message; hdr->message_hdr.message_type=THEMIS_SECURE_MESSAGE_EC_ENCRYPTED; hdr->message_hdr.message_length=(uint32_t)(sizeof(themis_secure_encrypted_message_hdr_t)+encrypted_message_length); encrypted_message_length=(*wrapped_message_length)-sizeof(themis_secure_encrypted_message_hdr_t); THEMIS_CHECK(themis_secure_cell_encrypt_seal(ctx->shared_secret, ctx->shared_secret_length, NULL,0, message, message_length, wrapped_message+sizeof(themis_secure_encrypted_message_hdr_t), &encrypted_message_length)==THEMIS_SUCCESS); (*wrapped_message_length)=encrypted_message_length+sizeof(themis_secure_encrypted_message_hdr_t); return THEMIS_SUCCESS; }
themis_status_t themis_secure_message_unwrap(const uint8_t* private_key, const size_t private_key_length, const uint8_t* public_key, const size_t public_key_length, const uint8_t* wrapped_message, const size_t wrapped_message_length, uint8_t* message, size_t* message_length){ THEMIS_CHECK_PARAM(public_key!=NULL); THEMIS_CHECK_PARAM(public_key_length!=0); THEMIS_CHECK_PARAM(wrapped_message!=NULL); THEMIS_CHECK_PARAM(wrapped_message_length!=0); THEMIS_CHECK_PARAM(message_length!=NULL); themis_secure_message_hdr_t* message_hdr=(themis_secure_message_hdr_t*)wrapped_message; THEMIS_CHECK_PARAM(IS_THEMIS_SECURE_MESSAGE_SIGNED(message_hdr->message_type) || IS_THEMIS_SECURE_MESSAGE_ENCRYPTED(message_hdr->message_type)); THEMIS_CHECK_PARAM(wrapped_message_length>=THEMIS_SECURE_MESSAGE_LENGTH(message_hdr)); if(IS_THEMIS_SECURE_MESSAGE_SIGNED(message_hdr->message_type)){ themis_secure_message_verifier_t* ctx=NULL; ctx = themis_secure_message_verifier_init(public_key, public_key_length); THEMIS_CHECK(ctx!=NULL); themis_status_t res=themis_secure_message_verifier_proceed(ctx, wrapped_message, wrapped_message_length, message, message_length); themis_secure_message_verifier_destroy(ctx); return res; } else{ THEMIS_CHECK_PARAM(private_key!=NULL); THEMIS_CHECK_PARAM(private_key_length!=0); themis_secure_message_decrypter_t* ctx=NULL; ctx = themis_secure_message_decrypter_init(private_key, private_key_length, public_key, public_key_length); THEMIS_CHECK(ctx!=NULL); themis_status_t res=themis_secure_message_decrypter_proceed(ctx, wrapped_message, wrapped_message_length, message, message_length); themis_secure_message_decrypter_destroy(ctx); return res; } return THEMIS_INVALID_PARAMETER; }
themis_status_t themis_secure_message_ec_encrypter_destroy(themis_secure_message_ec_t* ctx){ THEMIS_CHECK_PARAM(ctx!=NULL); free(ctx); return THEMIS_SUCCESS; }