/*Public functions*/ AXIS2_EXTERN axis2_status_t AXIS2_CALL oxs_xml_key_info_build(const axutil_env_t *env, axiom_node_t *parent, oxs_x509_cert_t *cert, oxs_key_info_build_pattern_t pattern) { axis2_status_t status = AXIS2_FAILURE; axiom_node_t *key_info_node = NULL; /*Build the KeyInfo node*/ key_info_node = oxs_token_build_key_info_element(env, parent); if(OXS_KIBP_X509DATA_X509CERTIFICATE == pattern){ status = oxs_xml_key_info_build_x509_data_x509_certificate(env, key_info_node, cert); }else if(OXS_KIBP_X509DATA_ISSUER_SERIAL == pattern){ status = oxs_xml_key_info_build_x509_data_issuer_serial(env, key_info_node, cert); }else{ /*We do not support*/ } return status; }
axiom_node_t * AXIS2_CALL create_key_info(const axutil_env_t *env, rampart_saml_token_t *saml) { axiom_node_t *key_info = NULL; oxs_key_t *session_key = NULL; axis2_status_t status = AXIS2_FAILURE; oxs_asym_ctx_t * asym_ctx = NULL; axis2_char_t *key_info_str = NULL; oxs_x509_cert_t *cert = NULL; /* Set the receiver certificate file. This public key will be used to encrypt the session key.*/ axis2_char_t *certificate_file = axutil_stracat(env, axis2c_home, RECEIVER_CERTIFICATE_FILE); session_key = oxs_key_create(env); status = oxs_key_for_algo(session_key, env, NULL); key_info = oxs_token_build_key_info_element(env, NULL); /* Create the asym_ctx_t and populate it.*/ asym_ctx = oxs_asym_ctx_create(env); oxs_asym_ctx_set_algorithm(asym_ctx, env, OXS_HREF_RSA_PKCS1); oxs_asym_ctx_set_operation(asym_ctx, env, OXS_ASYM_CTX_OPERATION_PUB_ENCRYPT); cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, certificate_file); if (!cert) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Certificate cannot be loaded"); return NULL; } oxs_asym_ctx_set_certificate(asym_ctx, env, cert); status = oxs_xml_enc_encrypt_key(env, asym_ctx, key_info, session_key, NULL); rampart_saml_token_set_session_key(saml, env, session_key); key_info_str = axiom_node_to_string(key_info, env); return key_info; }
/*For SOAP this parent is the wsse:Security node*/ AXIS2_EXTERN axis2_status_t AXIS2_CALL oxs_xml_enc_encrypt_key( const axutil_env_t *env, oxs_asym_ctx_t * asym_ctx, axiom_node_t *parent, oxs_key_t *sym_key, axutil_array_list_t *id_list) { axis2_char_t *algorithm = NULL; axis2_char_t *encrypted_key_data = NULL; axis2_char_t *st_ref_pattern = NULL; oxs_buffer_t *input = NULL; oxs_buffer_t *result = NULL; axiom_node_t *encrypted_key_node = NULL; axiom_node_t *enc_mtd_node = NULL; axiom_node_t *key_info_node = NULL; axiom_node_t *stref_node = NULL; axiom_node_t *cd_node = NULL; axiom_node_t *cv_node = NULL; axis2_status_t status = AXIS2_FAILURE; axis2_char_t* encrypted_key_hash = NULL; int decoded_len = 0; axis2_char_t *decoded_enc_sec = NULL; /*Create input buffer*/ input = oxs_buffer_create(env); oxs_buffer_populate(input, env, oxs_key_get_data(sym_key, env), oxs_key_get_size(sym_key, env)); /*Create an empty buffer to collect results*/ result = oxs_buffer_create(env); /*Call encryption*/ status = oxs_encryption_asymmetric_crypt(env, asym_ctx, input, result); /*Free input*/ oxs_buffer_free(input, env); input = NULL; if(AXIS2_FAILURE == status) { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED, "Assymmetric key encryption failed"); return AXIS2_FAILURE; } /*Get the encrypted key*/ encrypted_key_data = (axis2_char_t *)oxs_buffer_get_data(result, env); /*Build nodes*/ encrypted_key_node = oxs_token_build_encrypted_key_element(env, parent); algorithm = oxs_asym_ctx_get_algorithm(asym_ctx, env); enc_mtd_node = oxs_token_build_encryption_method_element(env, encrypted_key_node, algorithm); key_info_node = oxs_token_build_key_info_element(env, encrypted_key_node); stref_node = oxs_token_build_security_token_reference_element(env, key_info_node); /*Get the ST REF pattern. If not set the default*/ st_ref_pattern = oxs_asym_ctx_get_st_ref_pattern(asym_ctx, env); if((!st_ref_pattern) || (0 == axutil_strcmp(st_ref_pattern, ""))) { st_ref_pattern = OXS_STR_DEFAULT; } if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_ISSUER_SERIAL)) { status = oxs_xml_enc_populate_stref_with_issuer_serial(env, asym_ctx, stref_node); } else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_EMBEDDED)) { status = oxs_xml_enc_populate_stref_with_embedded(env, asym_ctx, stref_node); } else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_DIRECT_REFERENCE)) { status = oxs_xml_enc_populate_stref_with_bst(env, asym_ctx, stref_node, parent); } else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_KEY_IDENTIFIER)) { status = oxs_xml_enc_populate_stref_with_key_identifier(env, asym_ctx, stref_node, AXIS2_FALSE); } else if(0 == axutil_strcmp(st_ref_pattern, OXS_STR_THUMB_PRINT)) { /*TODO: Need to support Thumbprint Ref*/ status = oxs_xml_enc_populate_stref_with_key_identifier(env, asym_ctx, stref_node, AXIS2_TRUE); } cd_node = oxs_token_build_cipher_data_element(env, encrypted_key_node); cv_node = oxs_token_build_cipher_value_element(env, cd_node, encrypted_key_data); /*If and only if the id_list the present, we create the reference list*/ if(id_list) { oxs_token_build_data_reference_list(env, encrypted_key_node, id_list); } /*calculate the EncryptedKeySHA1 and set as the key_sha*/ decoded_len = axutil_base64_decode_len(encrypted_key_data); decoded_enc_sec = AXIS2_MALLOC(env->allocator, decoded_len); axutil_base64_decode_binary((unsigned char*)decoded_enc_sec, encrypted_key_data); encrypted_key_hash = openssl_sha1(env, decoded_enc_sec, decoded_len); oxs_key_set_key_sha(sym_key, env, encrypted_key_hash); AXIS2_FREE(env->allocator, decoded_enc_sec); /*Free*/ oxs_buffer_free(result, env); result = NULL; return AXIS2_SUCCESS; }
AXIS2_EXTERN axis2_status_t AXIS2_CALL oxs_xml_enc_encrypt_data( const axutil_env_t *env, oxs_ctx_t * enc_ctx, oxs_buffer_t *content_buf, axiom_node_t **enc_type_node, axiom_node_t *security_token_reference_node) { oxs_buffer_t *result_buf = NULL; oxs_key_t *sym_key = NULL; axis2_char_t *sym_algo = NULL; axiom_node_t *enc_mtd_node = NULL; axiom_node_t *cd_node = NULL; axiom_node_t *cv_node = NULL; axis2_status_t ret = AXIS2_FAILURE; /*Determine the algorithm to be used*/ sym_algo = oxs_ctx_get_enc_mtd_algorithm(enc_ctx, env); /*Determine the key to be used*/ sym_key = oxs_ctx_get_key(enc_ctx, env); /*Set the operation to encrypt*/ oxs_ctx_set_operation(enc_ctx, env, OXS_CTX_OPERATION_ENCRYPT); /*Create an empty buffer for encrypted data*/ result_buf = oxs_buffer_create(env); /*Call encryption. Result should be base64 encoded*/ ret = oxs_encryption_symmetric_crypt(env, enc_ctx, content_buf, result_buf); /*Create EncryptionMethod*/ enc_mtd_node = oxs_token_build_encryption_method_element(env, *enc_type_node, sym_algo); /*If security_token_reference_node is given, then use it to build the key info*/ /*if we are using any trust/sct related token, then the key reference is given with the token *and we are suppose to use it */ if(security_token_reference_node) { axiom_node_t *key_info_node = NULL; key_info_node = oxs_token_build_key_info_element(env, *enc_type_node); axiom_node_add_child(key_info_node, env, security_token_reference_node); } /*If the enc_ctx has a key name, then build the KeyInfo element using key name*/ else if(oxs_ctx_get_ref_key_name(enc_ctx, env)) { axiom_node_t *key_info_node = NULL; axiom_node_t *str_node = NULL; axiom_node_t *ref_node = NULL; key_info_node = oxs_token_build_key_info_element(env, *enc_type_node); str_node = oxs_token_build_security_token_reference_element(env, key_info_node); ref_node = oxs_token_build_reference_element(env, str_node, oxs_ctx_get_ref_key_name( enc_ctx, env), NULL); } /*Create CipherData element and populate*/ cd_node = oxs_token_build_cipher_data_element(env, *enc_type_node); cv_node = oxs_token_build_cipher_value_element(env, cd_node, (axis2_char_t*)oxs_buffer_get_data(result_buf, env)); /*Free buffers*/ oxs_buffer_free(result_buf, env); result_buf = NULL; return AXIS2_SUCCESS; }