axis2_status_t verify(axutil_env_t *env, axis2_char_t *filename, openssl_pkey_t *prvkey , oxs_x509_cert_t *cert) { oxs_sign_ctx_t *sign_ctx = NULL; axiom_node_t *tmpl = NULL; axis2_status_t status = AXIS2_FAILURE; tmpl = load_sample_xml(env , tmpl, filename); printf("File : \n%s\n", axiom_node_to_string(tmpl, env)); sign_ctx = oxs_sign_ctx_create(env); if(sign_ctx){ axiom_node_t *sig_node = NULL; /*Set the operation*/ oxs_sign_ctx_set_operation(sign_ctx, env, OXS_SIGN_OPERATION_VERIFY); sig_node = oxs_axiom_get_first_child_node_by_name(env, tmpl, OXS_NODE_SIGNATURE, OXS_DSIG_NS, OXS_DS ); if(!sig_node){ printf("Verification : Cannot find ds:Signature node\n"); return AXIS2_FAILURE; } /**If the certificate is not given check key information*/ if(!cert){ axiom_node_t *ki_node = NULL; axiom_node_t *x509_node = NULL; ki_node = oxs_axiom_get_first_child_node_by_name(env, sig_node, OXS_NODE_KEY_INFO, OXS_DSIG_NS, OXS_DS); x509_node = oxs_axiom_get_first_child_node_by_name(env, ki_node, OXS_NODE_X509_DATA, OXS_DSIG_NS, OXS_DS); cert = oxs_x509_cert_create(env); printf("No certificate is given. Fetching certificate from the KeyInfo\n"); status = oxs_xml_key_process_X509Data(env, x509_node, cert); if(AXIS2_FAILURE == status){ printf("Error reading KeyInfo\n"); return AXIS2_FAILURE; } } /*Set certificate*/ if(cert){ oxs_sign_ctx_set_certificate(sign_ctx, env, cert); }else{ printf("Certificate is NULL\n"); return AXIS2_FAILURE; } /*Verify*/ status = oxs_xml_sig_verify(env, sign_ctx, sig_node, tmpl); if(AXIS2_SUCCESS != status){ printf("\nSignature Failed :-(\n"); }else{ printf("\nSignature Verified :-)\n"); } } return status; }
static axis2_status_t oxs_xml_enc_process_key_info( const axutil_env_t *env, oxs_asym_ctx_t *asym_ctx, axiom_node_t *key_info_node, axiom_node_t *parent_node) { axiom_node_t *st_ref_node = NULL; st_ref_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node, OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, OXS_WSSE); if(!st_ref_node) { return AXIS2_FAILURE; } /* WSS-Core specification suggests 1. Resolve any <wsse:Reference> elements (specified within <wsse:SecurityTokenReference>). 2. Resolve any <wsse:KeyIdentifier> elements (specified within <wsse:SecurityTokenReference>). 3. Resolve any <ds:KeyName> elements. NOT PERMITTED by WS-i 4. Resolve any other <ds:KeyInfo> elements. NOT PERMITTED by WS-i */ /* * TODO: This method should get the key from the key_node. Currently key is taken from * given private key file */ return AXIS2_SUCCESS; }
AXIS2_EXTERN axis2_char_t *AXIS2_CALL oxs_token_get_cipher_value_from_cipher_data( const axutil_env_t *env, axiom_node_t *cd_node) { axiom_node_t *cv_node = NULL; axis2_char_t *value = NULL; /* First check direct <CipherValue> */ 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) { value = oxs_token_get_cipher_value(env, cv_node); } else { /* If not then check for <CipherReference URI?> */ /* TODO */ } return value; }
axis2_status_t __euca_authenticate(const axutil_env_t *env,axis2_msg_ctx_t *out_msg_ctx, axis2_op_ctx_t *op_ctx) { //***** First get the message context before doing anything dumb w/ a NULL pointer *****/ axis2_msg_ctx_t *msg_ctx = NULL; //<--- incoming msg context, it is NULL, see? msg_ctx = axis2_op_ctx_get_msg_ctx(op_ctx, env, AXIS2_WSDL_MESSAGE_LABEL_IN); //***** Print everything from the security results, just for testing now *****// rampart_context_t *rampart_context = NULL; axutil_property_t *property = NULL; property = axis2_msg_ctx_get_property(msg_ctx, env, RAMPART_CONTEXT); if(property) { rampart_context = (rampart_context_t *)axutil_property_get_value(property, env); // AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," ======== PRINTING PROCESSED WSSEC TOKENS ======== "); rampart_print_security_processed_results_set(env,msg_ctx); } //***** Extract Security Node from header from enveloper from msg_ctx *****// axiom_soap_envelope_t *soap_envelope = NULL; axiom_soap_header_t *soap_header = NULL; axiom_node_t *sec_node = NULL; soap_envelope = axis2_msg_ctx_get_soap_envelope(msg_ctx, env); if(!soap_envelope) NO_U_FAIL("SOAP envelope cannot be found."); soap_header = axiom_soap_envelope_get_header(soap_envelope, env); if (!soap_header) NO_U_FAIL("SOAP header cannot be found."); sec_node = rampart_get_security_header(env, msg_ctx, soap_header); // <---- here it is! if(!sec_node)NO_U_FAIL("No node wsse:Security -- required: ws-security"); //***** Find the wsse:Reference to the BinarySecurityToken *****// //** Path is: Security/ //** *sec_node must be non-NULL, kkthx **// axiom_node_t *sig_node = NULL; axiom_node_t *key_info_node = NULL; axiom_node_t *sec_token_ref_node = NULL; /** the ds:Signature node **/ sig_node = oxs_axiom_get_first_child_node_by_name(env,sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, OXS_DS ); if(!sig_node)NO_U_FAIL("No node ds:Signature -- required: signature"); /** the ds:KeyInfo **/ key_info_node = oxs_axiom_get_first_child_node_by_name(env, sig_node, OXS_NODE_KEY_INFO, OXS_DSIG_NS, NULL ); if(!key_info_node)NO_U_FAIL("No node ds:KeyInfo -- required: signature key"); /** the wsse:SecurityTokenReference **/ sec_token_ref_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node,OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL); if(!sec_token_ref_node)NO_U_FAIL("No node wsse:SecurityTokenReference -- required: signing token"); //** in theory this is the branching point for supporting all kinds of tokens -- we only do BST Direct Reference **/ //***** Find the wsse:Reference to the BinarySecurityToken *****// //** *sec_token_ref_node must be non-NULL **/ axis2_char_t *ref = NULL; axis2_char_t *ref_id = NULL; axiom_node_t *token_ref_node = NULL; axiom_node_t *bst_node = NULL; /** the wsse:Reference node **/ token_ref_node = oxs_axiom_get_first_child_node_by_name(env, sec_token_ref_node,OXS_NODE_REFERENCE, OXS_WSSE_XMLNS, NULL); /** pull out the name of the BST node **/ ref = oxs_token_get_reference(env, token_ref_node); ref_id = axutil_string_substring_starting_at(axutil_strdup(env, ref), 1); /** get the wsse:BinarySecurityToken used to sign the message **/ bst_node = oxs_axiom_get_node_by_id(env, sec_node, "Id", ref_id, OXS_WSU_XMLNS); if(!bst_node){oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Error retrieving elementwith ID=%s", ref_id);NO_U_FAIL("Cant find the required node");} //***** Find the wsse:Reference to the BinarySecurityToken *****// //** *bst_node must be non-NULL **/ axis2_char_t *data = NULL; oxs_x509_cert_t *_cert = NULL; oxs_x509_cert_t *recv_cert = NULL; axis2_char_t *file_name = NULL; axis2_char_t *recv_x509_buf = NULL; axis2_char_t *msg_x509_buf = NULL; /** pull out the data from the BST **/ data = oxs_axiom_get_node_content(env, bst_node); /** create an oxs_X509_cert **/ _cert = oxs_key_mgr_load_x509_cert_from_string(env, data); if(_cert) { //***** FINALLY -- we have the certificate used to sign the message. authenticate it HERE *****// msg_x509_buf = oxs_x509_cert_get_data(_cert,env); if(!msg_x509_buf)NO_U_FAIL("OMG WHAT NOW?!"); /* recv_x509_buf = (axis2_char_t *)rampart_context_get_receiver_certificate(rampart_context, env); if(recv_x509_buf) recv_cert = oxs_key_mgr_load_x509_cert_from_string(env, recv_x509_buf); else { file_name = rampart_context_get_receiver_certificate_file(rampart_context, env); if(!file_name) NO_U_FAIL("Policy for the service is incorrect -- ReceiverCertificate is not set!!"); if (check_file(file_name)) NO_U_FAIL("No cert file ($EUCALYPTUS/var/lib/eucalyptus/keys/cloud-cert.pem) found, failing"); recv_cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name); } */ file_name = rampart_context_get_receiver_certificate_file(rampart_context, env); if(!file_name) NO_U_FAIL("Policy for the service is incorrect -- ReceiverCertificate is not set!!"); if (check_file(file_name)) NO_U_FAIL("No cert file ($EUCALYPTUS/var/lib/eucalyptus/keys/cloud-cert.pem) found, failing"); recv_cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name); if (recv_cert) { recv_x509_buf = oxs_x509_cert_get_data(recv_cert,env); } else { NO_U_FAIL("could not populate receiver cert"); } if( axutil_strcmp(recv_x509_buf,msg_x509_buf)!=0){ AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," --------- Received x509 certificate value ---------" ); AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI, msg_x509_buf ); AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," --------- Local x509 certificate value! ---------" ); AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI, recv_x509_buf ); AXIS2_LOG_CRITICAL(env->log,AXIS2_LOG_SI," ---------------------------------------------------" ); NO_U_FAIL("The certificate specified is invalid!"); } } else { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_DEFAULT, "Cannot load certificate from string =%s", data); NO_U_FAIL("Failed to build certificate from BinarySecurityToken"); } oxs_x509_cert_free(_cert, env); oxs_x509_cert_free(recv_cert, env); return AXIS2_SUCCESS; }
/** * Verifes that Body, Timestamp, To, Action, and MessageId elements are signed and located * where expected by the application logic. Timestamp is checked for expiration regardless * of its actual location. */ axis2_status_t verify_references(axiom_node_t *sig_node, const axutil_env_t *env, axis2_msg_ctx_t *msg_ctx, axiom_soap_envelope_t *envelope) { axiom_node_t *si_node = NULL; axiom_node_t *ref_node = NULL; axis2_status_t status = AXIS2_SUCCESS; si_node = oxs_axiom_get_first_child_node_by_name(env,sig_node, OXS_NODE_SIGNEDINFO, OXS_DSIG_NS, OXS_DS); if(!si_node) { axis2_char_t *tmp = axiom_node_to_string(sig_node, env); AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart]sig = %s", tmp); NO_U_FAIL("Couldn't find SignedInfo!"); } axutil_qname_t *qname = NULL; axiom_element_t *parent_elem = NULL; axiom_children_qname_iterator_t *qname_iter = NULL; parent_elem = axiom_node_get_data_element(si_node, env); if(!parent_elem) { NO_U_FAIL("Could not get Reference elem"); } axis2_char_t *ref = NULL; axis2_char_t *ref_id = NULL; axiom_node_t *signed_node = NULL; axiom_node_t *envelope_node = NULL; short signed_elems[5] = {0,0,0,0,0}; envelope_node = axiom_soap_envelope_get_base_node(envelope, env); qname = axutil_qname_create(env, OXS_NODE_REFERENCE, OXS_DSIG_NS, NULL); qname_iter = axiom_element_get_children_with_qname(parent_elem, env, qname, si_node); while (axiom_children_qname_iterator_has_next(qname_iter , env)) { ref_node = axiom_children_qname_iterator_next(qname_iter, env); axis2_char_t *txt = axiom_node_to_string(ref_node, env); /* get reference to a signed element */ ref = oxs_token_get_reference(env, ref_node); if(ref == NULL || strlen(ref) == 0 || ref[0] != '#') { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Unsupported reference ID in %s", txt); status = AXIS2_FAILURE; break; } AXIS2_LOG_DEBUG(env->log, AXIS2_LOG_SI, "[euca-rampart] %s, ref = %s", txt, ref); /* get rid of '#' */ ref_id = axutil_string_substring_starting_at(axutil_strdup(env, ref), 1); signed_node = oxs_axiom_get_node_by_id(env, envelope_node, OXS_ATTR_ID, ref_id, OXS_WSU_XMLNS); if(!signed_node) { oxs_error(env, OXS_ERROR_LOCATION, OXS_ERROR_ELEMENT_FAILED, "Error retrieving elementwith ID=%s", ref_id); status = AXIS2_FAILURE; break; } if(verify_node(signed_node, env, msg_ctx, ref, signed_elems)) { status = AXIS2_FAILURE; break; } } axutil_qname_free(qname, env); qname = NULL; if(status == AXIS2_FAILURE) { NO_U_FAIL("Failed to verify location of signed elements!"); } /* This is needed to make sure that all security-critical elements are signed */ for(int i = 0; i < 5; i++) { if(signed_elems[i] == 0) { NO_U_FAIL("Not all required elements are signed"); } } 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 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; }
/*Public functions*/ AXIS2_EXTERN axis2_status_t AXIS2_CALL rampart_shb_ensure_sec_header_order(const axutil_env_t *env, axis2_msg_ctx_t *msg_ctx, rampart_context_t *rampart_context, axiom_node_t* sec_node) { axis2_bool_t signature_protection = AXIS2_FALSE; axis2_bool_t is_encrypt_before_sign = AXIS2_FALSE; axiom_node_t *sig_node = NULL; axiom_node_t *enc_key_node = NULL; axiom_node_t *ref_list_node = NULL; axiom_node_t *h_node = NULL; axutil_array_list_t *dk_list = NULL; axutil_array_list_t *enc_key_list = NULL; axiom_node_t* first_protection_item = NULL; int i = 0; signature_protection = rampart_context_is_encrypt_signature(rampart_context, env); is_encrypt_before_sign = rampart_context_is_encrypt_before_sign(rampart_context, env); dk_list = axutil_array_list_create(env, 5); enc_key_list = axutil_array_list_create(env, 2); h_node = axiom_node_get_first_child(sec_node, env); while(h_node) { if(0 == axutil_strcmp(OXS_NODE_DERIVED_KEY_TOKEN, axiom_util_get_localname(h_node, env)) || (0 == axutil_strcmp(OXS_NODE_BINARY_SECURITY_TOKEN, axiom_util_get_localname(h_node, env)))) { axutil_array_list_add(dk_list, env, h_node); } else if((0 == axutil_strcmp(OXS_NODE_ENCRYPTED_KEY, axiom_util_get_localname(h_node, env))) || (0 == axutil_strcmp(OXS_NODE_SECURITY_CONTEXT_TOKEN, axiom_util_get_localname(h_node, env)))) { axutil_array_list_add(enc_key_list, env, h_node); } h_node = axiom_node_get_next_sibling(h_node, env); } ref_list_node = oxs_axiom_get_first_child_node_by_name(env, sec_node, OXS_NODE_REFERENCE_LIST, OXS_ENC_NS, NULL); sig_node = oxs_axiom_get_first_child_node_by_name(env, sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, NULL); /*Ensure the protection order in the header*/ if(sig_node && ref_list_node) { if(is_encrypt_before_sign) { int no_of_sig_node = 0; /*Encrypt->Sig <Sig><RefList>*/ oxs_axiom_interchange_nodes(env, sig_node, ref_list_node ); first_protection_item = sig_node; no_of_sig_node = oxs_axiom_get_number_of_children_with_qname(env, sec_node, OXS_NODE_SIGNATURE, OXS_DSIG_NS, NULL); if(no_of_sig_node > 1) { axiom_node_t* cur_node = NULL; cur_node = axiom_node_get_first_child(sec_node, env); while(cur_node) { axis2_char_t *cur_local_name = NULL; cur_local_name = axiom_util_get_localname(cur_node, env); if(0 == axutil_strcmp(cur_local_name, OXS_NODE_SIGNATURE)) { oxs_axiom_interchange_nodes(env, cur_node, ref_list_node); } cur_node = axiom_node_get_next_sibling(cur_node, env); } } } else { /*Sig->Encrypt <RefList> <Sig>*/ oxs_axiom_interchange_nodes(env, ref_list_node, sig_node ); first_protection_item = ref_list_node; } } else if(sig_node) { first_protection_item = sig_node; } else { first_protection_item = ref_list_node; } /*makesure enc_key_node is appearing before first protection item*/ if(first_protection_item) { for(i = 0; i < axutil_array_list_size(enc_key_list, env); i++) { axiom_node_t *tmp_node = NULL; tmp_node = (axiom_node_t*)axutil_array_list_get(enc_key_list, env, i); enc_key_node = axiom_node_detach_without_namespaces(tmp_node, env); axiom_node_insert_sibling_before(first_protection_item, env, enc_key_node); } } /* * If there are derived keys, make sure they come after the EncryptedKey/security context token 1. First we get all the derived keys 2. Then we attach after the EncryptedKey(hidden sessionkey)/security context token 3. If key is not available, then attach derived keys before sig_node and ref_list_node (whichever is first) */ if(enc_key_node) { for(i = 0; i < axutil_array_list_size(dk_list, env); i++) { axiom_node_t *dk_node = NULL; axiom_node_t *tmp_node = NULL; dk_node = (axiom_node_t*)axutil_array_list_get(dk_list, env, i); tmp_node = axiom_node_detach(dk_node, env); axiom_node_insert_sibling_after(enc_key_node, env, tmp_node); } } else { if(first_protection_item) { for(i = 0; i < axutil_array_list_size(dk_list, env); i++) { axiom_node_t *dk_node = NULL; axiom_node_t *tmp_node = NULL; dk_node = (axiom_node_t*)axutil_array_list_get(dk_list, env, i); tmp_node = axiom_node_detach(dk_node, env); axiom_node_insert_sibling_before(first_protection_item, env, tmp_node); } } } axutil_array_list_free(dk_list, env); axutil_array_list_free(enc_key_list, env); return AXIS2_SUCCESS; }
/** * Extract certificate/session_key related information using given key_info node and scope node * This will extract either certificate(asymmetric signing) or session_key (symmetric signing) * @param env Environment structure * @param key_info_node key info node. * @param rampart_context rampart context where key details could be found. * @param msg_ctx message context * @param is_signature boolean denoting whether the key_info is for signature * @param cert where the certificate extracted (if any) should be populated * @param key where the session key extracted (if any) should be populated * @return status of the operation */ AXIS2_EXTERN axis2_status_t AXIS2_CALL rampart_token_process_key_info( const axutil_env_t *env, axiom_node_t *key_info_node, axiom_node_t *sec_node, rampart_context_t* rampart_context, axis2_msg_ctx_t *msg_ctx, axis2_bool_t is_signature, oxs_x509_cert_t **cert, oxs_key_t **key, axis2_char_t **token_type, axis2_char_t **reference_method) { axiom_node_t *str_node = NULL; axis2_status_t status = AXIS2_FAILURE; /* Get the SecurityTokenReference, which is the common case, but not the only case */ str_node = oxs_axiom_get_first_child_node_by_name(env, key_info_node, OXS_NODE_SECURITY_TOKEN_REFRENCE, OXS_WSSE_XMLNS, NULL); if(str_node) { axiom_node_t *str_child_node = NULL; /* A <wsse:SecurityTokenReference> element MAY reference an X.509 token type * by one of the following means: * - Reference to a Subject Key Identifier (<wsse:KeyIdentifier>) * - Reference to a Binary Security Token (<wsse:Reference> element that * references a local <wsse:BinarySecurityToken> element or a remote data * source that contains the token data itself) * - Reference to an Issuer and Serial Number (<ds:X509Data> element that * contains a <ds:X509IssuerSerial> element that uniquely identifies an * end entity certificate) */ str_child_node = axiom_node_get_first_element(str_node, env); if(!str_child_node) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "No Child node in the Security Token Reference Element."); return AXIS2_FAILURE; } *reference_method = axiom_util_get_localname(str_child_node, env); if(!*reference_method) { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get the key Reference Type from the message."); return AXIS2_FAILURE; } if(0 == axutil_strcmp(*reference_method, OXS_NODE_REFERENCE)) { status = rampart_token_process_direct_ref(env, str_child_node, sec_node, msg_ctx, rampart_context, cert, key, token_type); } else if(0 == axutil_strcmp(*reference_method, OXS_NODE_EMBEDDED)) { /* embedded tokens are only possible with x509 token */ status = rampart_token_process_embedded(env, str_child_node, cert); } else if(0 == axutil_strcmp(*reference_method, OXS_NODE_KEY_IDENTIFIER)) { status = rampart_token_process_key_identifier(env, str_child_node, sec_node, str_node, rampart_context, is_signature, cert, key, token_type); } else if(0 == axutil_strcmp(*reference_method, OXS_NODE_X509_DATA)) { /* <ds:X509Data> contains a <ds:X509IssuerSerial> element which is used to specify a * reference to an X.509 security token by means of the certificate issuer name and * serial number. */ *cert = rampart_token_process_issuer_serial(env, rampart_context, str_child_node); status = AXIS2_SUCCESS; } else { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Key Reference %s not supported ", *reference_method); return AXIS2_FAILURE; } } else { /* There may be scenarios where there is no Security Token Reference Element. */ /*In such case policy support only Isssuer Serial scenario.*/ /*if(axutil_strcmp(eki, RAMPART_STR_ISSUER_SERIAL) == 0) { key_info_child_node = axiom_node_get_first_element(key_info_node, env); if(key_info_child_node) { axis2_char_t *key_info_child_name = NULL; key_info_child_name = axiom_util_get_localname(key_info_child_node, env); if(key_info_child_name) { if(0 == axutil_strcmp(key_info_child_name, OXS_NODE_X509_DATA)) { status = rampart_token_process_x509_data(env, key_info_child_node, cert); if(status != AXIS2_SUCCESS || !cert) { rampart_create_fault_envelope(env, RAMPART_FAULT_INVALID_SECURITY_TOKEN, "Cannot load the key to verify the message .", RAMPART_FAULT_IN_SIGNATURE, msg_ctx); AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[Rampart][shp] Cannot load the key to verify the message"); return AXIS2_FAILURE; } } else { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[Rampart][shp]Cannot get the key Reference Type from the message."); return AXIS2_FAILURE; } } else { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[Rampart][shp]Cannot get the key Reference Type from the message."); return AXIS2_FAILURE; } } else { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[Rampart][shp]Cannot get the key Reference Type from the message."); return AXIS2_FAILURE; } } else { AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "[Rampart][shp]Can't be used as a direct child of Key Info"); return AXIS2_FAILURE; }*/ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to key from key_info node"); return AXIS2_FAILURE; } if((status != AXIS2_SUCCESS) || ((!*cert) && (!*key))) { /* either status is AXIS2_FAILURE or both cert and key are NULL. This means error */ AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get key/certificate from key info node"); return AXIS2_FAILURE; } 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; }