LCOV - code coverage report
Current view: top level - zxid - zxidmk.c (source / functions) Hit Total Coverage
Test: ZXID Code Coverage Lines: 248 280 88.6 %
Date: 2010-12-19 Functions: 21 21 100.0 %
Branches: 91 157 58.0 %

           Branch data     Line data    Source code
       1                 :            : /* zxidmk.c  -  Handwritten nitty-gritty functions for constructing various elems
       2                 :            :  * Copyright (c) 2006-2009 Symlabs (symlabs@symlabs.com), All Rights Reserved.
       3                 :            :  * Author: Sampo Kellomaki (sampo@iki.fi)
       4                 :            :  * This is confidential unpublished proprietary source code of the author.
       5                 :            :  * NO WARRANTY, not even implied warranties. Contains trade secrets.
       6                 :            :  * Distribution prohibited unless authorized in writing.
       7                 :            :  * Licensed under Apache License 2.0, see file COPYING.
       8                 :            :  * $Id: zxidmk.c,v 1.27 2009-11-24 23:53:40 sampo Exp $
       9                 :            :  *
      10                 :            :  * 12.8.2006, created --Sampo
      11                 :            :  * 8.10.2007, added signing ArtifactResolve --Sampo
      12                 :            :  * 7.10.2008, added documentation --Sampo
      13                 :            :  * 24.8.2009, added XACML stuff --Sampo
      14                 :            :  */
      15                 :            : 
      16                 :            : #include "errmac.h"
      17                 :            : #include "zxid.h"
      18                 :            : #include "zxidpriv.h"
      19                 :            : #include "zxidutil.h"
      20                 :            : #include "zxidconf.h"
      21                 :            : #include "saml2.h"
      22                 :            : #include "c/zx-const.h"
      23                 :            : #include "c/zx-ns.h"
      24                 :            : #include "c/zx-data.h"
      25                 :            : 
      26                 :            : /*() Interpret ZXID standard form fields to construct a XML structure for AuthnRequest */
      27                 :            : 
      28                 :            : /* Called by:  a7n_test, x509_test, zxid_lecp_check, zxid_start_sso_url */
      29                 :            : struct zx_sp_AuthnRequest_s* zxid_mk_authn_req(zxid_conf* cf, zxid_cgi* cgi)
      30                 :          7 : {
      31                 :          7 :   char index[2] = "1";
      32                 :          7 :   struct zx_sp_AuthnRequest_s* ar = zx_NEW_sp_AuthnRequest(cf->ctx,0);
      33                 :          7 :   ar->Issuer = zxid_my_issuer(cf, &ar->gg);
      34                 :          7 :   ar->ID = zxid_mk_id_attr(cf, &ar->gg, zx_ID_ATTR, "N", ZXID_ID_BITS);
      35                 :          7 :   ar->Version = zx_ref_attr(cf->ctx, &ar->gg, zx_Version_ATTR, SAML2_VERSION);
      36                 :          7 :   ar->IssueInstant = zxid_date_time_attr(cf, &ar->gg, zx_IssueInstant_ATTR, time(0));
      37                 :            : 
      38   [ +  -  +  - ]:          7 :   if (cf->nice_name && cf->nice_name[0])
      39                 :          7 :     ar->ProviderName = zx_ref_attr(cf->ctx, &ar->gg, zx_ProviderName_ATTR, cf->nice_name);
      40                 :            : 
      41   [ +  +  -  + ]:          7 :   if (BOOL_STR_TEST(cgi->force_authn))
      42                 :          0 :     ar->ForceAuthn = zx_ref_attr(cf->ctx, &ar->gg, zx_ForceAuthn_ATTR, XML_TRUE);
      43                 :            : 
      44   [ +  +  -  + ]:          7 :   if (BOOL_STR_TEST(cgi->ispassive))
      45                 :          0 :     ar->IsPassive = zx_ref_attr(cf->ctx, &ar->gg, zx_IsPassive_ATTR, XML_TRUE);
      46                 :            : 
      47   [ +  +  -  + ]:          7 :   if (cgi->consent && cgi->consent[0])
      48                 :          0 :     ar->Consent = zx_ref_attr(cf->ctx, &ar->gg, zx_Consent_ATTR, cgi->consent);
      49                 :            : 
      50   [ +  +  -  + ]:          7 :   D("nid_fmt(%s) allow_create=%c ispassive=%c", cgi->nid_fmt, cgi->allow_create, cgi->ispassive);
      51   [ +  +  -  +  :          7 :   if (cgi->nid_fmt && cgi->nid_fmt[0] || cgi->affil && cgi->affil[0]
          -  +  #  #  -  
                +  #  # ]
      52                 :            :       || BOOL_STR_TEST(cgi->allow_create)) {
      53                 :          5 :     ar->NameIDPolicy = zx_NEW_sp_NameIDPolicy(cf->ctx, &ar->gg);
      54                 :            : 
      55   [ +  -  +  - ]:          5 :     if (cgi->nid_fmt && cgi->nid_fmt[0])
      56                 :          5 :       ar->NameIDPolicy->Format = zx_ref_attr(cf->ctx, &ar->NameIDPolicy->gg, zx_Format_ATTR, zxid_saml2_map_nid_fmt(cgi->nid_fmt));
      57                 :            : 
      58   [ +  -  -  + ]:          5 :     if (cgi->affil && cgi->affil[0])
      59                 :          0 :       ar->NameIDPolicy->SPNameQualifier = zx_ref_attr(cf->ctx, &ar->NameIDPolicy->gg, zx_SPNameQualifier_ATTR, cgi->affil);
      60                 :            : 
      61   [ +  -  +  - ]:          5 :     if (BOOL_STR_TEST(cgi->allow_create))
      62                 :          5 :       ar->NameIDPolicy->AllowCreate = zx_ref_attr(cf->ctx, &ar->NameIDPolicy->gg, zx_AllowCreate_ATTR, XML_TRUE);  /* default false */
      63                 :            :   }
      64                 :            : 
      65   [ +  +  -  + ]:          7 :   if (cgi->authn_ctx && cgi->authn_ctx[0]) {
      66                 :          0 :     ar->RequestedAuthnContext = zx_NEW_sp_RequestedAuthnContext(cf->ctx, &ar->gg);
      67                 :          0 :     ar->RequestedAuthnContext->AuthnContextClassRef
      68                 :            :       = zx_ref_elem(cf->ctx, &ar->RequestedAuthnContext->gg, zx_sa_AuthnContextClassRef_ELEM, zxid_saml2_map_authn_ctx(cgi->authn_ctx));
      69   [ #  #  #  # ]:          0 :     if (cgi->matching_rule && cgi->matching_rule[0])
      70                 :          0 :       ar->RequestedAuthnContext->Comparison = zx_ref_attr(cf->ctx, &ar->RequestedAuthnContext->gg, zx_Comparison_ATTR, cgi->matching_rule);
      71                 :            :   }
      72   [ +  +  -  + ]:          7 :   if (cgi->pr_ix && cgi->pr_ix != '0') {
      73                 :          0 :     index[0] = cgi->pr_ix;
      74                 :          0 :     ar->AssertionConsumerServiceIndex = zx_dup_attr(cf->ctx, &ar->gg, zx_AssertionConsumerServiceIndex_ATTR, index);
      75                 :            :   }
      76   [ -  +  #  #  :          7 :   if (cgi->get_complete && cgi->get_complete[0]
          -  +  #  #  -  
                +  #  # ]
      77                 :            :       || cgi->pxy_count && cgi->pxy_count[0]
      78                 :            :       || cgi->idppxylist && cgi->idppxylist[0]) {
      79                 :          0 :     ar->Scoping = zx_NEW_sp_Scoping(cf->ctx, &ar->gg);
      80   [ #  #  #  # ]:          0 :     if (cgi->pxy_count && cgi->pxy_count[0])
      81                 :          0 :       ar->Scoping->ProxyCount = zx_ref_attr(cf->ctx, &ar->gg, zx_ProxyCount_ATTR, cgi->pxy_count);
      82                 :            : #if 0
      83                 :            :     if (cgi->get_complete && cgi->get_complete[0] || cgi->idppxylist) {
      84                 :            :       ar->Scoping->IDPList = zx_NEW_sp_IDPList(cf->ctx, &ar->Scoping->gg);
      85                 :            :       /* *** Add IDPEntry and GetComplete */
      86                 :            :     }
      87                 :            : #endif
      88                 :            :   }
      89                 :          7 :   return ar;
      90                 :            : }
      91                 :            : 
      92                 :            : /*() Make the body for the ArtifactResolve SOAP message, signing it if needed. */
      93                 :            : 
      94                 :            : /* Called by:  zxid_sp_deref_art */
      95                 :            : struct zx_sp_ArtifactResolve_s* zxid_mk_art_deref(zxid_conf* cf, zxid_entity* idp_meta, const char* artifact)
      96                 :          1 : {
      97                 :            :   X509* sign_cert;
      98                 :            :   EVP_PKEY* sign_pkey;
      99                 :            :   struct zxsig_ref refs;
     100                 :          1 :   struct zx_sp_ArtifactResolve_s* ar = zx_NEW_sp_ArtifactResolve(cf->ctx,0);
     101                 :          1 :   ar->Issuer = zxid_my_issuer(cf, &ar->gg);
     102                 :          1 :   ar->ID = zxid_mk_id_attr(cf, &ar->gg, zx_ID_ATTR, "R", ZXID_ID_BITS);
     103                 :          1 :   ar->Version = zx_ref_attr(cf->ctx, &ar->gg, zx_Version_ATTR, SAML2_VERSION);
     104                 :          1 :   ar->IssueInstant = zxid_date_time_attr(cf, &ar->gg, zx_IssueInstant_ATTR, time(0));
     105                 :          1 :   ar->Artifact = zx_ref_elem(cf->ctx, &ar->gg, zx_sp_Artifact_ELEM, artifact);
     106         [ +  - ]:          1 :   if (cf->sso_soap_sign) {
     107                 :          1 :     ZERO(&refs, sizeof(refs));
     108                 :          1 :     refs.id = &ar->ID->g;
     109                 :          1 :     refs.canon = zx_easy_enc_elem_sig(cf, &ar->gg);
     110         [ +  - ]:          1 :     if (zxid_lazy_load_sign_cert_and_pkey(cf, &sign_cert, &sign_pkey, "use sign cert art deref")) {
     111                 :          1 :       ar->Signature = zxsig_sign(cf->ctx, 1, &refs, sign_cert, sign_pkey);
     112                 :          1 :       zx_add_kid_after_sa_Issuer(&ar->gg, &ar->Signature->gg);
     113                 :            :     }
     114                 :          1 :     zx_str_free(cf->ctx, refs.canon);
     115                 :            :   }
     116                 :          1 :   return ar;
     117                 :            : }
     118                 :            : 
     119                 :            : /*() Create SAML protocol <Status> element, given various levels of error input. */
     120                 :            : 
     121                 :            : /* Called by:  so_enc_dec, zxid_OK, zxid_nidmap_do x2, zxid_ssos_anreq x4 */
     122                 :            : struct zx_sp_Status_s* zxid_mk_Status(zxid_conf* cf, struct zx_elem_s* father, const char* sc1, const char* sc2, const char* msg)
     123                 :        111 : {
     124                 :        111 :   struct zx_sp_Status_s* st = zx_NEW_sp_Status(cf->ctx, father);
     125         [ +  + ]:        111 :   if (msg)
     126                 :          2 :     st->StatusMessage = zx_ref_elem(cf->ctx, &st->gg, zx_sp_StatusMessage_ELEM, msg);
     127                 :        111 :   st->StatusCode = zx_NEW_sp_StatusCode(cf->ctx, &st->gg);
     128                 :        111 :   st->StatusCode->Value = zx_ref_attr(cf->ctx, &st->StatusCode->gg, zx_Value_ATTR, sc1);
     129         [ +  + ]:        111 :   if (sc2) {
     130                 :          2 :     st->StatusCode->StatusCode = zx_NEW_sp_StatusCode(cf->ctx, &st->StatusCode->gg);
     131                 :          2 :     st->StatusCode->StatusCode->Value = zx_ref_attr(cf->ctx, &st->StatusCode->StatusCode->gg, zx_Value_ATTR, sc2);
     132                 :            :   }
     133                 :        111 :   return st;
     134                 :            : }
     135                 :            : 
     136                 :            : /*() Create SAML <Status> element indicating success. */
     137                 :            : 
     138                 :            : /* Called by:  zxid_idp_soap_dispatch, zxid_mk_saml_resp, zxid_mni_do, zxid_mni_do_ss, zxid_nidmap_do, zxid_slo_resp_redir, zxid_sp_soap_dispatch */
     139                 :            : struct zx_sp_Status_s* zxid_OK(zxid_conf* cf, struct zx_elem_s* father)
     140                 :        109 : {
     141                 :        109 :   return zxid_mk_Status(cf, father, SAML2_SC_SUCCESS, 0, 0);
     142                 :            : }
     143                 :            : 
     144                 :            : /*() Create EncryptedID given normal NameID and metadata of destination. Encryption
     145                 :            :  * will be done using encryption certificate of the receiver identified by the metadata. */
     146                 :            : 
     147                 :            : /* Called by:  zxid_mk_logout, zxid_mk_mni, zxid_mk_subj */
     148                 :            : struct zx_sa_EncryptedID_s* zxid_mk_enc_id(zxid_conf* cf, struct zx_elem_s* father, zxid_nid* nid, zxid_entity* meta)
     149                 :        820 : {
     150                 :        820 :   struct zx_sa_EncryptedID_s* encid = zx_NEW_sa_EncryptedID(cf->ctx, father);
     151                 :        820 :   struct zx_str* ss = zx_easy_enc_elem_opt(cf, &nid->gg);
     152         [ +  - ]:        820 :   if (cf->enckey_opt & 0x20) {
     153                 :            :     /* Nested EncryptedKey approach (Shibboleth early 2010) */
     154                 :        820 :     ZX_ADD_KID(encid, EncryptedData, zxenc_pubkey_enc(cf, ss, 0, meta->enc_cert, "41", 0));
     155                 :            :   } else {
     156                 :            :     /* RetrievalMethod approach */
     157                 :          0 :     ZX_ADD_KID(encid, EncryptedData, zxenc_pubkey_enc(cf, ss, &encid->EncryptedKey, meta->enc_cert, "38", meta));
     158                 :            :   }
     159                 :        820 :   zx_str_free(cf->ctx, ss);
     160                 :        820 :   return encid;
     161                 :            : }
     162                 :            : 
     163                 :            : /*() Create EncryptedAssertion given normal A7N and metadata of destination. Encryption
     164                 :            :  * will be done using encryption certificate of the receiver identified by the metadata. */
     165                 :            : 
     166                 :            : /* Called by:  zxid_add_fed_tok2epr, zxid_imreq, zxid_mk_saml_resp */
     167                 :            : struct zx_sa_EncryptedAssertion_s* zxid_mk_enc_a7n(zxid_conf* cf, struct zx_elem_s* father, zxid_a7n* a7n, zxid_entity* meta)
     168                 :        136 : {
     169                 :        136 :   struct zx_sa_EncryptedAssertion_s* enc_a7n = zx_NEW_sa_EncryptedAssertion(cf->ctx, father);
     170                 :        136 :   struct zx_str* ss = zx_easy_enc_elem_opt(cf, &a7n->gg);
     171         [ +  - ]:        136 :   if (cf->enckey_opt & 0x20) {
     172                 :            :     /* Nested EncryptedKey approach (Shibboleth early 2010) */
     173                 :        136 :     ZX_ADD_KID(enc_a7n, EncryptedData, zxenc_pubkey_enc(cf, ss, 0, meta->enc_cert, "40", 0));
     174                 :            :   } else {
     175                 :            :     /* RetrievalMethod approach */
     176                 :          0 :     ZX_ADD_KID(enc_a7n, EncryptedData, zxenc_pubkey_enc(cf, ss, &enc_a7n->EncryptedKey, meta->enc_cert, "39", meta));
     177                 :            :   }
     178                 :        136 :   zx_str_free(cf->ctx, ss);
     179                 :        136 :   return enc_a7n;
     180                 :            : }
     181                 :            : 
     182                 :            : /*() Create XML data structure for <LogoutRequest> element. Low level API. */
     183                 :            : 
     184                 :            : /* Called by:  test_ibm_cert_problem_enc_dec, zxid_sp_slo_redir, zxid_sp_slo_soap */
     185                 :            : struct zx_sp_LogoutRequest_s* zxid_mk_logout(zxid_conf* cf, zxid_nid* nid, struct zx_str* ses_ix, zxid_entity* idp_meta)
     186                 :          3 : {
     187                 :          3 :   struct zx_sp_LogoutRequest_s* r = zx_NEW_sp_LogoutRequest(cf->ctx,0);
     188                 :          3 :   r->Issuer = zxid_my_issuer(cf, &r->gg);
     189                 :          3 :   r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "L", ZXID_ID_BITS);
     190                 :          3 :   r->Version = zx_ref_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
     191                 :          3 :   r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
     192                 :            : 
     193   [ +  +  -  + ]:          3 :   D("nameid_enc(%d) idp_meta(%p) enc_cert(%p)", cf->nameid_enc, idp_meta, idp_meta->enc_cert);
     194   [ +  -  +  + ]:          5 :   if (cf->nameid_enc && idp_meta)
     195                 :          2 :     r->EncryptedID = zxid_mk_enc_id(cf, &r->gg, nid, idp_meta);
     196                 :            :   else
     197                 :          1 :     r->NameID = nid;
     198         [ +  + ]:          3 :   if (ses_ix)
     199                 :          2 :     r->SessionIndex = zx_new_str_elem(cf->ctx, &r->gg, zx_sp_SessionIndex_ELEM, ses_ix);
     200                 :          3 :   return r;
     201                 :            : }
     202                 :            : 
     203                 :            : /*() Create XML data structure for <LogoutResponse> element. Low level API. */
     204                 :            : 
     205                 :            : /* Called by:  zxid_idp_soap_dispatch, zxid_slo_resp_redir, zxid_sp_soap_dispatch */
     206                 :            : struct zx_sp_LogoutResponse_s* zxid_mk_logout_resp(zxid_conf* cf, struct zx_sp_Status_s* st, struct zx_str* req_id)
     207                 :          2 : {
     208                 :          2 :   struct zx_sp_LogoutResponse_s* r = zx_NEW_sp_LogoutResponse(cf->ctx,0);
     209                 :          2 :   r->Issuer = zxid_my_issuer(cf, &r->gg);
     210                 :          2 :   r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "r", ZXID_ID_BITS);
     211                 :          2 :   r->Version = zx_ref_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
     212                 :          2 :   r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
     213         [ +  - ]:          2 :   if (req_id)
     214                 :          2 :     r->InResponseTo = zx_ref_len_attr(cf->ctx, &r->gg, zx_InResponseTo_ATTR, req_id->len, req_id->s);
     215                 :          2 :   zx_add_kid(&r->gg, &st->gg);
     216                 :          2 :   r->Status = st;
     217                 :          2 :   return r;
     218                 :            : }
     219                 :            : 
     220                 :            : /*() Change SPNameID (newnym supplied), or Terminate federation (newnym not supplied).
     221                 :            :  * Create XML data structure for <ManageNameIDRequest> element. Low level API. */
     222                 :            : 
     223                 :            : /* Called by:  a7n_test, zxid_sp_mni_redir, zxid_sp_mni_soap */
     224                 :            : struct zx_sp_ManageNameIDRequest_s* zxid_mk_mni(zxid_conf* cf, zxid_nid* nid, struct zx_str* new_nym, zxid_entity* idp_meta)
     225                 :          1 : {
     226                 :            :   struct zx_str* ss;
     227                 :            :   struct zx_xenc_EncryptedKey_s* ek;
     228                 :            :   struct zx_elem_s* newid;
     229                 :          1 :   struct zx_sp_ManageNameIDRequest_s* r = zx_NEW_sp_ManageNameIDRequest(cf->ctx,0);
     230                 :          1 :   r->Issuer = zxid_my_issuer(cf, &r->gg);
     231                 :          1 :   r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "R", ZXID_ID_BITS);
     232                 :          1 :   r->Version = zx_ref_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
     233                 :          1 :   r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
     234   [ +  -  +  - ]:          2 :   if (cf->nameid_enc && idp_meta) {
     235                 :          1 :     r->EncryptedID = zxid_mk_enc_id(cf, &r->gg, nid, idp_meta);
     236   [ +  -  +  - ]:          2 :     if (new_nym && new_nym->len) {
     237                 :          1 :       newid = zx_new_str_elem(cf->ctx, 0, zx_sp_NewID_ELEM, new_nym);
     238                 :          1 :       ss = zx_easy_enc_elem_opt(cf, newid);
     239                 :          1 :       r->NewEncryptedID = zx_NEW_sp_NewEncryptedID(cf->ctx, &r->gg);
     240         [ +  - ]:          1 :       if (cf->enckey_opt & 0x20) {
     241                 :            :         /* Nested EncryptedKey approach (Shibboleth early 2010) */
     242                 :          1 :         ZX_ADD_KID(r->NewEncryptedID, EncryptedData, zxenc_pubkey_enc(cf, ss, 0, idp_meta->enc_cert, "43",0));
     243                 :            :       } else {
     244                 :            :         /* RetrievalMethod approach */
     245                 :          0 :         ZX_ADD_KID(r->NewEncryptedID, EncryptedData, zxenc_pubkey_enc(cf, ss, &ek, idp_meta->enc_cert, "39", idp_meta));
     246                 :          0 :         ZX_ADD_KID(r->NewEncryptedID, EncryptedKey, ek);
     247                 :          0 :         zx_reverse_elem_lists(&r->NewEncryptedID->gg);
     248                 :            :       }
     249                 :          1 :       zx_str_free(cf->ctx, ss);
     250                 :          1 :       zx_free_elem(cf->ctx, newid, 0);
     251                 :            :     } else
     252                 :          0 :       r->Terminate = zx_new_str_elem(cf->ctx, &r->gg, zx_sp_Terminate_ELEM, 0);
     253                 :            :   } else {
     254                 :          0 :     r->NameID = nid;
     255   [ #  #  #  # ]:          0 :     if (new_nym && new_nym->len)
     256                 :          0 :       r->NewID = zx_new_str_elem(cf->ctx, &r->gg, zx_sp_NewID_ELEM, new_nym);
     257                 :            :     else
     258                 :          0 :       r->Terminate = zx_new_str_elem(cf->ctx, &r->gg, zx_sp_Terminate_ELEM, 0);
     259                 :            :   }
     260                 :          1 :   return r;
     261                 :            : }
     262                 :            : 
     263                 :            : /*() Create XML data structure for <ManageNameIDResponse> element. Low level API.*/
     264                 :            : 
     265                 :            : /* Called by:  zxid_mni_do, zxid_mni_do_ss */
     266                 :            : struct zx_sp_ManageNameIDResponse_s* zxid_mk_mni_resp(zxid_conf* cf, struct zx_sp_Status_s* st, struct zx_str* req_id)
     267                 :          2 : {
     268                 :          2 :   struct zx_sp_ManageNameIDResponse_s* r = zx_NEW_sp_ManageNameIDResponse(cf->ctx,0);
     269                 :          2 :   r->Issuer = zxid_my_issuer(cf, &r->gg);
     270                 :          2 :   r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "r", ZXID_ID_BITS);
     271                 :          2 :   r->Version = zx_ref_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
     272                 :          2 :   r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
     273         [ +  - ]:          2 :   if (req_id)
     274                 :          2 :     r->InResponseTo = zx_ref_len_attr(cf->ctx, &r->gg,zx_InResponseTo_ATTR, req_id->len,req_id->s);
     275                 :          2 :   zx_add_kid(&r->gg, &st->gg);
     276                 :          2 :   r->Status = st;
     277                 :          2 :   return r;
     278                 :            : }
     279                 :            : 
     280                 :            : /* ======== IdP SSO Related ======== */
     281                 :            : 
     282                 :            : /*() Constructor for Assertion */
     283                 :            : 
     284                 :            : /* Called by:  zxid_map_val_ss, zxid_mk_usr_a7n_to_sp, zxid_xacml_az_cd1_do x2, zxid_xacml_az_do x2 */
     285                 :            : zxid_a7n* zxid_mk_a7n(zxid_conf* cf, struct zx_str* audience, struct zx_sa_Subject_s* subj, struct zx_sa_AuthnStatement_s* an_stmt, struct zx_sa_AttributeStatement_s* at_stmt)
     286                 :        916 : {
     287                 :        916 :   zxid_a7n* a7n =  zx_NEW_sa_Assertion(cf->ctx,0);
     288                 :        916 :   a7n->Version = zx_dup_attr(cf->ctx, &a7n->gg, zx_Version_ATTR, SAML2_VERSION);
     289                 :        916 :   a7n->ID = zxid_mk_id_attr(cf, &a7n->gg, zx_ID_ATTR, "A", ZXID_ID_BITS);
     290                 :        916 :   a7n->IssueInstant = zxid_date_time_attr(cf, &a7n->gg, zx_IssueInstant_ATTR, time(0));
     291                 :        916 :   a7n->Issuer = zxid_my_issuer(cf, &a7n->gg);
     292                 :        916 :   a7n->Subject = subj;
     293         [ +  + ]:        916 :   if (subj)
     294                 :        817 :     zx_add_kid(&a7n->gg, &subj->gg);
     295                 :        916 :   a7n->Conditions = zx_NEW_sa_Conditions(cf->ctx, &a7n->gg);
     296                 :        916 :   a7n->Conditions->NotOnOrAfter = zxid_date_time_attr(cf, &a7n->Conditions->gg, zx_NotOnOrAfter_ATTR, time(0) + cf->a7nttl);
     297                 :        916 :   a7n->Conditions->NotBefore = zxid_date_time_attr(cf, &a7n->Conditions->gg, zx_NotBefore_ATTR, time(0));
     298         [ +  + ]:        916 :   if (audience) {
     299                 :        817 :     a7n->Conditions->AudienceRestriction = zx_NEW_sa_AudienceRestriction(cf->ctx, &a7n->Conditions->gg);
     300                 :        817 :     a7n->Conditions->AudienceRestriction->Audience = zx_new_str_elem(cf->ctx, &a7n->Conditions->AudienceRestriction->gg, zx_sa_Audience_ELEM, audience);
     301                 :            :   }
     302                 :        916 :   a7n->AuthnStatement = an_stmt;
     303         [ +  + ]:        916 :   if (an_stmt)
     304                 :        137 :     zx_add_kid(&a7n->gg, &an_stmt->gg);
     305                 :        916 :   a7n->AttributeStatement = at_stmt;
     306         [ +  + ]:        916 :   if (at_stmt)
     307                 :        817 :     zx_add_kid(&a7n->gg, &at_stmt->gg);
     308                 :        916 :   zx_reverse_elem_lists(&a7n->gg);
     309                 :        916 :   return a7n;
     310                 :            : }
     311                 :            : 
     312                 :            : /*() Construct Subject, possibly with EncryptedID */
     313                 :            : 
     314                 :            : /* Called by:  zxid_map_val_ss, zxid_mk_usr_a7n_to_sp, zxid_xacml_az_cd1_do, zxid_xacml_az_do */
     315                 :            : struct zx_sa_Subject_s* zxid_mk_subj(zxid_conf* cf, struct zx_elem_s* father, zxid_entity* sp_meta, zxid_nid* nid)
     316                 :        817 : {
     317                 :        817 :   struct zx_sa_Subject_s* subj = zx_NEW_sa_Subject(cf->ctx, father);
     318                 :            : 
     319                 :            : #if 0
     320                 :            :   // , struct zx_str* affil, char* fmt
     321                 :            :   nid = zx_NEW_sa_NameID(cf->ctx,0);
     322                 :            :   nid->Format = zx_dup_str(cf->ctx, fmt);  /* *** implement persistent */
     323                 :            :   nid->NameQualifier = zxid_my_ent_id(cf);
     324                 :            :   nid->SPNameQualifier = affil;
     325                 :            :   if (!strcmp(fmt, SAML2_TRANSIENT_NID_FMT)) {
     326                 :            :     zx_add_content(cf->ctx, nid, zxid_mk_id(cf, "T", ZXID_ID_BITS));
     327                 :            :   } else {
     328                 :            :     /* *** see also zxid_get_user_nameid() */
     329                 :            :   }
     330                 :            : #endif
     331                 :            : 
     332         [ +  - ]:        817 :   if (cf->nameid_enc) {
     333         [ +  - ]:        817 :     if (sp_meta)
     334                 :        817 :       subj->EncryptedID = zxid_mk_enc_id(cf, &subj->gg, nid, sp_meta);
     335                 :            :     else {
     336                 :          0 :       ERR("NameID encryption confugred, but no metadata supplied. Defaulting to unencrypted NameID %d", 0);
     337                 :          0 :       subj->NameID = nid;
     338                 :            :     }
     339                 :            :   } else
     340                 :          0 :     subj->NameID = nid;
     341                 :            :   /* SAML spec is more lax than the schema: saml-core-2.0-os.pdf ll.653-657 says <SubjectConfirmation> [Zero or More] */
     342                 :        817 :   return subj;
     343                 :            : }
     344                 :            : 
     345                 :            : /*() Construct AuthnStatement */
     346                 :            : 
     347                 :            : /* Called by:  zxid_mk_usr_a7n_to_sp */
     348                 :            : struct zx_sa_AuthnStatement_s* zxid_mk_an_stmt(zxid_conf* cf, zxid_ses* ses, struct zx_elem_s* father, const char* eid)
     349                 :        137 : {
     350                 :            :   struct zx_str sesix;
     351                 :            :   struct zx_str eid_ss;
     352                 :            :   struct zx_str* ss;
     353                 :        137 :   struct zx_sa_AuthnStatement_s* an_stmt = zx_NEW_sa_AuthnStatement(cf->ctx, father);
     354         [ +  + ]:        137 :   if (ses->sesix) {
     355                 :            : #if 0
     356                 :            :     an_stmt->SessionIndex = zx_dup_str(cf->ctx, ses->sesix);
     357                 :            : #else
     358                 :            :     /* Need noncorrelatable session index */
     359                 :         72 :     eid_ss.len = strlen(eid);
     360                 :         72 :     eid_ss.s = (char*)eid;
     361                 :         72 :     sesix.len = strlen(ses->sesix);
     362                 :         72 :     sesix.s = ses->sesix;
     363                 :         72 :     ss = zxid_psobj_enc(cf, &eid_ss, "ZS", &sesix);
     364                 :         72 :     an_stmt->SessionIndex = zx_ref_len_attr(cf->ctx, &an_stmt->gg, zx_SessionIndex_ATTR, ss->len, ss->s);
     365                 :            : #endif
     366                 :            :   }
     367                 :        137 :   an_stmt->AuthnInstant = zxid_date_time_attr(cf, &an_stmt->gg, zx_AuthnInstant_ATTR, ses->an_instant);
     368                 :        137 :   an_stmt->AuthnContext = zx_NEW_sa_AuthnContext(cf->ctx, &an_stmt->gg);
     369         [ +  + ]:        137 :   if (ses->an_ctx)
     370                 :         72 :     an_stmt->AuthnContext->AuthnContextClassRef
     371                 :            :       = zx_dup_elem(cf->ctx, &an_stmt->AuthnContext->gg, zx_sa_AuthnContextClassRef_ELEM, ses->an_ctx);
     372                 :            :   else {
     373                 :         65 :     ERR("Session(%s) lacks AuthentContextClassRef. Output AuthnStatement will not satisfy all processing rules. See configuration option ISSUE_AUTHNCTX_PW.", ses->sesix);
     374                 :            :   }
     375                 :        137 :   return an_stmt;
     376                 :            : }
     377                 :            : 
     378                 :            : /*() Construct SAML SAML Attribute from string */
     379                 :            : 
     380                 :            : /* Called by:  zxid_add_mapped_attr, zxid_map_val_ss, zxid_mk_sa_attribute */
     381                 :            : struct zx_sa_Attribute_s* zxid_mk_sa_attribute_ss(zxid_conf* cf, struct zx_elem_s* father, const char* name, const char* namfmt, struct zx_str* val)
     382                 :       3806 : {
     383                 :            :   struct zx_root_s* r;
     384                 :       3806 :   struct zx_sa_Attribute_s* at = zx_NEW_sa_Attribute(cf->ctx, father);
     385         [ -  + ]:       3806 :   if (namfmt)
     386                 :          0 :     at->NameFormat = zx_ref_attr(cf->ctx, &at->gg, zx_NameFormat_ATTR, namfmt);
     387                 :       3806 :   at->Name = zx_dup_attr(cf->ctx, &at->gg, zx_Name_ATTR, name);
     388                 :       3806 :   at->AttributeValue = zx_NEW_sa_AttributeValue(cf->ctx, &at->gg);
     389         [ +  + ]:       3806 :   if (!val)
     390                 :        114 :     return at;
     391                 :            : 
     392         [ +  + ]:       3692 :   if (val->s[0] == '<') {
     393                 :            :     /* Looks like the value may be XML data. We need to pass it as XML data structure for
     394                 :            :      * canonicalization to work right (e.g. value is an A7N that is rendered one
     395                 :            :      * way when canonicalized independently, but in different way when canonicalized
     396                 :            :      * as part of a bigger structure - for example sa namespace may be omitted as it
     397                 :            :      * is already supplied by the parent element). */
     398                 :        816 :     r = zx_dec_zx_root(cf->ctx, val->len, val->s, "sa at parse");
     399   [ +  -  +  - ]:       1632 :     if (r && r->gg.kids) {
     400                 :        816 :       at->AttributeValue->gg.kids = r->gg.kids;
     401   [ +  -  -  -  :        816 :       switch (r->gg.kids->g.tok) {
                      + ]
     402                 :        136 :       case zx_sa_Assertion_ELEM:          at->AttributeValue->Assertion = (void*)r->gg.kids; break;
     403                 :          0 :       case zx_sa_EncryptedAssertion_ELEM: at->AttributeValue->EncryptedAssertion = (void*)r->gg.kids; break;
     404                 :          0 :       case zx_di12_ResourceOffering_ELEM: at->AttributeValue->ResourceOffering = (void*)r->gg.kids; break;
     405                 :          0 :       case zx_a_EndpointReference_ELEM:   at->AttributeValue->EndpointReference = (void*)r->gg.kids; break;
     406                 :            :       }
     407                 :        816 :       ZX_FREE(cf->ctx, r);
     408                 :            :     } else {
     409                 :            :       /* XML did not parse, may be its just string data, after all. */
     410                 :          0 :       zx_add_content(cf->ctx, &at->AttributeValue->gg, val);
     411                 :            :     }
     412                 :            :   } else {
     413                 :       2876 :     zx_add_content(cf->ctx, &at->AttributeValue->gg, val);
     414                 :            :   }
     415                 :       3692 :   return at;
     416                 :            : }
     417                 :            : 
     418                 :            : /*() Construct SAML SAML Attribute */
     419                 :            : 
     420                 :            : /* Called by:  zxid_gen_boots, zxid_mk_usr_a7n_to_sp x2 */
     421                 :            : struct zx_sa_Attribute_s* zxid_mk_sa_attribute(zxid_conf* cf, struct zx_elem_s* father, const char* name, const char* namfmt, const char* val)
     422                 :        251 : {
     423         [ +  + ]:        251 :   return zxid_mk_sa_attribute_ss(cf, father, name, namfmt, val?zx_dup_str(cf->ctx, val):0);
     424                 :            : }
     425                 :            : 
     426                 :            : /*() Construct SAML protocol Response (such as may be used to carry assertion in SSO) */
     427                 :            : 
     428                 :            : /* Called by:  zxid_idp_sso x4, zxid_ssos_anreq, zxid_xacml_az_cd1_do x2, zxid_xacml_az_do x2 */
     429                 :            : struct zx_sp_Response_s* zxid_mk_saml_resp(zxid_conf* cf, zxid_a7n* a7n, zxid_entity* enc_meta)
     430                 :        105 : {
     431                 :        105 :   struct zx_sp_Response_s* r = zx_NEW_sp_Response(cf->ctx,0);
     432                 :        105 :   r->Version = zx_dup_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
     433                 :        105 :   r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "R", ZXID_ID_BITS);
     434                 :        105 :   r->Issuer = zxid_my_issuer(cf, &r->gg);
     435                 :        105 :   r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
     436                 :        105 :   r->Status = zxid_OK(cf, &r->gg);
     437         [ +  - ]:        105 :   if (a7n) {
     438         [ +  + ]:        105 :     if (enc_meta) {
     439                 :            :       /* See saml-bindings-2.0-os.pdf, sec 3.5.5.2 Security Considerations, p.24, ll.847-851
     440                 :            :        * After publication it was understood that the SHOULD NOT could be eliminated
     441                 :            :        * if EncryptedAssertion is used. */
     442                 :            : 
     443                 :          6 :       r->EncryptedAssertion = zxid_mk_enc_a7n(cf, &r->gg, a7n, enc_meta);
     444                 :            :     } else {
     445                 :         99 :       r->Assertion = a7n;
     446                 :         99 :       zx_add_kid(&r->gg, &a7n->gg);
     447                 :            :     }
     448                 :            :   }
     449                 :        105 :   zx_reverse_elem_lists(&r->gg);
     450                 :        105 :   return r;
     451                 :            : }
     452                 :            : 
     453                 :            : /*() Construct XACML Response */
     454                 :            : 
     455                 :            : /* Called by:  zxid_ins_xacml_az_cd1_stmt x2, zxid_ins_xacml_az_stmt x2 */
     456                 :            : struct zx_xac_Response_s* zxid_mk_xacml_resp(zxid_conf* cf, char* decision)
     457                 :         99 : {
     458                 :         99 :   struct zx_xac_Response_s* resp = zx_NEW_xac_Response(cf->ctx,0);
     459                 :         99 :   resp->Result = zx_NEW_xac_Result(cf->ctx, &resp->gg);
     460                 :         99 :   resp->Result->Decision = zx_ref_elem(cf->ctx, &resp->Result->gg, zx_xac_Decision_ELEM, decision);
     461                 :         99 :   resp->Result->Status = zx_NEW_xac_Status(cf->ctx, &resp->Result->gg);
     462                 :         99 :   resp->Result->Status->StatusCode = zx_NEW_xac_StatusCode(cf->ctx, &resp->Result->Status->gg);
     463                 :         99 :   resp->Result->Status->StatusCode->Value
     464                 :            :     = zx_ref_attr(cf->ctx, &resp->Result->Status->StatusCode->gg, zx_Value_ATTR, "urn:oasis:names:tc:xacml:1.0:status:ok");
     465                 :         99 :   zx_reverse_elem_lists(&resp->Result->gg);
     466                 :         99 :   return resp;
     467                 :            : }
     468                 :            : 
     469                 :            : /* Called by:  zxid_pepmap_extract x3 */
     470                 :            : struct zx_xac_Attribute_s* zxid_mk_xacml_simple_at(zxid_conf* cf, struct zx_elem_s* father, struct zx_str* atid, struct zx_str* attype, struct zx_str* atissuer, struct zx_str* atvalue)
     471                 :       4148 : {
     472                 :            :   struct zx_root_s* r;
     473                 :       4148 :   struct zx_xac_Attribute_s* at = zx_NEW_xac_Attribute(cf->ctx, father);
     474                 :       4148 :   at->AttributeId = zx_ref_len_attr(cf->ctx, &at->gg, zx_AttributeId_ATTR, atid->len, atid->s);
     475                 :       4148 :   at->DataType = zx_ref_len_attr(cf->ctx, &at->gg, zx_DataType_ATTR, attype->len, attype->s);
     476         [ +  + ]:       4148 :   if (atissuer)
     477                 :       1625 :     at->Issuer = zx_ref_len_attr(cf->ctx, &at->gg, zx_Issuer_ATTR, atissuer->len, atissuer->s);
     478         [ +  + ]:       4148 :   if (atvalue->s[0] == '<') {
     479                 :            :     /* Looks like the value may be XML data. We need to pass it as XML data structure for
     480                 :            :      * canonicalization to work right (e.g. value is an A7N that is rendered one
     481                 :            :      * way when canonicalized independently, but in different way when canonicalized
     482                 :            :      * as part of a bigger structure - for example sa namespace may be omitted as it
     483                 :            :      * is already supplied by the parent element). */
     484                 :        142 :     r = zx_dec_zx_root(cf->ctx, atvalue->len, atvalue->s, "xac at parse");
     485   [ +  -  +  - ]:        284 :     if (r && r->gg.kids) {
     486                 :        142 :       at->AttributeValue = zx_new_elem(cf->ctx, &at->gg, zx_xac_AttributeValue_ELEM);
     487                 :        142 :       at->AttributeValue->kids = r->gg.kids;
     488                 :        142 :       ZX_FREE(cf->ctx, r);
     489                 :            :     } else {
     490                 :            :       /* XML did not parse, may be its just string data, after all. */
     491                 :          0 :       at->AttributeValue = zx_new_str_elem(cf->ctx, &at->gg, zx_xac_AttributeValue_ELEM, atvalue);
     492                 :            :     }
     493                 :            :   } else {
     494                 :       4006 :     at->AttributeValue = zx_new_str_elem(cf->ctx, &at->gg, zx_xac_AttributeValue_ELEM, atvalue);
     495                 :            :   }
     496                 :       4148 :   zx_reverse_elem_lists(&at->gg);
     497                 :       4148 :   return at;
     498                 :            : }
     499                 :            : 
     500                 :            : /*() Construct xac_Request */
     501                 :            : 
     502                 :            : /* Called by:  zxid_az_soap, zxid_mk_az, zxid_mk_az_cd1 */
     503                 :            : struct zx_xac_Request_s* zxid_mk_xac_az(zxid_conf* cf, struct zx_elem_s* father, struct zx_xac_Attribute_s* subj, struct zx_xac_Attribute_s* rsrc, struct zx_xac_Attribute_s* act, struct zx_xac_Attribute_s* env)
     504                 :         93 : {
     505                 :         93 :   struct zx_xac_Request_s* r = zx_NEW_xac_Request(cf->ctx, father);
     506                 :            :   /* N.B. The lists are already linked and only need to be attached to kids lists. */
     507                 :         93 :   r->Subject  = zx_NEW_xac_Subject(cf->ctx, &r->gg);
     508                 :         93 :   r->Subject->gg.kids = (struct zx_elem_s*)(r->Subject->Attribute = subj);
     509                 :            : 
     510                 :         93 :   r->Resource = zx_NEW_xac_Resource(cf->ctx, &r->gg);
     511                 :         93 :   r->Resource->gg.kids = (struct zx_elem_s*)(r->Resource->Attribute = rsrc);
     512                 :            : 
     513                 :         93 :   r->Action   = zx_NEW_xac_Action(cf->ctx, &r->gg);
     514                 :         93 :   r->Action->gg.kids = (struct zx_elem_s*)(r->Action->Attribute = act);
     515                 :            : 
     516                 :         93 :   r->Environment = zx_NEW_xac_Environment(cf->ctx, &r->gg);
     517                 :         93 :   r->Environment->gg.kids = (struct zx_elem_s*)(r->Environment->Attribute = env);
     518                 :            : 
     519                 :         93 :   zx_reverse_elem_lists(&r->gg);
     520                 :         93 :   return r;
     521                 :            : }
     522                 :            : 
     523                 :            : /*() Construct XACMLAuthzDecisionQuery */
     524                 :            : 
     525                 :            : /* Called by:  attribute_sort_test, zxid_az_soap */
     526                 :            : struct zx_xasp_XACMLAuthzDecisionQuery_s* zxid_mk_az(zxid_conf* cf, struct zx_xac_Attribute_s* subj, struct zx_xac_Attribute_s* rsrc, struct zx_xac_Attribute_s* act, struct zx_xac_Attribute_s* env)
     527                 :         91 : {
     528                 :         91 :   struct zx_xasp_XACMLAuthzDecisionQuery_s* r = zx_NEW_xasp_XACMLAuthzDecisionQuery(cf->ctx,0);
     529                 :         91 :   r->Issuer = zxid_my_issuer(cf, &r->gg);
     530                 :         91 :   r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "R", ZXID_ID_BITS);
     531                 :         91 :   r->Version = zx_ref_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
     532                 :         91 :   r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
     533                 :         91 :   r->Request = zxid_mk_xac_az(cf, &r->gg, subj, rsrc, act, env);
     534                 :         91 :   zx_reverse_elem_lists(&r->gg);
     535                 :         91 :   return r;
     536                 :            : }
     537                 :            : 
     538                 :            : /*() Construct XACMLAuthzDecisionQuery according to Commitee Draft 1 */
     539                 :            : 
     540                 :            : /* Called by:  zxid_az_soap */
     541                 :            : struct zx_xaspcd1_XACMLAuthzDecisionQuery_s* zxid_mk_az_cd1(zxid_conf* cf, struct zx_xac_Attribute_s* subj, struct zx_xac_Attribute_s* rsrc, struct zx_xac_Attribute_s* act, struct zx_xac_Attribute_s* env)
     542                 :          2 : {
     543                 :          2 :   struct zx_xaspcd1_XACMLAuthzDecisionQuery_s* r = zx_NEW_xaspcd1_XACMLAuthzDecisionQuery(cf->ctx,0);
     544                 :          2 :   r->Issuer = zxid_my_issuer(cf, &r->gg);
     545                 :          2 :   r->ID = zxid_mk_id_attr(cf, &r->gg, zx_ID_ATTR, "R", ZXID_ID_BITS);
     546                 :          2 :   r->Version = zx_ref_attr(cf->ctx, &r->gg, zx_Version_ATTR, SAML2_VERSION);
     547                 :          2 :   r->IssueInstant = zxid_date_time_attr(cf, &r->gg, zx_IssueInstant_ATTR, time(0));
     548                 :          2 :   r->Request = zxid_mk_xac_az(cf, &r->gg, subj, rsrc, act, env);
     549                 :          2 :   zx_reverse_elem_lists(&r->gg);
     550                 :          2 :   return r;
     551                 :            : }
     552                 :            : 
     553                 :            : /* EOF  --  zxidmk.c */

Generated by: LCOV version 1.9