📄 sccom.c
字号:
(SCWRKEY.keyattrlist->key_inst_mode > REPL) || (SCWRKEY.keyattrlist->key_attr.key_presentation > KEY_LOCAL) || (SCWRKEY.keyattrlist->key_attr.key_op_mode > NO_REPLACE) || (SCWRKEY.keyattrlist->key_fpc > 255) || (SCWRKEY.keyattrlist->key_status.key_state > KEY_LOCKED)) { sc_errno = EPARINC; sc_errmsg = sct_error[sc_errno].msg; return (-1); }; lscapdu += KEYHEAD + SCWRKEY.key_len + 1; /* RFU-Byte */ if ((scapdu = SCalloc(lscapdu)) == NULL) return (-1); ptr = scapdu + 2; Ioput(&ptr, kid_1); Ioput(&ptr, (int) SCWRKEY.keyattrlist->key_inst_mode); Ioput(&ptr, KEYHEAD + SCWRKEY.key_len + 1); if (sec_mode == TRUE) Ioput(&ptr, ssc); Ioput(&ptr, SC_NOTUSED); e_KeyAttrList(&ptr, SCWRKEY.keyattrlist, SCWRKEY.key_algid); Ioput(&ptr, SCWRKEY.key_len); Ioputbuff(&ptr, SCWRKEY.key_body, SCWRKEY.key_len); break; /*----------------------------*/ /* create SC_WRITEF */ /*----------------------------*/ case SC_WRITEF: if ((fid = e_FileId(SCWRITEF.fid)) == -1) return (-1); if ((SCWRITEF.data_sel->data_struc > TRANSPARENT) || (SCWRITEF.data_sel->data_struc < LIN_FIX) || ((SCWRITEF.data_sel->data_struc == LIN_FIX) && ((SCWRITEF.data_sel->data_ref.record_sel.record_id < 0) || (SCWRITEF.data_sel->data_ref.record_sel.record_id > 255))) || ((SCWRITEF.data_sel->data_struc == LIN_VAR) && ((SCWRITEF.data_sel->data_ref.record_sel.record_id < 0) || (SCWRITEF.data_sel->data_ref.record_sel.record_id > 254))) || (SCWRITEF.lwrdata > MAXR_W_LEN)) { sc_errno = EPARINC; sc_errmsg = sct_error[sc_errno].msg; return (-1); }; lscapdu += SCWRITEF.lwrdata + FIDLEN; if ((scapdu = SCalloc(lscapdu)) == NULL) return (-1); ptr = scapdu + 2; switch (SCWRITEF.data_sel->data_struc) { case CYCLIC: Ioput(&ptr, SCWRITEF.data_sel->data_ref.element_sel.element_ref); Ioput(&ptr, SCWRITEF.data_sel->data_ref.element_sel.element_no); break; case TRANSPARENT: e_TwoByte(&ptr, SCWRITEF.data_sel->data_ref.string_sel); break; case LIN_FIX: case LIN_VAR: Ioput(&ptr, SCWRITEF.data_sel->data_ref.record_sel.record_id); Ioput(&ptr, SCWRITEF.data_sel->data_ref.record_sel.record_pos); break; }; Ioput(&ptr, SCWRITEF.lwrdata + FIDLEN); if (sec_mode == TRUE) Ioput(&ptr, ssc); Ioput(&ptr, fid); Ioputbuff(&ptr, SCWRITEF.wrdata, SCWRITEF.lwrdata); break; /*----------------------------*/ /* create SC_LOCKKEY */ /*----------------------------*/ case SC_LOCKKEY: if ((kid_1 = e_KeyId(SCLOCKK.kid)) == -1) return (-1); if ((scapdu = SCalloc(lscapdu)) == NULL) return (-1); ptr = scapdu + 2; Ioput(&ptr, kid_1); Ioput(&ptr, SCLOCKK.operation); Ioput(&ptr, SC_NOTUSED); if (sec_mode == TRUE) Ioput(&ptr, ssc); break; /*----------------------------*/ /* create SC_CRYPT */ /*----------------------------*/ case SC_CRYPT: if ((kid_1 = e_KeyId(SCCRYPT.kid)) == -1) return (-1); if ((SCCRYPT.modi > SC_MAC) || (SCCRYPT.modi < SC_ENC)) { sc_errno = EPARINC; sc_errmsg = sct_error[sc_errno].msg; return (-1); }; lscapdu += SCCRYPT.lcrdata; if ((scapdu = SCalloc(lscapdu)) == NULL) return (-1); ptr = scapdu + 2; Ioput(&ptr, kid_1); Ioput(&ptr, SCCRYPT.modi); Ioput(&ptr, SCCRYPT.lcrdata); if (sec_mode == TRUE) Ioput(&ptr, ssc); Ioputbuff(&ptr, SCCRYPT.crdata, SCCRYPT.lcrdata); if (sec_mode == TRUE) Ioput(&ptr, ssc); break; /*----------------------------*/ /* DEFAULT */ /*----------------------------*/ default: sc_errno = ESCIN; sc_errmsg = sct_error[sc_errno].msg; return (-1); break; }; /*------------------------------------*/ /* create CLASS / INS in s_apdu */ /*------------------------------------*/ class = SCHEAD.cmd_class; class |= (unsigned) SOURCE_DTE << 6; if (SCHEAD.security_mess.command != SEC_NORMAL) class |= (unsigned) SCHEAD.security_mess.command << 2; if (SCHEAD.security_mess.response != SEC_NORMAL) class |= (unsigned) SCHEAD.security_mess.response; *scapdu = class; *(scapdu + 1) = SCHEAD.inscode; /*------------------------------------*/ /* print scapdu */ /*------------------------------------*/#ifdef STREAM sta_aux_sc_apdu(sc_trfp, scapdu, lscapdu);#endif /*------------------------------------*/ /* return sc_apdu */ /*------------------------------------*/ sc_apdu->nbytes = lscapdu; sc_apdu->bytes = scapdu; return (0);}/*-------------------------------------------------------------*//* E N D O F P R O C E D U R E sc_create *//*-------------------------------------------------------------*//*--------------------------------------------------------*//* | GMD *//* +-----*//* PROC sc_check VERSION 2.0 *//* DATE November 1991 *//* BY L.Eckstein,GMD *//* *//* DESCRIPTION *//* Check SC-Response (without Secure Messaging) *//* The Response must have the structur: *//* ______________________ *//* | L,DATA,SW1,SW2 | *//* ______________________ *//* Check the SW1 / SW2 - Byte. *//* In case of O.K., sc_check remove the Length-field, *//* the SW1 and the SW2 - field out of the response-buffer.//* The response-buffer contains only the datafield*//* without SW1 / SW2. *//* If SW1/SW2 indicates an error, sc_check returns *//* the value -1 and in sc_errno the error number. *//* *//* *//* *//* INOUT DESCRIPTION *//* sc_response SC-Response-buffer *//* *//* OUT *//* *//* *//* RETURN DESCRIPTION *//* 0 o.k *//* -1 Error *//* sw/sw2 of SC response *//* *//* CALLED FUNCTIONS *//* sta_aux_elemlen *//* sta_aux_bytestr_free *//* sta_aux_sc_resp *//*--------------------------------------------------------*/intsc_check(sc_response) Bytestring *sc_response; /* Structure of SC-Response-Apdu */{ /*----------------------------------------------------------*/ /* Definitions */ /*----------------------------------------------------------*/ unsigned int sw1; unsigned int sw2; unsigned int index = 0; unsigned int listlen = 0; /*----------------------------------------------------------*/ /* Statements */ /*----------------------------------------------------------*/#ifdef STREAM sta_aux_sc_resp(sc_trfp, sc_response->bytes, sc_response->nbytes);#endif /*------------------------------------*/ /* eleminate Length-field in Response */ /*------------------------------------*/ sta_aux_elemlen(sc_response); /*------------------------------------*/ /* check SW1/SW2 */ /*------------------------------------*/ sw1 = *(sc_response->bytes + (sc_response->nbytes - 2)) & 0xFF; sw2 = *(sc_response->bytes + (sc_response->nbytes - 1)) & 0xFF; /* delete sw1/sw2 in response-buffer */ *(sc_response->bytes + (sc_response->nbytes - 2)) = 0x00; *(sc_response->bytes + (sc_response->nbytes - 1)) = 0x00; sc_response->nbytes -= 2; /*------------------------------------*/ /* if sw1 indicates an error, then */ /* search in sct_error list sw1/sw2 */ /* and return index in sc_errno to */ /* calling procedure */ /*------------------------------------*/ if ((sw1 != OKSC) || ((sw1 == OKSC) && (sw2 == DATAINC))) { listlen = sizeof(sct_error) / sizeof(SCTerror); for (index = 0; index < listlen; index++) { if (sct_error[index].sw1 == sw1 && sct_error[index].sw2 == sw2) { sc_errno = index; sc_errmsg = sct_error[sc_errno].msg; return (-1); } } /* sw1 + sw2 not found */ sc_errno = index - 1; /* last element in error-list */ sc_errmsg = sct_error[sc_errno].msg; sta_aux_bytestr_free(sc_response); return (-1); }; return (0);}/*-------------------------------------------------------------*//* E N D O F P R O C E D U R E sc_check *//*-------------------------------------------------------------*//*--------------------------------------------------------*//* | GMD *//* +-----*//* PROC sc_crmac VERSION 2.0 *//* DATE November 1991 *//* BY L.Eckstein,GMD *//* *//* DESCRIPTION *//* Create SC-COMMAND-APDU with MAC *//* This procedure can be called in case of *//* secure messaging = AUTHENTIC. *//* In case of secure messaging=COMBINED, this procedure *//* must be called before calling the procedure sc_enc. *//* *//* *//* *//* IN DESCRIPTION *//* sec_key Secure Messaging key *//* *//* in_apdu Pointer of SC-APDU *//* The SC-APDU must have the *//* structur: *//* __________________________ *//* | CLA,INS,P1,P2,L,SSC,DATA |*//* __________________________ *//* (= output of the procedure *//* sc_create) *//* *//* *//* algenc Encyption method *//* *//* maclen Length of MAC (0 - 8) *//* In the current Version *//* only 4 is allowed *//* OUT *//* out_apdu Pointer of SEC-APDU *//* out_apdu->bytes will be *//* allocated by the called *//* program *//* and must be set free by the*//* calling program *//* The APDU has the structure:*//* ______________________________ *//* | CLA,INS,P1,P2,L,SSC,DATA,MAC |*//* ______________________________ *//* *//* *//* RETURN DESCRIPTION *//* 0 o.k *//* -1 Error *//* EMEMAVAIL *//* EDESENC *//* EMAC *//* EALGO *//* *//* CALLED FUNCTIONS *//* des_encrypt *//* aux_fxdump *//* aux_free2_BitString *//* *//* Bemerkung: *//* Derzeit wird nur der DES-CBC-Mode unterstuetzt. *//* Der DES-3-CBC-Mode noch nicht. *//*--------------------------------------------------------*/intsc_crmac(sec_key, in_apdu, out_apdu, algenc, maclen) BitString *sec_key;/* secure messaging key */ Bytestring *in_apdu;/* SC-APDU */ Bytestring *out_apdu; /* SC-SEC-APDU */ AlgEnc algenc; /* encryption method */ int maclen; /* Length of MAC */{ /*----------------------------------------------------------*/ /* Definitions */ /*----------------------------------------------------------*/ OctetString in_octets; char *ptr, *mac_ptr; int i; int memolen; BitString out_bits; KeyInfo key_info; More more; /*----------------------------------------------------------*/ /* Statements */ /*----------------------------------------------------------*/ out_apdu->nbytes = 0; out_apdu->bytes = NULL; /* Test maclen) */ if (maclen != 4) { sc_errno = EMAC; sc_errmsg = sct_error[sc_errno].msg; return (-1); } in_octets.noctets = in_apdu->nbytes; in_octets.octets = in_apdu->bytes; /*---------------------------------------------------------*/ /* encrypt data (CLA,INS,P1,P2,L,SSC,DATA) */ /* with Secure Messaging Key */ /*---------------------------------------------------------*/#ifdef STREAM fprintf(sc_trfp, "TRACE in sc_crmac\n"); fprintf(sc_trfp, " in_octets.noctets = %d\n", in_octets.noctets); fprintf(sc_trfp, " in_octets.octets = \n"); aux_fxdump(sc_trfp, in_octets.octets, in_octets.noctets, 0);#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -