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_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; }
v8::Handle<v8::Value> SecureCellSeal::decrypt(const v8::Arguments& args) { v8::HandleScope scope; SecureCellSeal* obj = node::ObjectWrap::Unwrap<SecureCellSeal>(args.This()); size_t length=0; const uint8_t* context=NULL; size_t context_length=0; if(args.Length()==2) { context = (const uint8_t*)(node::Buffer::Data(args[1])); context_length = node::Buffer::Length(args[1]); } if(themis_secure_cell_decrypt_seal(&(obj->key_)[0], obj->key_.size(), context, context_length, (const uint8_t*)(node::Buffer::Data(args[0])), node::Buffer::Length(args[0]), NULL, &length)!=THEMIS_BUFFER_TOO_SMALL) { ThrowException(v8::Exception::Error(v8::String::New("Secure Cell (seal) failed decrypting"))); return scope.Close(v8::Undefined()); } uint8_t* data=new uint8_t[length]; if(themis_secure_cell_decrypt_seal(&(obj->key_)[0], obj->key_.size(), context, context_length, (const uint8_t*)(node::Buffer::Data(args[0])), node::Buffer::Length(args[0]), data, &length)!=THEMIS_SUCCESS) { ThrowException(v8::Exception::Error(v8::String::New("Secure Cell (seal) failed decrypting"))); delete data; return scope.Close(v8::Undefined()); } node::Buffer *buffer = node::Buffer::New((const char*)(data), length); delete data; return scope.Close(buffer->handle_); }
void SecureCellSeal::decrypt(const Nan::FunctionCallbackInfo<v8::Value>& args) { themis_status_t status = THEMIS_FAIL; SecureCellSeal* obj = Nan::ObjectWrap::Unwrap<SecureCellSeal>(args.This()); if (args.Length() < 1) { ThrowParameterError("Secure Cell (Seal) failed to decrypt", "not enough arguments, expected message"); args.GetReturnValue().SetUndefined(); return; } if (!args[0]->IsUint8Array()) { ThrowParameterError("Secure Cell (Seal) failed to decrypt", "message is not a byte buffer, use ByteBuffer or Uint8Array"); args.GetReturnValue().SetUndefined(); return; } if (node::Buffer::Length(args[0]) == 0) { ThrowParameterError("Secure Cell (Seal) failed to decrypt", "message is empty"); args.GetReturnValue().SetUndefined(); return; } size_t length = 0; const uint8_t* context = NULL; size_t context_length = 0; if (args.Length() == 2) { if (!args[1]->IsUint8Array()) { ThrowParameterError("Secure Cell (Seal) failed to decrypt", "context is not a byte buffer, use ByteBuffer or Uint8Array"); args.GetReturnValue().SetUndefined(); return; } context = (const uint8_t*)(node::Buffer::Data(args[1])); context_length = node::Buffer::Length(args[1]); } status = themis_secure_cell_decrypt_seal(&(obj->key_)[0], obj->key_.size(), context, context_length, (const uint8_t*)(node::Buffer::Data(args[0])), node::Buffer::Length(args[0]), NULL, &length); if (status != THEMIS_BUFFER_TOO_SMALL) { ThrowError("Secure Cell (Seal) failed to decrypt", status); args.GetReturnValue().SetUndefined(); return; } uint8_t* data = (uint8_t*)malloc(length); status = themis_secure_cell_decrypt_seal(&(obj->key_)[0], obj->key_.size(), context, context_length, (const uint8_t*)(node::Buffer::Data(args[0])), node::Buffer::Length(args[0]), data, &length); if (status != THEMIS_SUCCESS) { ThrowError("Secure Cell (Seal) failed to decrypt", status); free(data); args.GetReturnValue().SetUndefined(); return; } args.GetReturnValue().Set(Nan::NewBuffer((char*)(data), length).ToLocalChecked()); }
int main(int argc, char** argv) { themis_status_t err = THEMIS_SUCCESS; /* * Read test data. */ if (argc != 2) { fprintf(stderr, "usage:\n\t%s <input-file>\n", argv[0]); return 1; } FILE* input = fopen(argv[1], "rb"); if (!input) { fprintf(stderr, "failed to open %s: %s\n", argv[1], strerror(errno)); return 1; } uint8_t* master_key_bytes = NULL; size_t master_key_size = 0; if (read_line_binary(input, &master_key_bytes, &master_key_size)) { fprintf(stderr, "failed to read %s: %s\n", argv[1], strerror(errno)); return 1; } uint8_t* user_context_bytes = NULL; size_t user_context_size = 0; if (read_line_binary(input, &user_context_bytes, &user_context_size)) { fprintf(stderr, "failed to read %s: %s\n", argv[1], strerror(errno)); return 1; } uint8_t* message_bytes = NULL; size_t message_size = 0; if (read_line_binary(input, &message_bytes, &message_size)) { fprintf(stderr, "failed to read %s: %s\n", argv[1], strerror(errno)); return 1; } fclose(input); /* * Try decrypting it. */ uint8_t* decrypted_bytes = NULL; size_t decrypted_size = 0; err = themis_secure_cell_decrypt_seal(master_key_bytes, master_key_size, user_context_bytes, user_context_size, message_bytes, message_size, NULL, &decrypted_size); if (err != THEMIS_BUFFER_TOO_SMALL) { fprintf(stderr, "failed to determine decrypted message size: %d\n", err); return 2; } decrypted_bytes = malloc(decrypted_size); if (!decrypted_bytes) { fprintf(stderr, "failed to allocate memory for decrypted message (%zu bytes)\n", decrypted_size); return 2; } err = themis_secure_cell_decrypt_seal(master_key_bytes, master_key_size, user_context_bytes, user_context_size, message_bytes, message_size, decrypted_bytes, &decrypted_size); if (err != THEMIS_SUCCESS) { fprintf(stderr, "failed to decrypt message: %d\n", err); return 2; } return 0; }