Exemple #1
0
int GWEN_Padd_PaddWithPkcs1Bt1(GWEN_BUFFER *buf, int dstSize) {
  unsigned int diff;
  char *p;

  if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
    return GWEN_ERROR_INVALID;
  }
  diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
  if (diff<11) {
    /* honour minimum padding length for BT 1 of 8 bytes, plus the
     * leading and the trailing zero and the block type identifier */
    DBG_ERROR(GWEN_LOGDOMAIN,
              "Buffer contains too many bytes (diff is <11)");
    return GWEN_ERROR_INVALID;
  }

  /* reset position to 0 */
  GWEN_Buffer_Rewind(buf);
  if (GWEN_Buffer_InsertRoom(buf, diff)) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
    return GWEN_ERROR_GENERIC;
  }

  p=GWEN_Buffer_GetStart(buf);
  *(p++)=0x00;
  *(p++)=0x01; /* block type 01 */
  if (diff>3) {
    memset(p, 0xff, diff-3);
    p+=diff-3;
  }
  *(p++)=0x00;

  return 0;
}
Exemple #2
0
int GWEN_Padd_UnpaddWithIso9796_2(GWEN_BUFFER *buf) {
  uint32_t l;
  uint32_t realSize;
  const uint8_t *p;

  l=GWEN_Buffer_GetUsedBytes(buf);
  if (l<11) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too few bytes");
    return GWEN_ERROR_INVALID;
  }

  p=(const uint8_t*)GWEN_Buffer_GetStart(buf);
  if (*p!=0x60) {
    DBG_ERROR(GWEN_LOGDOMAIN, "First byte is not a 0x60");
    return GWEN_ERROR_BAD_DATA;
  }
  p++;
  l=0;
  while(*p==0x00) {
    l++;
    p++;
  }
  if (*p!=0x01) {
    /*DBG_ERROR(GWEN_LOGDOMAIN, "First byte after padding is not a 0x01");*/
    return GWEN_ERROR_BAD_DATA;
  }

  realSize=GWEN_Buffer_GetUsedBytes(buf)-11-l;
  GWEN_Buffer_Crop(buf, 10+l, realSize);

  return 0;
}
Exemple #3
0
LC_CLIENT_RESULT LC_EgkCard_ReadRawPd(LC_CARD *card, GWEN_BUFFER *buf){
  LC_EGKCARD *egk;
  LC_CLIENT_RESULT res;
  GWEN_BUFFER *lbuf;
  int size;
  const unsigned char *p;

  assert(card);
  egk=GWEN_INHERIT_GETDATA(LC_CARD, LC_EGKCARD, card);
  assert(egk);

  res=LC_Card_SelectEf(card, "EF_PD");
  if (res!=LC_Client_ResultOk)
    return res;

  lbuf=GWEN_Buffer_new(0, 2, 0, 1);
  res=LC_Card_IsoReadBinary(card, 0, 0, 2, lbuf);
  if (res!=LC_Client_ResultOk) {
    GWEN_Buffer_free(lbuf);
    return res;
  }

  if (GWEN_Buffer_GetUsedBytes(lbuf)<2) {
    DBG_ERROR(LC_LOGDOMAIN, "Invalid response size (%d)",
	      GWEN_Buffer_GetUsedBytes(lbuf));
    GWEN_Buffer_free(lbuf);
    return LC_Client_ResultDataError;
  }

  p=(const unsigned char*)GWEN_Buffer_GetStart(lbuf);
  assert(p);
  size=(*(p++))<<8;
  size+=*p;
  if (size<2) {
    DBG_ERROR(LC_LOGDOMAIN, "Invalid size spec in data (%d)", size);
    GWEN_Buffer_free(lbuf);
    return LC_Client_ResultDataError;
  }
  size-=2;

  GWEN_Buffer_Reset(lbuf);

  if (size) {
    res=LC_Card_ReadBinary(card, 2, size, lbuf);
    if (res!=LC_Client_ResultOk) {
      DBG_INFO(LC_LOGDOMAIN, "here (%d)", res);
      GWEN_Buffer_free(lbuf);
      return res;
    }
  }

  res=LC_EgkCard_Unzip(GWEN_Buffer_GetStart(lbuf),
		       GWEN_Buffer_GetUsedBytes(lbuf),
                       buf);
  GWEN_Buffer_free(lbuf);

  return res;
}
Exemple #4
0
int GWEN_Padd__UnpaddWithPkcs1Bt1Or2(GWEN_BUFFER *buf) {
  char *p;
  uint32_t len;
  uint32_t paddBytes;

  assert(buf);
  len=GWEN_Buffer_GetUsedBytes(buf);
  assert(len);

  p=GWEN_Buffer_GetStart(buf);
  if  (*p==0) {
    p++;
    len--;
  }
  if (len<11) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes left (%d)", len);
    return GWEN_ERROR_INVALID;
  }

  if (*p!=0x01 && *p!=0x02) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Unsupported block type %02x", *p);
    return GWEN_ERROR_INVALID;
  }
  p++;
  len--;

  /* skip padding bytes */
  paddBytes=0;
  while(*p!=0x00 && len) {
    p++;
    len--;
    paddBytes++;
  }

  if (*p!=0x00) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding");
    return GWEN_ERROR_INVALID;
  }
  p++;
  len--;

  if (paddBytes<8) {
    /* at least 8 padding bytes are needed */
    DBG_ERROR(GWEN_LOGDOMAIN, "Bad padding (too few padding bytes)");
    return GWEN_ERROR_INVALID;
  }

  GWEN_Buffer_Crop(buf, GWEN_Buffer_GetUsedBytes(buf)-len, len);

  return 0;
}
Exemple #5
0
int GWEN_CryptMgr_Decode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
  GWEN_BUFFER *tbuf;
  int rv;

  tbuf=GWEN_Buffer_new(0, lData, 0, 1);

  /* decrypt encrypted object */
  DBG_INFO(GWEN_LOGDOMAIN, "Decrypting data");
  rv=GWEN_CryptMgr_Decrypt(cm, pData, lData, tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  /* verify signature, copy signed data to dbuf in the process */
  DBG_INFO(GWEN_LOGDOMAIN, "Verifying data");
  rv=GWEN_CryptMgr_Verify(cm,
                          (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
                          GWEN_Buffer_GetUsedBytes(tbuf),
                          dbuf);
  GWEN_Buffer_free(tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    return rv;
  }

  return 0;
}
Exemple #6
0
LC_CLIENT_RESULT LC_EgkCard_ReadInsuranceData(LC_CARD *card,
					      LC_HI_INSURANCE_DATA **pData) {
  GWEN_BUFFER *dbuf;
  LC_CLIENT_RESULT res;

  dbuf=GWEN_Buffer_new(0, 256, 0, 1);
  res=LC_EgkCard_ReadVd(card, dbuf);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here (%d)", res);
    GWEN_Buffer_free(dbuf);
    return res;
  }
  else {
    GWEN_XMLNODE *root;

    root=GWEN_XMLNode_fromString(GWEN_Buffer_GetStart(dbuf),
				 GWEN_Buffer_GetUsedBytes(dbuf),
				 GWEN_XML_FLAGS_HANDLE_HEADERS |
				 GWEN_XML_FLAGS_HANDLE_NAMESPACES);
    if (root==NULL) {
      DBG_INFO(LC_LOGDOMAIN, "Invalid XML string");
      GWEN_Buffer_free(dbuf);
      return LC_Client_ResultDataError;
    }
    GWEN_Buffer_free(dbuf);

    GWEN_XMLNode_StripNamespaces(root);
    res=LC_EgkCard_ParseInsuranceData(root, pData);

    GWEN_XMLNode_free(root);
    return res;
  }
}
Exemple #7
0
const char *AB_ImExporterContext_GetLog(const AB_IMEXPORTER_CONTEXT *iec) {
  assert(iec);
  if (GWEN_Buffer_GetUsedBytes(iec->logs))
    return GWEN_Buffer_GetStart(iec->logs);
  else
    return NULL;
}
Exemple #8
0
int GWEN_CryptMgr_Encode(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
  GWEN_BUFFER *tbuf;
  int rv;

  tbuf=GWEN_Buffer_new(0, lData, 0, 1);

  /* create signed object */
  DBG_INFO(GWEN_LOGDOMAIN, "Signing data");
  rv=GWEN_CryptMgr_Sign(cm, pData, lData, tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  /* create encrypted object (containing a signed object in this case) */
  DBG_INFO(GWEN_LOGDOMAIN, "Encrypting data");
  rv=GWEN_CryptMgr_Encrypt(cm,
                           (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
                           GWEN_Buffer_GetUsedBytes(tbuf),
                           dbuf);
  GWEN_Buffer_free(tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    return rv;
  }

  return 0;
}
Exemple #9
0
int GWEN_Gui_CProgress_Log(GWEN_GUI_CPROGRESS *cp,
                           GWEN_UNUSED GWEN_LOGGER_LEVEL level,
                           const char *text)
{
  assert(cp);
  assert(text);

  if (!(GWEN_Gui_GetFlags(cp->gui) & GWEN_GUI_FLAGS_NONINTERACTIVE)) {
    GWEN_BUFFER *tbuf;
    const char *t;

    tbuf=GWEN_Buffer_new(0, 256, 0, 1);
    GWEN_Gui_GetRawText(cp->gui, text, tbuf);
    t=GWEN_Buffer_GetStart(tbuf);
    if (t[GWEN_Buffer_GetUsedBytes(tbuf)-1]!='\n') {
      GWEN_Buffer_AppendByte(tbuf, '\n');
      /* Just in case the buffer has been reallocated */
      t=GWEN_Buffer_GetStart(tbuf);
    }
    GWEN_Gui_StdPrintf(cp->gui, stderr, "%s", t);

    GWEN_Buffer_AppendString(cp->logBuf, t);
    GWEN_Buffer_free(tbuf);
    tbuf=0;
    if (cp->aborted)
      return GWEN_ERROR_USER_ABORTED;
  }
  return 0;
}
Exemple #10
0
LC_CLIENT_RESULT LC_DDVCard_CryptBlock(LC_CARD *card,
                                       GWEN_BUFFER *ibuf,
                                       GWEN_BUFFER *obuf){
  return LC_DDVCard_CryptCharBlock(card,
                                   GWEN_Buffer_GetStart(ibuf),
                                   GWEN_Buffer_GetUsedBytes(ibuf),
                                   obuf);
}
Exemple #11
0
int GWEN_Padd_PaddWithIso9796_2(GWEN_BUFFER *buf, int dstSize) {
  unsigned int diff;
  char *p;
  int i;

  if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)+12) {
    /*DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");*/
    return GWEN_ERROR_INVALID;
  }

  /* add trailer */
  GWEN_Buffer_AppendByte(buf, 0xbc);

  /* reset position to 0 */
  GWEN_Buffer_Rewind(buf);

  /* insert room for header */
  diff=dstSize-GWEN_Buffer_GetUsedBytes(buf)-11+1;
  if (GWEN_Buffer_InsertRoom(buf, 1+diff+1+8)) {
    DBG_ERROR(GWEN_LOGDOMAIN,
              "Could not insert room for %d bytes",
              1+diff+1+8);
    return GWEN_ERROR_GENERIC;
  }

  /* insert header and more-data-bit */
  p=GWEN_Buffer_GetStart(buf);
  *(p++)=0x60;

  /* insert padding field */
  for (i=0; i<diff; i++)
    *(p++)=0x0;
  *(p++)=0x01;

  /* insert 8 random bytes */
  GWEN_Crypt_Random(2, (uint8_t*)p, 8);
  for (i=0; i<8; i++) {
    if (*p==0)
      /* TODO: Need to find a better but yet fast way */
      *p=0xff;
    p++;
  }

  return 0;
}
Exemple #12
0
int GWEN_Padd_PaddWithAnsiX9_23ToMultipleOf(GWEN_BUFFER *src, int y) {
  unsigned char paddLength;
  unsigned int i;

  paddLength=y-(GWEN_Buffer_GetUsedBytes(src) % y);
  for (i=0; i<paddLength; i++)
    GWEN_Buffer_AppendByte(src, paddLength);
  return 0;
}
Exemple #13
0
int GWEN_Padd_UnpaddWithAnsiX9_23FromMultipleOf(GWEN_BUFFER *src, int y) {
  const char *p;
  unsigned int lastpos;
  unsigned char paddLength;

  lastpos=GWEN_Buffer_GetUsedBytes(src);
  if (lastpos<y) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Buffer too small");
    return -1;
  }
  lastpos--;

  p=GWEN_Buffer_GetStart(src)+lastpos;
  paddLength=*p;
  if (paddLength<1 || paddLength>y) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Invalid padding (%d bytes ?)", paddLength);
    return -1;
  }
  GWEN_Buffer_Crop(src, 0, GWEN_Buffer_GetUsedBytes(src)-paddLength);
  GWEN_Buffer_SetPos(src, lastpos-paddLength);
  return 0;
}
Exemple #14
0
int GWEN_Padd_PaddWithPkcs1Bt2(GWEN_BUFFER *buf, int dstSize) {
  unsigned int diff;
  char *p;
  int i;

  if ((unsigned int)dstSize<GWEN_Buffer_GetUsedBytes(buf)) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Buffer contains too much data");
    return GWEN_ERROR_INVALID;
  }
  diff=dstSize-GWEN_Buffer_GetUsedBytes(buf);
  if (diff<11) {
    /* honour minimum padding length for BT 1 of 8 bytes, plus the
     * leading and the trailing zero and the block type identifier */
    DBG_ERROR(GWEN_LOGDOMAIN,
              "Buffer contains too many bytes (diff is <11)");
    return GWEN_ERROR_INVALID;
  }

  /* reset position to 0 */
  GWEN_Buffer_Rewind(buf);
  if (GWEN_Buffer_InsertRoom(buf, diff)) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Could not insert room for %d bytes", diff);
    return GWEN_ERROR_GENERIC;
  }

  p=GWEN_Buffer_GetStart(buf);
  *(p++)=0x00;
  *(p++)=0x02; /* block type 02 */
  GWEN_Crypt_Random(2, (uint8_t*)p, diff-3);
  for (i=0; i<diff-3; i++) {
    if (*p==0)
      /* TODO: Need to find a better but yet fast way */
      *p=0xff;
    p++;
  }
  *(p++)=0x00;

  return 0;
}
Exemple #15
0
int AO_Provider__WrapRequest(AB_PROVIDER *pro,
                             AB_USER *u,
			     const char *mTypeName,
			     const char *tTypeName,
			     GWEN_BUFFER *buf) {
  GWEN_BUFFER *tbuf;
  GWEN_TIME *ti;

  tbuf=GWEN_Buffer_new(0, 512, 0, 1);

  /* begin: msg wrapper */
  GWEN_Buffer_AppendString(tbuf, "<");
  GWEN_Buffer_AppendString(tbuf, mTypeName);
  GWEN_Buffer_AppendString(tbuf, "MSGSRQV1>");

  /* begin: transaction wrapper */
  GWEN_Buffer_AppendString(tbuf, "<");
  GWEN_Buffer_AppendString(tbuf, tTypeName);
  GWEN_Buffer_AppendString(tbuf, "TRNRQ>");
  ti=GWEN_CurrentTime();
  assert(ti);
  GWEN_Buffer_AppendString(tbuf, "<TRNUID>");
  if (AO_User_GetFlags(u) & AO_USER_FLAGS_SEND_SHORT_DATE)
    GWEN_Time_toString(ti, "YYYYMMDDhhmmss", tbuf);
  else
    GWEN_Time_toString(ti, "YYYYMMDDhhmmss.000", tbuf);
  GWEN_Buffer_AppendString(tbuf, "<CLTCOOKIE>1");

  /* append ends of elements to original buffer */
  GWEN_Buffer_AppendString(buf, "</");
  GWEN_Buffer_AppendString(buf, tTypeName);
  GWEN_Buffer_AppendString(buf, "TRNRQ>");

  GWEN_Buffer_AppendString(buf, "</");
  GWEN_Buffer_AppendString(buf, mTypeName);
  GWEN_Buffer_AppendString(buf, "MSGSRQV1>");

  /* go to start of buffer and insert leading elements there */
  GWEN_Buffer_SetPos(buf, 0);
  GWEN_Buffer_InsertBuffer(buf, tbuf);

  /* point to end of buffer */
  GWEN_Buffer_SetPos(buf, GWEN_Buffer_GetUsedBytes(buf));

  /* cleanup */
  GWEN_Time_free(ti);
  GWEN_Buffer_free(tbuf);

  return 0;
}
Exemple #16
0
GWENHYWFAR_CB
int GWEN_CryptMgrKeys_EncryptKey(GWEN_CRYPTMGR *cm,
                                 const uint8_t *pData, uint32_t lData,
                                 GWEN_BUFFER *dbuf) {
  GWEN_CRYPTMGR_KEYS *xcm;
  int rv;
  GWEN_BUFFER *tbuf;
  int ksize;
  uint32_t l;

  assert(cm);
  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
  assert(xcm);

  if (xcm->peerKey==NULL) {
    DBG_ERROR(GWEN_LOGDOMAIN, "No peer key");
    return GWEN_ERROR_GENERIC;
  }

  ksize=GWEN_Crypt_Key_GetKeySize(xcm->peerKey);

  /* padd key data */
  tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
  GWEN_Buffer_AppendBytes(tbuf, (const char*) pData, lData);
  rv=GWEN_Padd_PaddWithIso9796_2(tbuf, ksize);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  GWEN_Buffer_AllocRoom(dbuf, ksize);
  l=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf);
  rv=GWEN_Crypt_Key_Encipher(xcm->peerKey,
                             (const uint8_t*)GWEN_Buffer_GetStart(tbuf),
                             GWEN_Buffer_GetUsedBytes(tbuf),
                             (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf),
                             &l);
  GWEN_Buffer_free(tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    return rv;
  }

  GWEN_Buffer_IncrementPos(dbuf, l);
  GWEN_Buffer_AdjustUsedBytes(dbuf);

  return 0;
}
Exemple #17
0
int HtmlGroup_Box_AddData(HTML_GROUP *g, const char *data)
{
  GWEN_XML_CONTEXT *ctx;
  GWEN_BUFFER *buf;
  int rv;
  uint8_t *s;
  HTML_OBJECT *o;

  assert(g);

  ctx=HtmlGroup_GetXmlContext(g);
  if (data && *data) {
    buf=GWEN_Buffer_new(0, strlen(data), 0, 1);
    rv=HtmlCtx_SanitizeData(ctx, data, buf);
    if (rv<0) {
      DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
      GWEN_Buffer_free(buf);
      return rv;
    }
    if (GWEN_Buffer_GetUsedBytes(buf)) {
      s=(uint8_t *)GWEN_Buffer_GetStart(buf);

      while (*s) {
        uint8_t *t;
        uint8_t c;

        /* find begin of word */
        while (*s && isspace(*s))
          s++;

        /* find end of word */
        t=s;
        while (*t && !isspace(*t))
          t++;
        c=*t;
        *t=0;
        o=HtmlObject_Word_new(ctx, (const char *) s);
        HtmlObject_SetProperties(o, HtmlGroup_GetProperties(g));
        HtmlObject_Tree_AddChild(HtmlGroup_GetObject(g), o);
        *t=c;
        s=t;
      }
    }
    GWEN_Buffer_free(buf);
  }

  return 0;
}
Exemple #18
0
LC_CLIENT_RESULT LC_DDVCard_WriteInstituteData(LC_CARD *card,
                                               int idx,
                                               GWEN_DB_NODE *dbData){
  LC_DDVCARD *ddv;
  LC_CLIENT_RESULT res;
  GWEN_BUFFER *buf;

  assert(card);
  ddv=GWEN_INHERIT_GETDATA(LC_CARD, LC_DDVCARD, card);
  assert(ddv);

  if (idx==0) {
    DBG_ERROR(LC_LOGDOMAIN, "Invalid index 0");
    return LC_Client_ResultInvalid;
  }

  /* select EF_BNK */
  res=LC_Card_SelectEf(card, "EF_BNK");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  /* create record data */
  buf=GWEN_Buffer_new(0, 256, 0, 1);
  if (LC_Card_CreateRecord(card, idx, buf, dbData)) {
    DBG_ERROR(LC_LOGDOMAIN, "Error creating record %d", idx);
    GWEN_Buffer_free(buf);
    return LC_Client_ResultDataError;
  }
  GWEN_Buffer_Rewind(buf);

  /* write record */
  res=LC_Card_IsoUpdateRecord(card, LC_CARD_ISO_FLAGS_RECSEL_GIVEN, idx,
                              GWEN_Buffer_GetStart(buf),
                              GWEN_Buffer_GetUsedBytes(buf));
  GWEN_Buffer_free(buf);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  return LC_Client_ResultOk;
}
Exemple #19
0
int GWEN_XML__ReadData(GWEN_XML_CONTEXT *ctx,
                       GWEN_FAST_BUFFER *fb,
                       GWEN_UNUSED uint32_t flags) {
  int chr;
  unsigned char uc;
  GWEN_BUFFER *dbuf;

  dbuf=GWEN_Buffer_new(0, 256, 0, 1);

  for (;;) {
    GWEN_FASTBUFFER_PEEKBYTE(fb, chr);
    if (chr<0) {
      if (chr==GWEN_ERROR_EOF)
        break;
      else {
        GWEN_Buffer_free(dbuf);
        return chr;
      }
    }

    uc=(unsigned char) chr;
    if (uc=='<')
      break;
    fb->bufferReadPos++;
    GWEN_Buffer_AppendByte(dbuf, uc);
  }

  if (GWEN_Buffer_GetUsedBytes(dbuf)) {
    int rv;
    const char *s;

    s=GWEN_Buffer_GetStart(dbuf);
    if (*s) {
      rv=GWEN_XmlCtx_AddData(ctx, s);
      if (rv) {
        GWEN_Buffer_free(dbuf);
        return rv;
      }
    }
  }
  GWEN_Buffer_free(dbuf);

  return 0;
}
Exemple #20
0
int AO_Provider__WrapMessage(AB_PROVIDER *pro,
                             AB_USER *u,
			     GWEN_BUFFER *buf) {
  GWEN_BUFFER *tbuf;
  int rv;

  tbuf=GWEN_Buffer_new(0, 1024, 0, 1);

  /* add headers and "<OFX>" */
  rv=AO_Provider__AddHeaders(pro, u, tbuf);
  if (rv<0) {
    DBG_ERROR(AQOFXCONNECT_LOGDOMAIN,
	      "Error adding headers (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  GWEN_Buffer_AppendString(tbuf, "<OFX>");

  rv=AO_Provider__AddSignOn(pro, u, tbuf);
  if (rv<0) {
    DBG_ERROR(AQOFXCONNECT_LOGDOMAIN,
	      "Error adding signon element (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  /* append end of OFX element to original buffer */
  GWEN_Buffer_AppendString(buf, "</OFX>");

  /* go to start of buffer and insert leading elements there */
  GWEN_Buffer_SetPos(buf, 0);
  GWEN_Buffer_InsertBuffer(buf, tbuf);

  /* point to end of buffer */
  GWEN_Buffer_SetPos(buf, GWEN_Buffer_GetUsedBytes(buf));

  /* cleanup */
  GWEN_Buffer_free(tbuf);

  return 0;
}
Exemple #21
0
int AIO_OfxXmlCtx_SanitizeData(GWEN_XML_CONTEXT *ctx,
			       const char *data,
			       GWEN_BUFFER *buf) {
  AIO_OFX_XMLCTX *xctx;

  assert(ctx);
  xctx=GWEN_INHERIT_GETDATA(GWEN_XML_CONTEXT, AIO_OFX_XMLCTX, ctx);
  assert(xctx);

  if (xctx->charset) {
    GWEN_BUFFER *tbuf;
    int rv;

    tbuf=GWEN_Buffer_new(0, 256, 0, 1);
    rv=AIO_OfxXmlCtx_CleanupData(ctx, data, tbuf);
    if (rv<0) {
      DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
      GWEN_Buffer_free(tbuf);
      return rv;
    }

    rv=GWEN_Text_ConvertCharset(xctx->charset, "UTF-8",
				GWEN_Buffer_GetStart(tbuf),
				GWEN_Buffer_GetUsedBytes(tbuf),
				buf);
    if (rv<0) {
      DBG_INFO(AQBANKING_LOGDOMAIN, "here (%d)", rv);
      GWEN_Buffer_free(tbuf);
      return rv;
    }
    GWEN_Buffer_free(tbuf);
    return 0;
  }
  else
    return AIO_OfxXmlCtx_CleanupData(ctx, data, buf);
}
Exemple #22
0
void GWEN_DBIO__XmlDb_ReadDataTags(GWEN_XMLNODE *node, GWEN_BUFFER *buf) {
  GWEN_XMLNODE *ndata;
  GWEN_BUFFER *tbuf;
  int rv;

  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
  ndata=GWEN_XMLNode_GetFirstData(node);
  while(ndata) {
    const char *s;

    s=GWEN_XMLNode_GetData(ndata);
    if (s) {
      if (GWEN_Buffer_GetUsedBytes(tbuf))
	GWEN_Buffer_AppendByte(tbuf, ' ');
      GWEN_Buffer_AppendString(tbuf, s);
    }
    ndata=GWEN_XMLNode_GetNextData(node);
  }
  rv=GWEN_Text_UnescapeXmlToBuffer(GWEN_Buffer_GetStart(tbuf), buf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
  }
  GWEN_Buffer_free(tbuf);
}
Exemple #23
0
int EBC_Provider_XchgHpdRequest(AB_PROVIDER *pro,
				GWEN_HTTP_SESSION *sess,
				AB_USER *u) {
  int rv;
  GWEN_BUFFER *buf;

  buf=GWEN_Buffer_new(0, 1024, 0, 1);
  rv=EBC_Provider_XchgDownloadRequest(pro, sess, u, "HPD", buf, 0, NULL, NULL);
  if (rv<0 || rv>=300) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(buf);
    return rv;
  }
  else {
    xmlDocPtr orderDoc=NULL;
    xmlNodePtr root_node=NULL;
    xmlNodePtr node=NULL;
    xmlNodePtr nodeX=NULL;
    const char *s;
    uint32_t uflags=0;

    /* parse XML document */
    rv=EB_Xml_DocFromBuffer(GWEN_Buffer_GetStart(buf),
			    GWEN_Buffer_GetUsedBytes(buf),
			    &orderDoc);
    GWEN_Buffer_free(buf);
    if (rv<0) {
      DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
      return rv;
    }

    /* get keys */
    root_node=xmlDocGetRootElement(orderDoc);

    /* get auth key */
    node=EB_Xml_GetNode(root_node, "ProtocolParams",
			GWEN_PATH_FLAGS_NAMEMUSTEXIST);
    if (node==NULL) {
      DBG_ERROR(AQEBICS_LOGDOMAIN,
		"No ProtocolParams found");
      xmlFreeDoc(orderDoc);
      return GWEN_ERROR_BAD_DATA;
    }
    nodeX=EB_Xml_GetNode(node, "ClientDataDownload",
			 GWEN_PATH_FLAGS_NAMEMUSTEXIST);
    if (nodeX) {
      s=(const char*)xmlGetProp(nodeX, BAD_CAST "supported");
      if (s && strcasecmp(s, "true")==0) {
        DBG_INFO(AQEBICS_LOGDOMAIN, "Client data download supported");
	uflags|=EBC_USER_FLAGS_CLIENT_DATA_DOWNLOAD_SPP;
      }
    }

    nodeX=EB_Xml_GetNode(node, "PreValidation",
			 GWEN_PATH_FLAGS_NAMEMUSTEXIST);
    if (nodeX) {
      s=(const char*)xmlGetProp(nodeX, BAD_CAST "supported");
      if (s && strcasecmp(s, "true")==0) {
	DBG_INFO(AQEBICS_LOGDOMAIN, "Prevalidation supported");
	uflags|=EBC_USER_FLAGS_PREVALIDATION_SPP;
      }
    }

    nodeX=EB_Xml_GetNode(node, "Recovery",
			 GWEN_PATH_FLAGS_NAMEMUSTEXIST);
    if (nodeX) {
      s=(const char*)xmlGetProp(nodeX, BAD_CAST "supported");
      if (s && strcasecmp(s, "true")==0) {
	DBG_INFO(AQEBICS_LOGDOMAIN, "Recovery supported");
	uflags|=EBC_USER_FLAGS_RECOVERY_SPP;
      }
    }

    EBC_User_AddFlags(u, uflags);

    xmlFreeDoc(orderDoc);
    return 0;
  }


}
Exemple #24
0
int addUser(AB_PROVIDER *pro,
            GWEN_DB_NODE *dbArgs,
            int argc,
            char **argv)
{
  GWEN_DB_NODE *db;
  int rv;
  GWEN_BUFFER *nameBuffer=NULL;
  const char *tokenName;
  const char *tokenType;
  const char *bankId;
  const char *userId;
  const char *customerId;
  const char *userName;
  const char *hostName;
  const char *server;
  const char *ebicsVersion;
  int importing;
  uint32_t cid;
  const GWEN_ARGS args[]= {
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "bankId",                     /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      "b",                          /* short option */
      "bank",                       /* long option */
      "Specify the bank code",      /* short description */
      "Specify the bank code"       /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "userId",                     /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      "u",                          /* short option */
      "user",                       /* long option */
      "Specify the user id (Benutzerkennung)",        /* short description */
      "Specify the user id (Benutzerkennung)"         /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "customerId",                 /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      "c",                          /* short option */
      "customer",                   /* long option */
      "Specify the customer id (Kundennummer)",    /* short description */
      "Specify the customer id (Kundennummer)"     /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "tokenType",                  /* name */
      1,                            /* minnum */
      1,                            /* maxnum */
      "t",                          /* short option */
      "tokentype",                  /* long option */
      "Specify the crypt token type", /* short description */
      "Specify the crypt token type"  /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "tokenName",                  /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      "n",                          /* short option */
      "tokenname",                  /* long option */
      "Specify the crypt token name", /* short description */
      "Specify the crypt token name"  /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "serverAddr",                 /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      "s",                          /* short option */
      "server",                     /* long option */
      "Specify the server URL",     /* short description */
      "Specify the server URL"      /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "hostName",                 /* name */
      1,                            /* minnum */
      1,                            /* maxnum */
      "H",                          /* short option */
      "hostname",                     /* long option */
      "Specify the EBICS hostname",     /* short description */
      "Specify the EBICS hostname"      /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "userName",                 /* name */
      1,                            /* minnum */
      1,                            /* maxnum */
      "N",                          /* short option */
      "username",                     /* long option */
      "Specify the realname of the user",     /* short description */
      "Specify the realname of the user"      /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Char,           /* type */
      "ebicsVersion",                /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      "E",                          /* short option */
      "ebicsversion",               /* long option */
      "Specify the EBICS version to use (e.g. H002)",     /* short description */
      "Specify the EBICS version to use (e.g. H002)"      /* long description */
    },
    {
      GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
      GWEN_ArgsType_Int,            /* type */
      "context",                    /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      0,                            /* short option */
      "context",                    /* long option */
      "Select a context on the medium", /* short description */
      "Select a context on the medium"  /* long description */
    },
    {
      0,                            /* flags */
      GWEN_ArgsType_Int,            /* type */
      "import",                     /* name */
      0,                            /* minnum */
      1,                            /* maxnum */
      0,                            /* short option */
      "import",                     /* long option */
      "Import a user which has already been in use (e.g. with previous versions)",
      "Import a user which has already been in use (e.g. with previous versions)"
    },
    {
      GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
      GWEN_ArgsType_Int,            /* type */
      "help",                       /* name */
      0,                            /* minnum */
      0,                            /* maxnum */
      "h",                          /* short option */
      "help",                       /* long option */
      "Show this help screen",      /* short description */
      "Show this help screen"       /* long description */
    }
  };

  db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
  rv=GWEN_Args_Check(argc, argv, 1,
                     0 /*GWEN_ARGS_MODE_ALLOW_FREEPARAM*/,
                     args,
                     db);
  if (rv==GWEN_ARGS_RESULT_ERROR) {
    fprintf(stderr, "ERROR: Could not parse arguments\n");
    return 1;
  }
  else if (rv==GWEN_ARGS_RESULT_HELP) {
    GWEN_BUFFER *ubuf;

    ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
    if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
      fprintf(stderr, "ERROR: Could not create help string\n");
      return 1;
    }
    fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf));
    GWEN_Buffer_free(ubuf);
    return 0;
  }

  tokenType=GWEN_DB_GetCharValue(db, "tokenType", 0, 0);
  tokenName=GWEN_DB_GetCharValue(db, "tokenName", 0, 0);
  bankId=GWEN_DB_GetCharValue(db, "bankId", 0, 0);
  userId=GWEN_DB_GetCharValue(db, "userId", 0, 0);
  customerId=GWEN_DB_GetCharValue(db, "customerId", 0, 0);
  hostName=GWEN_DB_GetCharValue(db, "hostName", 0, 0);
  userName=GWEN_DB_GetCharValue(db, "userName", 0, 0);
  server=GWEN_DB_GetCharValue(db, "serverAddr", 0, 0);
  cid=GWEN_DB_GetIntValue(db, "context", 0, 0);
  importing=GWEN_DB_GetIntValue(db, "import", 0, 0);
  ebicsVersion=GWEN_DB_GetCharValue(db, "ebicsVersion", 0, "H003");

  if (1) {
    const char *lbankId;
    const char *luserId;
    const char *lcustomerId;
    const char *lserverAddr;
    GWEN_URL *url;
    GWEN_CRYPT_TOKEN_CONTEXT *ctx=NULL;
    AB_USER *user;

    if (1) {
      GWEN_PLUGIN_MANAGER *pm;
      GWEN_PLUGIN *pl;
      GWEN_CRYPT_TOKEN *ct;
      const GWEN_CRYPT_TOKEN_CONTEXT *cctx;

      if (cid==0) {
        DBG_ERROR(0, "No context given.");
        return 1;
      }

      /* get crypt token */
      pm=GWEN_PluginManager_FindPluginManager("ct");
      if (pm==0) {
        DBG_ERROR(0, "Plugin manager not found");
        return 3;
      }

      pl=GWEN_PluginManager_GetPlugin(pm, tokenType);
      if (pl==0) {
        DBG_ERROR(0, "Plugin not found");
        return 3;
      }
      DBG_INFO(0, "Plugin found");

      ct=GWEN_Crypt_Token_Plugin_CreateToken(pl, tokenName);
      if (ct==0) {
        DBG_ERROR(0, "Could not create crypt token");
        return 3;
      }

      /* open crypt token */
      rv=GWEN_Crypt_Token_Open(ct, 0, 0);
      if (rv) {
        DBG_ERROR(0, "Could not open token (%d)", rv);
        return 3;
      }

      /* get real token name */
      nameBuffer=GWEN_Buffer_new(0, 64, 0, 1);
      GWEN_Buffer_AppendString(nameBuffer, GWEN_Crypt_Token_GetTokenName(ct));
      tokenName=GWEN_Buffer_GetStart(nameBuffer);

      cctx=GWEN_Crypt_Token_GetContext(ct, cid, 0);
      if (cctx==NULL) {
        DBG_ERROR(0, "Context %02x not found", cid);
        return 3;
      }
      ctx=GWEN_Crypt_Token_Context_dup(cctx);
      lbankId=bankId?bankId:GWEN_Crypt_Token_Context_GetServiceId(ctx);

      luserId=userId?userId:GWEN_Crypt_Token_Context_GetUserId(ctx);
      lcustomerId=customerId?customerId:luserId;

      lserverAddr=server?server:GWEN_Crypt_Token_Context_GetAddress(ctx);

      rv=GWEN_Crypt_Token_Close(ct, 0, 0);
      if (rv) {
        DBG_ERROR(0, "Could not close token (%d)", rv);
        return 3;
      }

      GWEN_Crypt_Token_free(ct);
    }

    if (!lbankId || !*lbankId) {
      DBG_ERROR(0, "No bank id stored and none given");
      return 3;
    }
    if (!luserId || !*luserId) {
      DBG_ERROR(0, "No user id (Benutzerkennung) stored and none given");
      return 3;
    }

    /* TODO: Check for existing users to avoid duplicates */
#if 0
    user=AB_Banking_FindUser(ab, EBC_PROVIDER_NAME,
                             "de",
                             lbankId, luserId, lcustomerId);
    if (user) {
      DBG_ERROR(0, "User %s already exists", luserId);
      return 3;
    }
#endif

    user=AB_Provider_CreateUserObject(pro);
    assert(user);

    AB_User_SetCountry(user, "de");
    AB_User_SetBankCode(user, lbankId);
    AB_User_SetUserId(user, luserId);
    AB_User_SetCustomerId(user, lcustomerId);
    EBC_User_SetPeerId(user, hostName);
    AB_User_SetUserName(user, userName);
    EBC_User_SetTokenType(user, tokenType);
    EBC_User_SetTokenName(user, tokenName);
    EBC_User_SetTokenContextId(user, cid);
    if (ebicsVersion) {
      if (strcasecmp(ebicsVersion, "H002")==0) {
        EBC_User_SetProtoVersion(user, "H002");
        EBC_User_SetSignVersion(user, "A004");
        EBC_User_SetAuthVersion(user, "X001");
        EBC_User_SetCryptVersion(user, "E001");
      }
      else if (strcasecmp(ebicsVersion, "H003")==0) {
        EBC_User_SetProtoVersion(user, "H003");
        EBC_User_SetSignVersion(user, "A005");
        EBC_User_SetAuthVersion(user, "X002");
        EBC_User_SetCryptVersion(user, "E002");
      }
      else if (strcasecmp(ebicsVersion, "H004")==0) {
        EBC_User_SetProtoVersion(user, "H004");
        EBC_User_SetSignVersion(user, "A005");
        EBC_User_SetAuthVersion(user, "X002");
        EBC_User_SetCryptVersion(user, "E002");
      }
      else {
        fprintf(stderr, "%s",
                I18N("Invalid protocol version.\n"
                     "Possible versions are H002, H003 and H004.\n"));
        return 3;
      }
    }

    /* try to get server address from database if still unknown */
    if (!lserverAddr || *lserverAddr==0) {
      GWEN_BUFFER *tbuf;

      tbuf=GWEN_Buffer_new(0, 256, 0, 1);
      if (getBankUrl(AB_Provider_GetBanking(pro), lbankId, tbuf)) {
        DBG_INFO(0, "Could not find server address for \"%s\"", lbankId);
      }
      if (GWEN_Buffer_GetUsedBytes(tbuf)==0) {
        DBG_ERROR(0, "No address given and none available in internal db");
        return 3;
      }
      url=GWEN_Url_fromString(GWEN_Buffer_GetStart(tbuf));
      if (url==NULL) {
        DBG_ERROR(0, "Bad URL \"%s\" in internal db",
                  GWEN_Buffer_GetStart(tbuf));
        return 3;
      }
      GWEN_Buffer_free(tbuf);
    }
    else {
      /* set address */
      url=GWEN_Url_fromString(lserverAddr);
      if (url==NULL) {
        DBG_ERROR(0, "Bad URL \"%s\"", lserverAddr);
        return 3;
      }
    }

    GWEN_Url_SetProtocol(url, "https");
    if (GWEN_Url_GetPort(url)==0)
      GWEN_Url_SetPort(url, 443);

    /* set url */
    if (1) {
      GWEN_BUFFER *tbuf;

      tbuf=GWEN_Buffer_new(0, 256, 0, 1);
      rv=GWEN_Url_toString(url, tbuf);
      if (rv<0) {
        DBG_ERROR(0, "Internal error storing URL");
        return 3;
      }
      EBC_User_SetServerUrl(user, GWEN_Buffer_GetStart(tbuf));
      GWEN_Buffer_free(tbuf);
    }
    GWEN_Url_free(url);

    if (importing) {
      EBC_User_AddFlags(user, EBC_USER_FLAGS_INI | EBC_USER_FLAGS_HIA);
      EBC_User_SetStatus(user, EBC_UserStatus_Enabled);
    }

    rv=AB_Provider_AddUser(pro, user);
    if (rv<0) {
      DBG_ERROR(AQEBICS_LOGDOMAIN, "Coud not add new user (%d)", rv);
      AB_User_free(user);
      return 4;
    }
    AB_User_free(user);

    /* context no longer needed */
    GWEN_Crypt_Token_Context_free(ctx);
  }

  return 0;
}
Exemple #25
0
LC_CLIENT_RESULT LC_ZkaCard_Reopen(LC_CARD *card) {
  LC_CLIENT_RESULT res;
  LC_ZKACARD *xc;
  GWEN_BUFFER *mbuf;

  DBG_INFO(LC_LOGDOMAIN, "Opening ZkaCard card");

  assert(card);
  xc=GWEN_INHERIT_GETDATA(LC_CARD, LC_ZKACARD, card);
  assert(xc);

  LC_Card_SetLastResult(card, 0, 0, 0, 0);
  GWEN_Buffer_free(xc->bin_ef_gd_0);
  xc->bin_ef_gd_0=NULL;

  GWEN_Buffer_free(xc->bin_ef_id);
  xc->bin_ef_id=NULL;

  GWEN_Buffer_free(xc->bin_ef_ssd);
  xc->bin_ef_ssd=NULL;

  res=LC_Card_SelectCard(card, "zkacard");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  /* first select generic app for all ZKACARD HBCI cards */
  res=LC_Card_SelectApp(card, "zkacard");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  DBG_INFO(LC_LOGDOMAIN, "Selecting MF...");
  res=LC_Card_SelectMf(card);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  /* read EF_ID */
  DBG_INFO(LC_LOGDOMAIN, "Selecting EF_ID...");
  res=LC_Card_SelectEf(card, "EF_ID");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  DBG_INFO(LC_LOGDOMAIN, "Reading record...");
  mbuf=GWEN_Buffer_new(0, 32, 0, 1);
  res=LC_Card_IsoReadRecord(card, LC_CARD_ISO_FLAGS_RECSEL_GIVEN, 1, mbuf);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    GWEN_Buffer_free(mbuf);
    return res;
  }
  xc->bin_ef_id=mbuf;


  /* read EG_GD0 */
  DBG_INFO(LC_LOGDOMAIN, "Selecting EF_GD0...");
  res=LC_Card_SelectEf(card, "EF_GD0");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  DBG_INFO(LC_LOGDOMAIN, "Reading data...");
  mbuf=GWEN_Buffer_new(0, 16, 0, 1);
  res=LC_Card_IsoReadBinary(card, 0, 0, 12, mbuf);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    GWEN_Buffer_free(mbuf);
    return res;
  }
  if (GWEN_Buffer_GetUsedBytes(mbuf)<12) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    GWEN_Buffer_free(mbuf);
    return LC_Client_ResultDataError;
  }
  xc->bin_ef_gd_0=mbuf;


  /* select DF_SIG */
  DBG_INFO(LC_LOGDOMAIN, "Selecting DF_SIG...");
  res=LC_Card_SelectDf(card, "DF_SIG");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  /* read EG_SSD */
  DBG_INFO(LC_LOGDOMAIN, "Selecting EF_SSD...");
  res=LC_Card_SelectEf(card, "EF_SSD");
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here");
    return res;
  }

  DBG_INFO(LC_LOGDOMAIN, "Reading data...");
  mbuf=GWEN_Buffer_new(0, 16, 0, 1);
  res=LC_Card_ReadBinary(card, 0, 65535, mbuf);
  if (res!=LC_Client_ResultOk) {
    DBG_INFO(LC_LOGDOMAIN, "here (%d)", res);
    GWEN_Buffer_free(mbuf);
    return res;
  }
  xc->bin_ef_ssd=mbuf;



  return LC_Client_ResultOk;
}
Exemple #26
0
GWENHYWFAR_CB
int GWEN_CryptMgrKeys_VerifyData(GWEN_CRYPTMGR *cm,
                                 const uint8_t *pData, uint32_t lData,
                                 const uint8_t *pSignature, uint32_t lSignature) {
  GWEN_CRYPTMGR_KEYS *xcm;
  GWEN_MDIGEST *md;
  int rv;
  GWEN_BUFFER *tbuf;
  int ksize;
  uint32_t l;

  assert(cm);
  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
  assert(xcm);

  if (xcm->peerKey==NULL) {
    DBG_ERROR(GWEN_LOGDOMAIN, "No peer key");
    return GWEN_ERROR_GENERIC;
  }

  ksize=GWEN_Crypt_Key_GetKeySize(xcm->peerKey);

  /* the padding algo uses random numbers, so we must use the encrypt function and
   * compare the decoded and unpadded signature with the hash of the source data
   */
  tbuf=GWEN_Buffer_new(0, ksize+16, 0, 1);
  l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
  rv=GWEN_Crypt_Key_Encipher(xcm->peerKey,
                             pSignature, lSignature,
                             (uint8_t*)GWEN_Buffer_GetPosPointer(tbuf),
                             &l);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  GWEN_Buffer_IncrementPos(tbuf, l);
  GWEN_Buffer_AdjustUsedBytes(tbuf);

  /* unpadd */
  rv=GWEN_Padd_UnpaddWithIso9796_2(tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  /* tbuf now contains the hash */

  /* hash source data */
  md=GWEN_MDigest_Rmd160_new();
  rv=GWEN_MDigest_Begin(md);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_MDigest_free(md);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  rv=GWEN_MDigest_Update(md, pData, lData);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_MDigest_free(md);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  rv=GWEN_MDigest_End(md);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_MDigest_free(md);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  if (GWEN_MDigest_GetDigestSize(md)!=GWEN_Buffer_GetUsedBytes(tbuf)) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature");
    GWEN_MDigest_free(md);
    GWEN_Buffer_free(tbuf);
    return GWEN_ERROR_VERIFY;
  }

  if (memcmp(GWEN_MDigest_GetDigestPtr(md),
             GWEN_Buffer_GetStart(tbuf),
             GWEN_MDigest_GetDigestSize(md))!=0) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Invalid signature");
    GWEN_MDigest_free(md);
    GWEN_Buffer_free(tbuf);
    return GWEN_ERROR_VERIFY;
  }

  GWEN_MDigest_free(md);
  GWEN_Buffer_free(tbuf);

  return 0;
}
Exemple #27
0
GWENHYWFAR_CB
int GWEN_CryptMgrKeys_SignData(GWEN_CRYPTMGR *cm,
                               const uint8_t *pData, uint32_t lData,
                               GWEN_BUFFER *dbuf) {
  GWEN_CRYPTMGR_KEYS *xcm;
  GWEN_MDIGEST *md;
  int rv;
  GWEN_BUFFER *tbuf;
  int ksize;
  uint32_t signatureLen;

  assert(cm);
  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
  assert(xcm);

  if (xcm->localKey==NULL) {
    DBG_ERROR(GWEN_LOGDOMAIN, "No local key");
    return GWEN_ERROR_GENERIC;
  }

  ksize=GWEN_Crypt_Key_GetKeySize(xcm->localKey);

  /* hash pData */
  md=GWEN_MDigest_Rmd160_new();
  rv=GWEN_MDigest_Begin(md);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_MDigest_free(md);
    return rv;
  }
  rv=GWEN_MDigest_Update(md, pData, lData);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_MDigest_free(md);
    return rv;
  }
  rv=GWEN_MDigest_End(md);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_MDigest_free(md);
    return rv;
  }

  /* padd */
  tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
  GWEN_Buffer_AppendBytes(tbuf,
                          (const char*)GWEN_MDigest_GetDigestPtr(md),
                          GWEN_MDigest_GetDigestSize(md));
  GWEN_MDigest_free(md);
  GWEN_Padd_PaddWithIso9796_2(tbuf, ksize);

  /* sign */
  GWEN_Buffer_AllocRoom(dbuf, ksize);
  signatureLen=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf);
  rv=GWEN_Crypt_Key_Sign(xcm->localKey,
                         (uint8_t*)GWEN_Buffer_GetStart(tbuf),
                         GWEN_Buffer_GetUsedBytes(tbuf),
                         (uint8_t*)GWEN_Buffer_GetPosPointer(dbuf),
                         &signatureLen);
  GWEN_Buffer_free(tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    return rv;
  }

  GWEN_Buffer_IncrementPos(dbuf, signatureLen);
  GWEN_Buffer_AdjustUsedBytes(dbuf);

  return 0;
}
int AH_Msg_EncryptPinTan(AH_MSG *hmsg) {
  AH_HBCI *h;
  GWEN_XMLNODE *node;
  GWEN_DB_NODE *cfg;
  GWEN_BUFFER *hbuf;
  int rv;
  const char *p;
  GWEN_MSGENGINE *e;
  AB_USER *u;
  const char *peerId;
//  uint32_t uFlags;

  assert(hmsg);
  h=AH_Dialog_GetHbci(hmsg->dialog);
  assert(h);
  e=AH_Dialog_GetMsgEngine(hmsg->dialog);
  assert(e);
  GWEN_MsgEngine_SetMode(e, "pintan");

  u=AH_Dialog_GetDialogOwner(hmsg->dialog);
//  uFlags=AH_User_GetFlags(u);

  peerId=AH_User_GetPeerId(u);
  if (!peerId || *peerId==0)
    peerId=AB_User_GetUserId(u);

  /* create crypt head */
  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "CryptHead");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptHead\" not found");
    return GWEN_ERROR_INTERNAL;
  }

  /* create CryptHead */
  cfg=GWEN_DB_Group_new("crypthead");
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "head/seq", 998);

  rv=AH_MsgPinTan_PrepareCryptoSeg(hmsg, u, cfg, 1, 0);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
    GWEN_DB_Group_free(cfg);
    return rv;
  }

  /* store system id */
  p=NULL;
  if (!hmsg->noSysId)
    p=AH_User_GetSystemId(u);
  if (!p)
    p="0";
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p);

  /* store encrypted message key */
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "CryptAlgo/MsgKey",
                      "NOKEY", 5);

  hbuf=GWEN_Buffer_new(0, 256+GWEN_Buffer_GetUsedBytes(hmsg->buffer), 0, 1);
  rv=GWEN_MsgEngine_CreateMessageFromNode(e,
					  node,
					  hbuf,
					  cfg);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptHead (%d)", rv);
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return rv;
  }
  GWEN_DB_Group_free(cfg);

  /* create cryptdata */
  cfg=GWEN_DB_Group_new("cryptdata");
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "head/seq", 999);
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "cryptdata",
		      GWEN_Buffer_GetStart(hmsg->buffer),
                      GWEN_Buffer_GetUsedBytes(hmsg->buffer));

  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "CryptData");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"CryptData\"not found");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return -1;
  }
  rv=GWEN_MsgEngine_CreateMessageFromNode(e,
                                          node,
                                          hbuf,
                                          cfg);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create CryptData (%d)", rv);
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return rv;
  }

  /* replace existing buffer by encrypted one */
  GWEN_Buffer_free(hmsg->buffer);
  hmsg->buffer=hbuf;
  GWEN_DB_Group_free(cfg);

  return 0;
}
int AH_Msg_SignPinTan(AH_MSG *hmsg,
		      GWEN_BUFFER *rawBuf,
		      const char *signer) {
  AH_HBCI *h;
  GWEN_XMLNODE *node;
  GWEN_DB_NODE *cfg;
  GWEN_BUFFER *hbuf;
  int rv;
  char ctrlref[15];
  const char *p;
  GWEN_MSGENGINE *e;
  AB_USER *su;
  uint32_t uFlags;
  char pin[64];
  uint32_t tm;

  assert(hmsg);
  h=AH_Dialog_GetHbci(hmsg->dialog);
  assert(h);
  e=AH_Dialog_GetMsgEngine(hmsg->dialog);
  assert(e);
  GWEN_MsgEngine_SetMode(e, "pintan");

  su=AB_Banking_FindUser(AH_HBCI_GetBankingApi(h),
			 AH_PROVIDER_NAME,
			 "de", "*",
			 signer, "*");
  if (!su) {
    DBG_ERROR(AQHBCI_LOGDOMAIN,
	      "Unknown user \"%s\"",
	      signer);
    return GWEN_ERROR_NOT_FOUND;
  }

  uFlags=AH_User_GetFlags(su);

  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "SigHead");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigHead\" not found");
    return GWEN_ERROR_INTERNAL;
  }

  /* for iTAN mode: set selected mode (Sicherheitsfunktion, kodiert) */
  tm=AH_Msg_GetItanMethod(hmsg);
  if (tm==0) {
    tm=AH_Dialog_GetItanMethod(hmsg->dialog);
    if (tm)
      /* this is needed by AH_MsgPinTan_PrepareCryptoSeg */
      AH_Msg_SetItanMethod(hmsg, tm);
  }

  /* prepare config for segment */
  cfg=GWEN_DB_Group_new("sighead");
  rv=AH_MsgPinTan_PrepareCryptoSeg(hmsg, su, cfg, 0, 1);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
    GWEN_DB_Group_free(cfg);
    return rv;
  }

  /* set expected signer */
  if (!(uFlags & AH_USER_FLAGS_BANK_DOESNT_SIGN)) {
    const char *remoteId;

    remoteId=AH_User_GetPeerId(su);
    if (!remoteId || *remoteId==0)
      remoteId=AB_User_GetUserId(su);
    assert(remoteId);
    assert(*remoteId);

    DBG_DEBUG(AQHBCI_LOGDOMAIN,
	      "Expecting \"%s\" to sign the response",
	      remoteId);
    AH_Msg_SetExpectedSigner(hmsg, remoteId);
  }

  /* store system id */
  p=NULL;
  if (!hmsg->noSysId)
    p=AH_User_GetSystemId(su);
  if (!p)
    p="0";
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p);

  if (tm) {
    GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			"function", tm);
  }

  /* retrieve control reference for sigtail (to be used later) */
  p=GWEN_DB_GetCharValue(cfg, "ctrlref", 0, "");
  if (strlen(p)>=sizeof(ctrlref)) {
    DBG_INFO(AQHBCI_LOGDOMAIN,
	     "Control reference too long (14 bytes maximum)");
    GWEN_DB_Group_free(cfg);
    return -1;
  }
  strcpy(ctrlref, p);

  /* create SigHead */
  hbuf=GWEN_Buffer_new(0, 128+GWEN_Buffer_GetUsedBytes(rawBuf), 0, 1);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "head/seq", hmsg->firstSegment-1);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "signseq", 1);

  /* create signature head segment */
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
  GWEN_DB_Group_free(cfg);
  cfg=0;
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigHead");
    GWEN_Buffer_free(hbuf);
    return rv;
  }

  /* insert new SigHead at beginning of message buffer */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Inserting signature head");
  GWEN_Buffer_Rewind(hmsg->buffer);
  GWEN_Buffer_InsertBytes(hmsg->buffer,
			  GWEN_Buffer_GetStart(hbuf),
			  GWEN_Buffer_GetUsedBytes(hbuf));

  /* create sigtail */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Completing signature tail");
  cfg=GWEN_DB_Group_new("sigtail");
  GWEN_Buffer_Reset(hbuf);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "head/seq", hmsg->lastSegment+1);
  /* store to DB */
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "signature",
		      "NOSIGNATURE",
                      11);
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		       "ctrlref", ctrlref);

  /* handle pin */
  memset(pin, 0, sizeof(pin));
  rv=AH_User_InputPin(su, pin, 4, sizeof(pin), 0);
  if (rv<0) {
    DBG_ERROR(AQHBCI_LOGDOMAIN,
	      "Error getting pin from medium (%d)", rv);
    GWEN_DB_Group_free(cfg);
    GWEN_Buffer_free(hbuf);
    memset(pin, 0, sizeof(pin));
    return rv;
  }
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "pin", pin);
  AH_Msg_SetPin(hmsg, pin);
  memset(pin, 0, sizeof(pin));

  /* handle tan */
  if (hmsg->needTan) {
    DBG_NOTICE(AQHBCI_LOGDOMAIN,
	       "This queue needs a TAN");
    if (hmsg->usedTan) {
      DBG_NOTICE(AQHBCI_LOGDOMAIN,
		 "Using existing TAN");
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			   "tan", hmsg->usedTan);
    }
    else {
      char tan[16];

      memset(tan, 0, sizeof(tan));
      DBG_NOTICE(AQHBCI_LOGDOMAIN, "Asking for TAN");
      rv=AH_User_InputTan(su, tan, 4, sizeof(tan));
      if (rv<0) {
	DBG_ERROR(AQHBCI_LOGDOMAIN, "Error getting TAN from medium");
	GWEN_DB_Group_free(cfg);
	GWEN_Buffer_free(hbuf);
	return rv;
      }
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			   "tan", tan);
      AH_Msg_SetTan(hmsg, tan);
    }
  }
  else {
    DBG_NOTICE(AQHBCI_LOGDOMAIN,
	       "This queue doesn't need a TAN");
  }

  /* get node */
  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "SigTail");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigTail\"not found");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return GWEN_ERROR_INTERNAL;
  }

  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigTail (%d)", rv);
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return rv;
  }

  /* append sigtail */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail");
  if (GWEN_Buffer_AppendBuffer(hmsg->buffer, hbuf)) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "here");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return GWEN_ERROR_MEMORY_FULL;
  }
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail: done");

  GWEN_Buffer_free(hbuf);
  GWEN_DB_Group_free(cfg);

  /* adjust segment numbers (for next signature and message tail */
  hmsg->firstSegment--;
  hmsg->lastSegment++;

  return 0;
}
Exemple #30
0
int EBC_Dialog_ExchangeMessages(GWEN_HTTP_SESSION *sess,
                                EB_MSG *msg,
                                EB_MSG **pResponse) {
  AB_USER *u;
  int rv;
  GWEN_BUFFER *sendBuf;
  GWEN_BUFFER *recvBuf;
  EB_MSG *mResponse;

  /* preparations */
  u=AB_HttpSession_GetUser(sess);
  assert(u);
  sendBuf=GWEN_Buffer_new(0, 1024, 0, 1);
  recvBuf=GWEN_Buffer_new(0, 1024, 0, 1);

  /* convert message to buffer for sending */
  EB_Msg_toBuffer(msg, sendBuf);

#if 0
  if (GWEN_Logger_GetLevel(AQEBICS_LOGDOMAIN)>=GWEN_LoggerLevel_Debug) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Sending this:");
    fprintf(stderr, "====================================\n");
    fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(sendBuf));
    fprintf(stderr, "====================================\n");
  }
#endif

  /* send request */
  rv=GWEN_HttpSession_SendPacket(sess,
				 "POST",
				 (const uint8_t*)GWEN_Buffer_GetStart(sendBuf),
				 GWEN_Buffer_GetUsedBytes(sendBuf));
  if (rv<0) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Error sending request (%d)", rv);
    GWEN_Buffer_free(recvBuf);
    GWEN_Buffer_free(sendBuf);
    return rv;
  }
  GWEN_Buffer_free(sendBuf);

  /* receive response */
  rv=GWEN_HttpSession_RecvPacket(sess, recvBuf);
  if (rv<0 || rv>=300) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Error sending request (%d)", rv);
    GWEN_Buffer_free(recvBuf);
    return rv;
  }

#if 0
  if (GWEN_Logger_GetLevel(AQEBICS_LOGDOMAIN)>=GWEN_LoggerLevel_Debug) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Received this:");
    fprintf(stderr, "====================================\n");
    fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(recvBuf));
    fprintf(stderr, "====================================\n");
  }
#endif

  /* convert buffer to EBICS message */
  mResponse=EB_Msg_fromBuffer(GWEN_Buffer_GetStart(recvBuf),
                              GWEN_Buffer_GetUsedBytes(recvBuf));
  GWEN_Buffer_free(recvBuf);
  if (!mResponse) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Invalid response (no EBICS message)");
    return GWEN_ERROR_BAD_DATA;
  }

  *pResponse=mResponse;
  return 0;
}