Beispiel #1
0
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_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_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_message_destroy(themis_message_t* ctx){
  THEMIS_CHECK(ctx);
  if(ctx->data!=NULL){
    free(ctx->data);
  }
  free(ctx);
  ctx=NULL;
  return THEMIS_SUCCESS;
}
themis_status_t themis_message_set(themis_message_t* ctx, const uint8_t* message, const size_t message_length){
  THEMIS_CHECK(ctx);
  THEMIS_CHECK(message);
  THEMIS_CHECK(message_length!=0);
  if(ctx->length<message_length){
    if(!ctx){
	ctx->data=malloc(message_length);
    } else {
	ctx->data=realloc(ctx->data, message_length);
    }
    if(!(ctx->data)){
      ctx->length=0;
      return THEMIS_FAIL;
    }
    ctx->length=message_length;
  }
  memcpy(ctx->data, message, message_length);
  return THEMIS_SUCCESS;
}
themis_status_t themis_secure_message_verifier_proceed(themis_secure_message_verifier_t* ctx, const uint8_t* wrapped_message, const size_t wrapped_message_length, uint8_t* message, size_t* message_length)
{
  THEMIS_CHECK(ctx!=NULL);
  THEMIS_CHECK(wrapped_message!=NULL && wrapped_message_length!=0 && message_length!=NULL);
  themis_secure_signed_message_hdr_t* msg=(themis_secure_signed_message_hdr_t*)wrapped_message;
  if(((msg->message_hdr.message_type==THEMIS_SECURE_MESSAGE_RSA_SIGNED && soter_verify_get_alg_id(ctx->verify_ctx)!=SOTER_SIGN_rsa_pss_pkcs8)
      || (msg->message_hdr.message_type==THEMIS_SECURE_MESSAGE_EC_SIGNED && soter_verify_get_alg_id(ctx->verify_ctx)!=SOTER_SIGN_ecdsa_none_pkcs8))
     && (msg->message_hdr.message_length+msg->signature_length+sizeof(themis_secure_message_hdr_t)>wrapped_message_length)){
    return THEMIS_INVALID_PARAMETER;
  }
  if(message == NULL || (*message_length)<msg->message_hdr.message_length){
    (*message_length)=msg->message_hdr.message_length;
    return THEMIS_BUFFER_TOO_SMALL;
  }
  THEMIS_CHECK(soter_verify_update(ctx->verify_ctx, wrapped_message+sizeof(themis_secure_signed_message_hdr_t), msg->message_hdr.message_length)==THEMIS_SUCCESS);
  THEMIS_CHECK(soter_verify_final(ctx->verify_ctx, wrapped_message+sizeof(themis_secure_signed_message_hdr_t)+msg->message_hdr.message_length, msg->signature_length)==THEMIS_SUCCESS);
  memcpy(message,wrapped_message+sizeof(themis_secure_signed_message_hdr_t),msg->message_hdr.message_length);
  (*message_length)=msg->message_hdr.message_length;
  return THEMIS_SUCCESS;
}
themis_status_t themis_secure_message_decrypter_destroy(themis_secure_message_decrypter_t* ctx){
  THEMIS_CHECK(ctx!=NULL);
  switch(ctx->alg){
  case SOTER_SIGN_ecdsa_none_pkcs8:
    return themis_secure_message_ec_decrypter_destroy(ctx->ctx.ec_encrypter);
  case SOTER_SIGN_rsa_pss_pkcs8:
    return themis_secure_message_rsa_decrypter_destroy(ctx->ctx.rsa_encrypter);
  default:
    return THEMIS_FAIL;
  }
  return THEMIS_INVALID_PARAMETER;;  
}
themis_status_t themis_secure_message_decrypter_proceed(themis_secure_message_decrypter_t* ctx, const uint8_t* wrapped_message, const size_t wrapped_message_length, uint8_t* message, size_t* message_length){
  THEMIS_CHECK(ctx!=NULL);
  switch(ctx->alg){
  case SOTER_SIGN_ecdsa_none_pkcs8:
    return themis_secure_message_ec_decrypter_proceed(ctx->ctx.ec_encrypter, wrapped_message, wrapped_message_length, message, message_length);
  case SOTER_SIGN_rsa_pss_pkcs8:
    return themis_secure_message_rsa_decrypter_proceed(ctx->ctx.rsa_encrypter, wrapped_message, wrapped_message_length, message, message_length);
  default:
    return THEMIS_FAIL;
  }
  return THEMIS_FAIL;
}
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_signer_proceed(themis_secure_message_signer_t* ctx, const uint8_t* message, const size_t message_length, uint8_t* wrapped_message, size_t* wrapped_message_length)
{
  THEMIS_CHECK(ctx!=NULL && ctx->sign_ctx!=NULL);
  THEMIS_CHECK(message!=NULL && message_length!=0 && wrapped_message_length!=NULL);
  uint8_t* signature=NULL;
  size_t signature_length=0;
  THEMIS_CHECK(soter_sign_update(ctx->sign_ctx, message, message_length)==THEMIS_SUCCESS);
  THEMIS_CHECK(soter_sign_final(ctx->sign_ctx, signature, &signature_length)==THEMIS_BUFFER_TOO_SMALL);
  if(wrapped_message==NULL ||(message_length+signature_length+sizeof(themis_secure_signed_message_hdr_t)>(*wrapped_message_length))){
    (*wrapped_message_length)=message_length+signature_length+sizeof(themis_secure_signed_message_hdr_t);
    return THEMIS_BUFFER_TOO_SMALL;
  }
  signature=malloc(signature_length);
  THEMIS_CHECK(signature!=NULL);
  if(soter_sign_final(ctx->sign_ctx, signature, &signature_length)!=THEMIS_SUCCESS){
    free(signature);
    return THEMIS_FAIL;
  }
  themis_secure_signed_message_hdr_t hdr;
  switch(soter_sign_get_alg_id(ctx->sign_ctx)){
  case SOTER_SIGN_ecdsa_none_pkcs8:
    hdr.message_hdr.message_type=THEMIS_SECURE_MESSAGE_EC_SIGNED;
    break;
  case SOTER_SIGN_rsa_pss_pkcs8:
    hdr.message_hdr.message_type=THEMIS_SECURE_MESSAGE_RSA_SIGNED;
    break;
  default:
    return THEMIS_INVALID_PARAMETER;  
  };
  hdr.message_hdr.message_length=(uint32_t)message_length;
  hdr.signature_length=(uint32_t)signature_length;
  memcpy(wrapped_message,&hdr,sizeof(themis_secure_signed_message_hdr_t));
  memcpy(wrapped_message+sizeof(themis_secure_signed_message_hdr_t),message,message_length);
  memcpy(wrapped_message+sizeof(themis_secure_signed_message_hdr_t)+message_length,signature,signature_length);
  (*wrapped_message_length)=message_length+signature_length+sizeof(themis_secure_signed_message_hdr_t);
  return THEMIS_SUCCESS;
}
Beispiel #11
0
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_rsa_encrypter_proceed(themis_secure_message_rsa_encrypter_t* ctx, const uint8_t* message, const size_t message_length, uint8_t* wrapped_message, size_t* wrapped_message_length){
  size_t symm_passwd_length=0;
  size_t seal_message_length=0;
  THEMIS_CHECK(soter_asym_cipher_encrypt(ctx->asym_cipher, (const uint8_t*)"123", 3, NULL, &symm_passwd_length)==THEMIS_BUFFER_TOO_SMALL);
  THEMIS_CHECK(themis_secure_cell_encrypt_seal((const uint8_t*)"123", 3, NULL, 0, message, message_length, NULL, &seal_message_length)==THEMIS_BUFFER_TOO_SMALL);
  if(wrapped_message==NULL || (*wrapped_message_length)<(sizeof(themis_secure_rsa_encrypted_message_hdr_t)+symm_passwd_length+seal_message_length)){
    (*wrapped_message_length)=(sizeof(themis_secure_rsa_encrypted_message_hdr_t)+symm_passwd_length+seal_message_length);
    return THEMIS_BUFFER_TOO_SMALL;
  }
//  symm_init_ctx_t symm_passwd_salt;
  uint8_t symm_passwd[THEMIS_RSA_SYMM_PASSWD_LENGTH];
  THEMIS_CHECK(soter_rand(symm_passwd, sizeof(symm_passwd))==THEMIS_SUCCESS);
  uint8_t* encrypted_symm_pass=wrapped_message+sizeof(themis_secure_rsa_encrypted_message_hdr_t);
  size_t encrypted_symm_pass_length=symm_passwd_length;
  THEMIS_CHECK(soter_asym_cipher_encrypt(ctx->asym_cipher, symm_passwd, sizeof(symm_passwd), encrypted_symm_pass, &encrypted_symm_pass_length)==THEMIS_SUCCESS);
  (((themis_secure_rsa_encrypted_message_hdr_t*)wrapped_message)->encrypted_passwd_length)=(uint32_t)encrypted_symm_pass_length;
  uint8_t* encrypted_message=encrypted_symm_pass+encrypted_symm_pass_length;
  size_t encrypted_message_length=seal_message_length;
  THEMIS_CHECK(themis_secure_cell_encrypt_seal(symm_passwd, sizeof(symm_passwd), NULL, 0, message, message_length, encrypted_message, &encrypted_message_length)==THEMIS_SUCCESS);
  (*wrapped_message_length)=sizeof(themis_secure_rsa_encrypted_message_hdr_t)+encrypted_symm_pass_length+encrypted_message_length;
  ((themis_secure_encrypted_message_hdr_t*)wrapped_message)->message_hdr.message_type=THEMIS_SECURE_MESSAGE_RSA_ENCRYPTED;
  ((themis_secure_encrypted_message_hdr_t*)wrapped_message)->message_hdr.message_length=(uint32_t)(*wrapped_message_length);
  return THEMIS_SUCCESS;
}
Beispiel #13
0
themis_status_t themis_gen_key_pair(soter_sign_alg_t alg,
				    uint8_t* private_key,
				    size_t* private_key_length,
				    uint8_t* public_key,
				    size_t* public_key_length)
{
  soter_sign_ctx_t* ctx=soter_sign_create(alg,NULL,0,NULL,0);
  THEMIS_CHECK(ctx!=NULL);
  soter_status_t res=soter_sign_export_key(ctx, private_key, private_key_length, true);
  if(res!=THEMIS_SUCCESS && res != THEMIS_BUFFER_TOO_SMALL){
    soter_sign_destroy(ctx);
    return res;
  }
  soter_status_t res2=soter_sign_export_key(ctx, public_key, public_key_length, false);
  if(res2!=THEMIS_SUCCESS && res2!=THEMIS_BUFFER_TOO_SMALL){
    soter_sign_destroy(ctx);
    return res;
  }
  soter_sign_destroy(ctx);
  if(res==THEMIS_BUFFER_TOO_SMALL || res2==THEMIS_BUFFER_TOO_SMALL){
    return THEMIS_BUFFER_TOO_SMALL;
  }
  return THEMIS_SUCCESS;
}