Exemple #1
0
int EB_Msg_WriteSignature(EB_MSG *m, const unsigned char *hash, int hsize) {
  int rv;
  GWEN_BUFFER *hbuf;

  assert(m);
  assert(m->usage);

  if (hsize!=128) {
    DBG_ERROR(AQEBICS_LOGDOMAIN,
	      "Bad signature size (expected 128, was %d)",
	      hsize);
    return -1;
  }

  hbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=GWEN_Base64_Encode(hash, (uint32_t) hsize, hbuf, 0);
  if (rv) {
    DBG_ERROR(AQEBICS_LOGDOMAIN,
	      "Could not base64-encode signature (%d)", rv);
    GWEN_Buffer_free(hbuf);
    return -1;
  }
  EB_Xml_SetCharValue(xmlDocGetRootElement(m->doc),
                      "AuthSignature/"
		      "ds:SignatureValue",
		      GWEN_Buffer_GetStart(hbuf));
  GWEN_Buffer_free(hbuf);

  return 0;
}
Exemple #2
0
static int EBC_Provider_SignMessage_X001(AB_PROVIDER *pro,
					 EB_MSG *msg,
					 AB_USER *u,
					 xmlNodePtr node) {
  EBC_PROVIDER *dp;
  int rv;
  GWEN_CRYPT_TOKEN *ct;
  const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
  const GWEN_CRYPT_TOKEN_KEYINFO *ki;
  uint32_t keyId;
  GWEN_BUFFER *hbuf;
  GWEN_BUFFER *bbuf;
  xmlNodePtr nodeX = NULL;
  xmlNodePtr nodeXX = NULL;
  xmlNodePtr nodeXXX = NULL;
  xmlNodePtr nodeXXXX = NULL;
  xmlNsPtr ns;

  assert(pro);
  dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
  assert(dp);

  /* get crypt token and context */
  rv=EBC_Provider_MountToken(pro, u, &ct, &ctx);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    return rv;
  }

  /* get key id */
  keyId=GWEN_Crypt_Token_Context_GetAuthSignKeyId(ctx);
  ki=GWEN_Crypt_Token_GetKeyInfo(ct,
				 keyId,
				 0xffffffff,
				 0);
  if (ki==NULL) {
    DBG_INFO(AQEBICS_LOGDOMAIN,
	     "Keyinfo %04x not found on crypt token [%s:%s]",
	     keyId,
	     GWEN_Crypt_Token_GetTypeName(ct),
	     GWEN_Crypt_Token_GetTokenName(ct));
    GWEN_Crypt_Token_Close(ct, 0, 0);
    return GWEN_ERROR_NOT_FOUND;
  }

  /* prepare signature nodes */
  ns=xmlSearchNs(EB_Msg_GetDoc(msg), node, BAD_CAST "ds");
  assert(ns);

  /* build hash */
  bbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=EB_Msg_BuildHashSha1(msg, bbuf);
  if (rv) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not build hash");
    GWEN_Buffer_free(bbuf);
    return rv;
  }

  /* base64 encode */
  hbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(bbuf),
			GWEN_Buffer_GetUsedBytes(bbuf),
			hbuf, 0);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(hbuf);
    GWEN_Buffer_free(bbuf);
    return rv;
  }
  GWEN_Buffer_free(bbuf);

  /* create signature node */
  nodeX=xmlNewChild(node, ns, BAD_CAST "SignedInfo", NULL);
  nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "CanonicalizationMethod", NULL);
  xmlNewProp(nodeXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
  nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "SignatureMethod", NULL);
  xmlNewProp(nodeXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
  nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "Reference", NULL);
  xmlNewProp(nodeXX,
	     BAD_CAST "URI",
	     BAD_CAST "#xpointer(//*[@authenticate='true'])");
  nodeXXX=xmlNewChild(nodeXX, ns, BAD_CAST "Transforms", NULL);
  nodeXXXX=xmlNewChild(nodeXXX, ns, BAD_CAST "Transform", NULL);
  xmlNewProp(nodeXXXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");

  nodeXXX=xmlNewChild(nodeXX, ns, BAD_CAST "DigestMethod", NULL);
  xmlNewProp(nodeXXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/2000/09/xmldsig#sha1");

  /* store hash value */
  xmlNewTextChild(nodeXX, ns,
		  BAD_CAST "DigestValue",
		  BAD_CAST GWEN_Buffer_GetStart(hbuf));
  GWEN_Buffer_free(hbuf);

  /* build hash over SignedInfo */
  bbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=EB_Xml_BuildNodeHashSha1(nodeX, "#xpointer(//*)", bbuf);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(bbuf);
    return rv;
  }

  /* sign hash */
  if (1) {
    GWEN_CRYPT_PADDALGO *algo;
    int ksize;
    uint32_t l;
    const uint8_t prefix[]={
      0x30, 0x21, 0x30, 0x09,
      0x06, 0x05, 0x2B, 0x0E,
      0x03, 0x02, 0x1A, 0x05,
      0x00, 0x04, 0x14};

    /* add prefix to hash of SignedInfo */
    hbuf=GWEN_Buffer_new(0, 256, 0, 1);
    ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki);
    GWEN_Buffer_AppendBytes(hbuf, (const char*)prefix, sizeof(prefix));
    GWEN_Buffer_AppendBuffer(hbuf, bbuf);
    GWEN_Buffer_Reset(bbuf);

    /* select padd algo */
    algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_1);
    GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize);

    /* actually sign */
    GWEN_Buffer_AllocRoom(bbuf, ksize+16);
    l=GWEN_Buffer_GetMaxUnsegmentedWrite(bbuf);
    rv=GWEN_Crypt_Token_Sign(ct, keyId,
			     algo,
			     (const uint8_t*)GWEN_Buffer_GetStart(hbuf),
			     GWEN_Buffer_GetUsedBytes(hbuf),
			     (uint8_t*)GWEN_Buffer_GetPosPointer(bbuf),
			     &l,
			     NULL, /* ignore seq counter */
			     0);
    GWEN_Crypt_PaddAlgo_free(algo);
    if (rv<0) {
      DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
      GWEN_Buffer_free(bbuf);
      GWEN_Buffer_free(hbuf);
      return rv;
    }
    GWEN_Buffer_IncrementPos(bbuf, l);
    GWEN_Buffer_AdjustUsedBytes(bbuf);

    /* base 64 encode signature */
    GWEN_Buffer_Reset(hbuf);
    rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(bbuf),
			  GWEN_Buffer_GetUsedBytes(bbuf),
			  hbuf, 0);
    if (rv<0) {
      DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
      GWEN_Buffer_free(hbuf);
      GWEN_Buffer_free(bbuf);
      return rv;
    }
    GWEN_Buffer_free(bbuf);

    /* store signature */
    xmlNewTextChild(node, ns,
		    BAD_CAST "SignatureValue",
		    BAD_CAST GWEN_Buffer_GetStart(hbuf));
    GWEN_Buffer_free(hbuf);
  }

  return 0;
}
Exemple #3
0
int EBC_Provider_MkEuZipDoc_A004(AB_PROVIDER *pro,
				 AB_USER *u,
				 const char *requestType,
				 const uint8_t *pMsg,
				 uint32_t lMsg,
				 GWEN_BUFFER *sbuf) {
  int rv;
  xmlDocPtr doc;
  xmlNodePtr root_node;
  xmlNodePtr node;
  xmlNsPtr ns;
  GWEN_BUFFER *tbuf;
  GWEN_BUFFER *bbuf;

  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=EBC_Provider_EuSign_A004(pro, u, requestType, pMsg, lMsg, tbuf);
  if (rv) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  bbuf=GWEN_Buffer_new(0, (GWEN_Buffer_GetUsedBytes(tbuf)*3)/2, 0, 1);
  rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(tbuf),
			GWEN_Buffer_GetUsedBytes(tbuf),
			bbuf, 0);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(bbuf);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  GWEN_Buffer_free(tbuf);

  doc=xmlNewDoc(BAD_CAST "1.0");

  root_node=xmlNewNode(NULL, BAD_CAST "UserSignatureData");
  xmlDocSetRootElement(doc, root_node);
  ns=xmlNewNs(root_node,
	      BAD_CAST "http://www.ebics.org/H002",
	      NULL);
  assert(ns);
  ns=xmlNewNs(root_node,
	      BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",
	      BAD_CAST "xsi");
  xmlNewNsProp(root_node,
	       ns,
	       BAD_CAST "schemaLocation", /* xsi:schemaLocation */
	       BAD_CAST "http://www.ebics.org/H002 "
	       "http://www.ebics.org/H002/ebics_orders.xsd");

  node=xmlNewTextChild(root_node, NULL,
		       BAD_CAST "OrderSignature",
		       BAD_CAST GWEN_Buffer_GetStart(bbuf));
  GWEN_Buffer_free(bbuf);

  xmlNewProp(node,
	     BAD_CAST "PartnerID",
	     BAD_CAST AB_User_GetCustomerId(u));


  rv=EB_Xml_CompressDoc(doc, sbuf);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    xmlFreeDoc(doc);
    return rv;
  }

  xmlFreeDoc(doc);


  return 0;
}
Exemple #4
0
int EBC_Provider_MkEuCryptZipDoc_A004(AB_PROVIDER *pro,
				      AB_USER *u,
				      const char *requestType,
				      const uint8_t *pMsg,
				      uint32_t lMsg,
				      GWEN_CRYPT_KEY *skey,
				      GWEN_BUFFER *sbuf) {
  GWEN_BUFFER *tbuf;
  GWEN_BUFFER *ebuf;
  int rv;
  uint32_t l;

  DBG_INFO(AQEBICS_LOGDOMAIN, "Generating EU A005");
  tbuf=GWEN_Buffer_new(0, 512, 0, 1);
  rv=EBC_Provider_MkEuZipDoc_A004(pro, u, requestType, pMsg, lMsg, tbuf);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  /* padd EU */
  rv=GWEN_Padd_PaddWithAnsiX9_23(tbuf);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  /* encrypt EU with the DES session key */
  ebuf=GWEN_Buffer_new(0, GWEN_Buffer_GetUsedBytes(tbuf)+16, 0, 1);
  l=GWEN_Buffer_GetMaxUnsegmentedWrite(ebuf);
  /* reset IV !! */
  GWEN_Crypt_KeyDes3K_SetIV(skey, NULL, 0);
  rv=GWEN_Crypt_Key_Encipher(skey,
			     (uint8_t*)GWEN_Buffer_GetStart(tbuf),
			     GWEN_Buffer_GetUsedBytes(tbuf),
			     (uint8_t*)GWEN_Buffer_GetPosPointer(ebuf),
			     &l);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(ebuf);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  GWEN_Buffer_free(tbuf);
  GWEN_Buffer_IncrementPos(ebuf, l);
  GWEN_Buffer_AdjustUsedBytes(ebuf);

  /* base64 encode encrypted EU into given buffer */
  rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(ebuf),
			GWEN_Buffer_GetUsedBytes(ebuf),
			sbuf, 0);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(ebuf);
    return rv;
  }
  GWEN_Buffer_free(ebuf);

  return 0;
}
Exemple #5
0
int EBC_Provider_XchgIniRequest_H002(AB_PROVIDER *pro,
                                     GWEN_HTTP_SESSION *sess,
                                     AB_USER *u)
{
  int rv;
  GWEN_CRYPT_TOKEN *ct;
  const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
  uint32_t kid;
  const GWEN_CRYPT_TOKEN_KEYINFO *signKeyInfo=NULL;
  xmlNsPtr ns;
  EB_MSG *msg;
  const char *userId;
  EB_MSG *mRsp;
  EB_RC rc;
  xmlDocPtr doc;
  xmlNodePtr root_node = NULL;
  xmlNodePtr node = NULL;
  GWEN_BUFFER *tbuf;
  const char *signVersion;
  const char *s;
  GWEN_BUFFER *bufKey;
  GWEN_BUFFER *bufZip;
  GWEN_BUFFER *bufB64;

  userId=AB_User_GetUserId(u);

  /* get crypt token and context */
  rv=EBC_Provider_MountToken(pro, u, &ct, &ctx);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    return rv;
  }

  /* get crypt key info */
  kid=GWEN_Crypt_Token_Context_GetSignKeyId(ctx);
  if (kid) {
    signKeyInfo=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
                                            0);
    if (signKeyInfo==NULL) {
      DBG_ERROR(AQEBICS_LOGDOMAIN, "Sign key info not found on crypt token");
      GWEN_Gui_ProgressLog(0,
                           GWEN_LoggerLevel_Error,
                           I18N("Sign key info not found on crypt token"));
      return GWEN_ERROR_NOT_FOUND;
    }
  }

  signVersion=EBC_User_GetSignVersion(u);
  if (!(signVersion && *signVersion))
    signVersion="A004";

  if (strcasecmp(signVersion, "A004")==0) {
    /* encode according to "DFUE-Abkommen" */
    bufKey=GWEN_Buffer_new(0, 512, 0, 1);
    rc=EB_Key_Info_toBin(signKeyInfo, userId, "A004", 1024, bufKey);
    if (rc) {
      DBG_ERROR(AQEBICS_LOGDOMAIN, "Error writing key (rc=%06x)", rc);
      GWEN_Buffer_free(bufKey);
      return GWEN_ERROR_GENERIC;
    }

    /* zip order */
    bufZip=GWEN_Buffer_new(0, 512, 0, 1);
    if (EB_Zip_Deflate(GWEN_Buffer_GetStart(bufKey),
                       GWEN_Buffer_GetUsedBytes(bufKey),
                       bufZip)) {
      DBG_ERROR(AQEBICS_LOGDOMAIN, "Unable to zip key data");
      GWEN_Buffer_free(bufZip);
      GWEN_Buffer_free(bufKey);
      return GWEN_ERROR_GENERIC;
    }
    GWEN_Buffer_free(bufKey);

    /* base64 encode for order */
    bufB64=GWEN_Buffer_new(0, 800, 0, 1);
    if (GWEN_Base64_Encode((const unsigned char *)GWEN_Buffer_GetStart(bufZip),
                           GWEN_Buffer_GetUsedBytes(bufZip),
                           bufB64, 0)) {
      DBG_ERROR(AQEBICS_LOGDOMAIN, "Error encoding key");
      GWEN_Buffer_free(bufB64);
      GWEN_Buffer_free(bufZip);
      return GWEN_ERROR_GENERIC;
    }
    GWEN_Buffer_free(bufZip);
  }
  else {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Unsupported sign version [%s]", signVersion);
    return GWEN_ERROR_INTERNAL;
  }

  /* create request */
  msg=EB_Msg_new();
  doc=EB_Msg_GetDoc(msg);
  root_node=xmlNewNode(NULL, BAD_CAST "ebicsUnsecuredRequest");
  xmlDocSetRootElement(doc, root_node);
  ns=xmlNewNs(root_node,
              BAD_CAST "http://www.ebics.org/H002",
              NULL);
  assert(ns);
  ns=xmlNewNs(root_node,
              BAD_CAST "http://www.w3.org/2000/09/xmldsig#",
              BAD_CAST "ds");
  assert(ns);
  ns=xmlNewNs(root_node,
              BAD_CAST "http://www.w3.org/2001/XMLSchema-instance",
              BAD_CAST "xsi");
  xmlNewNsProp(root_node,
               ns,
               BAD_CAST "schemaLocation", /* xsi:schemaLocation */
               BAD_CAST "http://www.ebics.org/H002 "
               "http://www.ebics.org/H002/ebics_keymgmt_request.xsd");
  xmlNewProp(root_node, BAD_CAST "Version", BAD_CAST "H002");
  xmlNewProp(root_node, BAD_CAST "Revision", BAD_CAST "1");

  /* header */
  node=xmlNewChild(root_node, NULL, BAD_CAST "header", NULL);
  xmlNewProp(node, BAD_CAST "authenticate", BAD_CAST "true");
  xmlNewChild(node, NULL, BAD_CAST "static", NULL);
  xmlNewChild(node, NULL, BAD_CAST "mutable", NULL);

  /* body */
  node=xmlNewChild(root_node, NULL, BAD_CAST "body", NULL);

  /* fill */
  s=EBC_User_GetPeerId(u);
  if (s)
    EB_Msg_SetCharValue(msg, "header/static/HostID", s);
  s=AB_User_GetCustomerId(u);
  if (s)
    EB_Msg_SetCharValue(msg, "header/static/PartnerID", s);
  EB_Msg_SetCharValue(msg, "header/static/UserID",
                      AB_User_GetUserId(u));
  EB_Msg_SetCharValue(msg, "header/static/OrderDetails/OrderType", "INI");
  tbuf=GWEN_Buffer_new(0, 16, 0, 1);
  rv=EBC_Provider_Generate_OrderId(pro, tbuf);
  if (rv<0) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Error creating order id (%d)", rv);
    GWEN_Buffer_free(tbuf);
    GWEN_Buffer_free(bufB64);
    EB_Msg_free(msg);
    return rv;
  }
  EB_Msg_SetCharValue(msg, "header/static/OrderDetails/OrderID",
                      GWEN_Buffer_GetStart(tbuf));
  GWEN_Buffer_free(tbuf);
  EB_Msg_SetCharValue(msg,
                      "header/static/OrderDetails/OrderAttribute",
                      "DZNNN");
  EB_Msg_SetCharValue(msg, "header/static/SecurityMedium", "0000");
  EB_Msg_SetCharValue(msg, "body/DataTransfer/OrderData",
                      GWEN_Buffer_GetStart(bufB64));
  GWEN_Buffer_free(bufB64);

  /* exchange requests */
  rv=EBC_Dialog_ExchangeMessages(sess, msg, &mRsp);
  if (rv<0 || rv>=300) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Error exchanging messages (%d)", rv);
    EB_Msg_free(msg);
    return rv;
  }
  EB_Msg_free(msg);

  /* check response */
  assert(mRsp);

  /* log results */
  EBC_Provider_LogRequestResults(pro, mRsp, NULL);

  rc=EB_Msg_GetResultCode(mRsp);
  if ((rc & 0xff0000)==0x090000 ||
      (rc & 0xff0000)==0x060000) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Error response: (%06x)", rc);
    EB_Msg_free(mRsp);
    return AB_ERROR_SECURITY;
  }
  rc=EB_Msg_GetBodyResultCode(mRsp);
  if (rc) {
    if ((rc & 0xff0000)==0x090000 ||
        (rc & 0xff0000)==0x060000) {
      DBG_ERROR(AQEBICS_LOGDOMAIN, "Error response: (%06x)", rc);
      EB_Msg_free(mRsp);
      if ((rc & 0xfff00)==0x091300 ||
          (rc & 0xfff00)==0x091200)
        return AB_ERROR_SECURITY;
      else
        return GWEN_ERROR_GENERIC;
    }
  }

  EB_Msg_free(mRsp);

  /* adjust user status and flags */
  DBG_NOTICE(AQEBICS_LOGDOMAIN, "Adjusting user flags");
  EBC_User_AddFlags(u, EBC_USER_FLAGS_INI);
  if ((EBC_User_GetFlags(u) & (EBC_USER_FLAGS_INI | EBC_USER_FLAGS_HIA))
      ==
      (EBC_USER_FLAGS_INI | EBC_USER_FLAGS_HIA))
    EBC_User_SetStatus(u, EBC_UserStatus_Init2);
  else
    EBC_User_SetStatus(u, EBC_UserStatus_Init1);

  return 0;
}