/**
 * extract certificate/key using key identifier
 */
static axis2_status_t
rampart_token_process_key_identifier(
    const axutil_env_t *env,
    axiom_node_t *key_identifier_node,
    axiom_node_t *scope_node,
    axiom_node_t *str_node,
    rampart_context_t *rampart_context,
    axis2_bool_t is_signature,
    oxs_x509_cert_t **cert,
    oxs_key_t **key,
    axis2_char_t **token_type)
{
    axis2_char_t *value_type = NULL;
    value_type = oxs_axiom_get_attribute_value_of_node_by_name(env, key_identifier_node,
        OXS_ATTR_VALUE_TYPE, NULL);

    if(axutil_strcmp(value_type, OXS_X509_SUBJ_KI) == 0)/* X509 Token */
    {
        /* In the client side, it is preferred to use certificate files instead of key store,
         * because one client normally interact with only one service. To handle this scenario,
         * if we found receiver certificate file specified in rampart_context we directly call the
         * get_reciever_certificate.
         */
        *cert = rampart_context_get_receiver_certificate(rampart_context, env);
        if(!*cert)
        {
            axis2_char_t *ski = NULL;
            oxs_key_mgr_t *key_mgr = NULL;
            key_mgr = rampart_context_get_key_mgr(rampart_context, env);
            ski = oxs_axiom_get_node_content(env, key_identifier_node);
            *cert = oxs_key_mgr_get_receiver_certificate_from_ski(key_mgr, env, ski);
            if(!*cert)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                    "Cannot retrieve certificate using key identifier");
                return AXIS2_FAILURE;
            }
        }
    }
    else if(axutil_strcmp(value_type, OXS_X509_ENCRYPTED_KEY_SHA1) == 0) /* EncryptedKey */
    {
        axis2_char_t *hash_value = NULL;
        hash_value = oxs_axiom_get_node_content(env, key_identifier_node);
        if(!hash_value)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to get value of EncryptedKeySHA1");
            return AXIS2_FAILURE;
        }

        *key = rampart_context_get_key_using_hash(rampart_context, env, hash_value);
        if(!*key)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Cannot get key corresponding to EncryptedKeySHA1");
            return AXIS2_FAILURE;
        }
    }
    else if(axutil_strcmp(value_type, OXS_ST_KEY_ID_VALUE_TYPE) == 0) /* SAML token reference */
    {
        axiom_node_t *assertion = NULL;
        rampart_saml_token_t *saml = NULL;
        rampart_st_type_t tok_type;
        oxs_key_mgr_t *key_mgr = NULL;
        openssl_pkey_t *pvt_key = NULL;

        key_mgr = rampart_context_get_key_mgr(rampart_context, env);
        pvt_key = oxs_key_mgr_get_prv_key(key_mgr, env);
        if(!pvt_key)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot load private key");
            return AXIS2_FAILURE;
        }

        assertion = oxs_saml_token_get_from_key_identifer_reference(env, key_identifier_node, NULL);
        if(!assertion)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get key SAML Assertion");
            return AXIS2_FAILURE;
        }
        if(is_signature)
        {
            tok_type = RAMPART_ST_TYPE_SIGNATURE_TOKEN;
        }
        else
        {
            tok_type = RAMPART_ST_TYPE_ENCRYPTION_TOKEN;
        }
        saml = rampart_saml_add_token(rampart_context, env, assertion, str_node, tok_type);
        *key = rampart_saml_token_get_session_key(saml, env);
        if(!*key)
        {
            *key = saml_assertion_get_session_key(env, assertion, pvt_key);
            rampart_saml_token_set_session_key(saml, env, *key);
            oxs_key_set_name(*key, env, "for-algo");
        }

        if(!*key)
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Cannot get key corresponding to SAML Token");
            return AXIS2_FAILURE;
        }
    }
    else
    {
        AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Failed to identify Key Identifier %s", value_type);
        return AXIS2_FAILURE;
    }

    return AXIS2_SUCCESS;
}
/* Get the client certificate from key manager by giving
 * issuer and serial number of the certificate
 */
static oxs_x509_cert_t *
rampart_token_process_issuer_serial(
    const axutil_env_t *env,
    rampart_context_t *rampart_ctx,
    axiom_node_t *x509_data_node)
{
    oxs_x509_cert_t *cert = NULL;
    axiom_node_t *issuer_serial_node = NULL;
    axiom_element_t *issuer_serial_ele = NULL;
    axiom_child_element_iterator_t *child_itr = NULL;
    axiom_node_t *child_node = NULL;
    axiom_element_t *child_ele = NULL;
    axis2_char_t *ele_name = NULL;
    axis2_char_t *issuer_name_str = NULL;
    axis2_char_t *serial_num_str = NULL;
    int serial_num = -1;
    oxs_key_mgr_t *key_mgr = NULL;

    if((cert = rampart_context_get_receiver_certificate(rampart_ctx, env)))
    {
        /* In the client side, it is preferred to use certificate files instead
         * of key store, because one client normally interact with only one
         * service. To handle this scenario, if we found receiver certificate file
         * specified in rampart_context we directly call the get_reciever_certificate.
         */
        return cert;
    }

    issuer_serial_node = axiom_node_get_first_child(x509_data_node, env);
    issuer_serial_ele = axiom_node_get_data_element(issuer_serial_node, env);

    child_itr = axiom_element_get_child_elements(issuer_serial_ele, env, issuer_serial_node);
    while(axiom_child_element_iterator_has_next(child_itr, env))
    {
        child_node = axiom_child_element_iterator_next(child_itr, env);
        child_ele = axiom_node_get_data_element(child_node, env);
        ele_name = axiom_element_get_localname(child_ele, env);
        if(axutil_strcmp(ele_name, OXS_NODE_X509_ISSUER_NAME) == 0)
        {
            issuer_name_str = axiom_element_get_text(child_ele, env, child_node);
            if(!issuer_name_str)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Issuer Name cannot be NULL.");
                return NULL;
            }
            AXIS2_LOG_INFO(env->log, AXIS2_LOG_SI, "X509 Certificate Issuer Name Found: %s",
                issuer_name_str);
        }
        else if(axutil_strcmp(ele_name, OXS_NODE_X509_SERIAL_NUMBER) == 0)
        {
            serial_num_str = axiom_element_get_text(child_ele, env, child_node);
            if(!serial_num_str)
            {
                AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI, "Serial number cannot be null.");
            }
            AXIS2_LOG_INFO(env->log, AXIS2_LOG_SI, "X509 Certificate Serial Number Found: %s",
                serial_num_str);
        }
        else
        {
            AXIS2_LOG_ERROR(env->log, AXIS2_LOG_SI,
                "Error in incoming key info. These types not supported: %", ele_name);
            return NULL;
        }
    }

    serial_num = atoi(serial_num_str);
    key_mgr = rampart_context_get_key_mgr(rampart_ctx, env);

    cert = oxs_key_mgr_get_receiver_certificate_from_issuer_serial(key_mgr, env, issuer_name_str,
        serial_num);

    return cert;
}
Exemple #3
0
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!!");
        recv_cert = oxs_key_mgr_load_x509_cert_from_pem_file(env, file_name);
    }
    recv_x509_buf = oxs_x509_cert_get_data(recv_cert,env);

    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;

}