AXIS2_EXTERN axis2_status_t AXIS2_CALL oxs_xml_enc_decrypt_data( const axutil_env_t *env, oxs_ctx_t * enc_ctx, axiom_node_t *enc_type_node, oxs_buffer_t *result_buf) { axiom_node_t *enc_mtd_node = NULL; axiom_node_t *cd_node = NULL; axiom_node_t *cv_node = NULL; axis2_char_t *cipher_val = NULL; axis2_char_t *new_cipher_val = NULL; axis2_char_t *sym_algo = NULL; axis2_char_t *type = NULL; axis2_char_t *id = NULL; oxs_buffer_t *input_buf = NULL; axis2_status_t status = AXIS2_FAILURE; /* Get the symmetric encryption algorithm */ enc_mtd_node = oxs_axiom_get_first_child_node_by_name(env, enc_type_node, OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, OXS_XENC); if(!enc_mtd_node) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find encryption method node"); return AXIS2_FAILURE; } sym_algo = oxs_token_get_encryption_method(env, enc_mtd_node); if(!sym_algo) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find encryption method"); return AXIS2_FAILURE; } /* Get ID, Type, MimeType attributes from the EncryptedDataNode */ id = oxs_axiom_get_attribute_value_of_node_by_name(env, enc_type_node, OXS_ATTR_ID, NULL); type = oxs_axiom_get_attribute_value_of_node_by_name(env, enc_type_node, OXS_ATTR_TYPE, NULL); /* Populate the context for future use */ oxs_ctx_set_enc_mtd_algorithm(enc_ctx, env, sym_algo); oxs_ctx_set_id(enc_ctx, env, id); oxs_ctx_set_type(enc_ctx, env, type); /* Get the cipher value */ cd_node = oxs_axiom_get_first_child_node_by_name(env, enc_type_node, OXS_NODE_CIPHER_DATA, OXS_ENC_NS, OXS_XENC); if(!cd_node) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher data node"); return AXIS2_FAILURE; } cv_node = oxs_axiom_get_first_child_node_by_name(env, cd_node, OXS_NODE_CIPHER_VALUE, OXS_ENC_NS, OXS_XENC); if(!cv_node) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher value node"); return AXIS2_FAILURE; } cipher_val = oxs_token_get_cipher_value(env, cv_node); if(!cipher_val) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[rampart]Cannot find cipher value"); return AXIS2_FAILURE; } /* We need to remove new lines if any */ new_cipher_val = oxs_util_get_newline_removed_string(env, cipher_val); /* Create input buffer with cipher data obtained */ input_buf = oxs_buffer_create(env); oxs_buffer_populate(input_buf, env, (unsigned char*)new_cipher_val, axutil_strlen(new_cipher_val)); /* Decrypt */ oxs_ctx_set_operation(enc_ctx, env, OXS_CTX_OPERATION_DECRYPT); status = oxs_encryption_symmetric_crypt(env, enc_ctx, input_buf, result_buf); /*Free*/ oxs_buffer_free(input_buf, env); input_buf = NULL; AXIS2_FREE(env->allocator, new_cipher_val); new_cipher_val = NULL; return status; }
/** * Inspect the key node. Then populate the sym_key */ AXIS2_EXTERN axis2_status_t AXIS2_CALL oxs_xml_enc_decrypt_key( const axutil_env_t *env, oxs_asym_ctx_t * asym_ctx, axiom_node_t *parent, axiom_node_t *encrypted_key_node, oxs_key_t *key) { axiom_node_t *enc_mtd_node = NULL; axiom_node_t *key_info_node = NULL; axiom_node_t *cd_node = NULL; axis2_char_t *enc_mtd_algo = NULL; axis2_char_t *cipher_val = NULL; axis2_char_t *new_cipher_val = NULL; axis2_status_t status = AXIS2_FAILURE; oxs_buffer_t *input_buf = NULL; oxs_buffer_t *result_buf = NULL; axis2_char_t *key_name = NULL; axis2_char_t* encrypted_key_hash = NULL; int decoded_len = 0; axis2_char_t *decoded_enc_sec = NULL; /*Get encryption method algorithm*/ enc_mtd_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node, OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, OXS_XENC); enc_mtd_algo = oxs_token_get_encryption_method(env, enc_mtd_node); if(!enc_mtd_algo) { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED, "Cannot find the Encryption method"); return AXIS2_FAILURE; } /*Get cipher data*/ cd_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node, OXS_NODE_CIPHER_DATA, OXS_ENC_NS, OXS_XENC); cipher_val = oxs_token_get_cipher_value_from_cipher_data(env, cd_node); if(!cipher_val) { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ENCRYPT_FAILED, "Cannot find the cipher value for key decryption"); return AXIS2_FAILURE; } new_cipher_val = oxs_util_get_newline_removed_string(env, cipher_val); /*Get key used to encrypt*/ key_info_node = oxs_axiom_get_first_child_node_by_name(env, encrypted_key_node, OXS_NODE_KEY_INFO, OXS_DSIG_NS, OXS_DS); status = oxs_xml_enc_process_key_info(env, asym_ctx, key_info_node, parent); /*Right now we support KeyInfo -> SecurityTokenReference -> Reference KeyInfo -> SecurityTokenReference -> X509IssuerSerial */ /*Get the pkey used to decrypt the session key. If found set it to the asym_ctx*/ /*Create the input buffer*/ input_buf = oxs_buffer_create(env); oxs_buffer_populate(input_buf, env, (unsigned char*)new_cipher_val, axutil_strlen( new_cipher_val)); /*Create a results buffer*/ result_buf = oxs_buffer_create(env); /*Call decryption*/ status = oxs_encryption_asymmetric_crypt(env, asym_ctx, input_buf, result_buf); /*Free input*/ oxs_buffer_free(input_buf, env); input_buf = NULL; /*calculate the EncryptedKeySHA1 and set as the key_sha*/ decoded_len = axutil_base64_decode_len(new_cipher_val); decoded_enc_sec = AXIS2_MALLOC(env->allocator, decoded_len); axutil_base64_decode_binary((unsigned char*)decoded_enc_sec, new_cipher_val); encrypted_key_hash = openssl_sha1(env, decoded_enc_sec, decoded_len); AXIS2_FREE(env->allocator, decoded_enc_sec); AXIS2_FREE(env->allocator, new_cipher_val); new_cipher_val = NULL; if(AXIS2_FAILURE == status) { return AXIS2_FAILURE; } key_name = oxs_axiom_get_attribute_value_of_node_by_name(env, encrypted_key_node, OXS_ATTR_ID, NULL); /*Populate the key with the data in the result buffer*/ oxs_key_populate(key, env, oxs_buffer_get_data(result_buf, env), key_name, oxs_buffer_get_size( result_buf, env), OXS_KEY_USAGE_SESSION); oxs_key_set_key_sha(key, env, encrypted_key_hash); /*Free*/ oxs_buffer_free(result_buf, env); result_buf = NULL; return AXIS2_SUCCESS; }
AXIS2_EXTERN oxs_key_t * AXIS2_CALL saml_assertion_get_session_key(const axutil_env_t *env, axiom_node_t *assertion, openssl_pkey_t *pvt_key) { axiom_node_t *encrypted_key_node = NULL; axiom_node_t *enc_mtd_node = NULL; axis2_char_t *enc_asym_algo = NULL; oxs_asym_ctx_t *asym_ctx = NULL; oxs_key_t *decrypted_sym_key = NULL; axis2_status_t status = AXIS2_FAILURE; if (!pvt_key) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[oxs][saml] Private key not specified"); return NULL; } encrypted_key_node = oxs_axiom_get_node_by_local_name(env, assertion, OXS_NODE_ENCRYPTED_KEY); if (!encrypted_key_node) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[oxs][saml] Encrypted key cannot be found"); return NULL; } enc_mtd_node = oxs_axiom_get_first_child_node_by_name( env, encrypted_key_node, OXS_NODE_ENCRYPTION_METHOD, OXS_ENC_NS, NULL); if (!enc_mtd_node) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[oxs][saml] EncryptedKey node cannot be found"); return NULL; } enc_asym_algo = oxs_token_get_encryption_method(env, enc_mtd_node); if (!enc_asym_algo) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[oxs][saml] Encryption Algorithm cannot be found"); return NULL; } asym_ctx = oxs_asym_ctx_create(env); oxs_asym_ctx_set_algorithm(asym_ctx, env, enc_asym_algo); oxs_asym_ctx_set_private_key(asym_ctx, env, pvt_key); oxs_asym_ctx_set_operation(asym_ctx, env, OXS_ASYM_CTX_OPERATION_PRV_DECRYPT); decrypted_sym_key = oxs_key_create(env); /*Call decrypt for the EncryptedKey*/ status = oxs_xml_enc_decrypt_key(env, asym_ctx, NULL, encrypted_key_node, decrypted_sym_key); if (status == AXIS2_FAILURE) { oxs_key_free(decrypted_sym_key, env); AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[oxs][saml] Decryption failed in SAML encrypted key"); return NULL; } return decrypted_sym_key; }