int CTlsSocket::VerifyCertificate() { if (m_tlsState != handshake) { m_pOwner->LogMessage(::Debug_Warning, _T("VerifyCertificate called at wrong time")); return FZ_REPLY_ERROR; } m_tlsState = verifycert; if (gnutls_certificate_type_get(m_session) != GNUTLS_CRT_X509) { m_pOwner->LogMessage(::Error, _("Unsupported certificate type")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } unsigned int status = 0; if (gnutls_certificate_verify_peers2(m_session, &status) < 0) { m_pOwner->LogMessage(::Error, _("Failed to verify peer certificate")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } if (status & GNUTLS_CERT_REVOKED) { m_pOwner->LogMessage(::Error, _("Beware! Certificate has been revoked")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } if (status & GNUTLS_CERT_SIGNER_NOT_CA) { m_pOwner->LogMessage(::Error, _("Incomplete chain, top certificate is not self-signed certificate authority certificate")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } if (m_require_root_trust && status & GNUTLS_CERT_SIGNER_NOT_FOUND) { m_pOwner->LogMessage(::Error, _("Root certificate is not trusted")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } unsigned int cert_list_size; const gnutls_datum_t* cert_list = gnutls_certificate_get_peers(m_session, &cert_list_size); if (!cert_list || !cert_list_size) { m_pOwner->LogMessage(::Error, _("gnutls_certificate_get_peers returned no certificates")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } if (m_implicitTrustedCert.data) { if (m_implicitTrustedCert.size != cert_list[0].size || memcmp(m_implicitTrustedCert.data, cert_list[0].data, cert_list[0].size)) { m_pOwner->LogMessage(::Error, _("Primary connection and data connection certificates don't match.")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } TrustCurrentCert(true); if (m_tlsState != conn) return FZ_REPLY_ERROR; return FZ_REPLY_OK; } std::vector<CCertificate> certificates; for (unsigned int i = 0; i < cert_list_size; i++) { gnutls_x509_crt_t cert; if (gnutls_x509_crt_init(&cert)) { m_pOwner->LogMessage(::Error, _("Could not initialize structure for peer certificates, gnutls_x509_crt_init failed")); Failure(0, ECONNABORTED); return FZ_REPLY_ERROR; } if (gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER)) { m_pOwner->LogMessage(::Error, _("Could not import peer certificates, gnutls_x509_crt_import failed")); Failure(0, ECONNABORTED); gnutls_x509_crt_deinit(cert); return FZ_REPLY_ERROR; } wxDateTime expirationTime = gnutls_x509_crt_get_expiration_time(cert); wxDateTime activationTime = gnutls_x509_crt_get_activation_time(cert); // Get the serial number of the certificate unsigned char buffer[40]; size_t size = sizeof(buffer); int res = gnutls_x509_crt_get_serial(cert, buffer, &size); wxString serial = bin2hex(buffer, size); unsigned int bits; int algo = gnutls_x509_crt_get_pk_algorithm(cert, &bits); wxString algoName; const char* pAlgo = gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)algo); if (pAlgo) algoName = wxString(pAlgo, wxConvUTF8); //int version = gnutls_x509_crt_get_version(cert); wxString subject, issuer; size = 0; res = gnutls_x509_crt_get_dn(cert, 0, &size); if (size) { char* dn = new char[size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_dn(cert, dn, &size))) { dn[size] = 0; subject = wxString(dn, wxConvUTF8); } else LogError(res); delete [] dn; } else LogError(res); if (subject == _T("")) { m_pOwner->LogMessage(::Error, _("Could not get distinguished name of certificate subject, gnutls_x509_get_dn failed")); Failure(0, ECONNABORTED); gnutls_x509_crt_deinit(cert); return FZ_REPLY_ERROR; } size = 0; res = gnutls_x509_crt_get_issuer_dn(cert, 0, &size); if (size) { char* dn = new char[++size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_issuer_dn(cert, dn, &size))) { dn[size] = 0; issuer = wxString(dn, wxConvUTF8); } else LogError(res); delete [] dn; } else LogError(res); if (issuer == _T("")) { m_pOwner->LogMessage(::Error, _("Could not get distinguished name of certificate issuer, gnutls_x509_get_issuer_dn failed")); Failure(0, ECONNABORTED); gnutls_x509_crt_deinit(cert); return FZ_REPLY_ERROR; } wxString fingerprint_md5; wxString fingerprint_sha1; unsigned char digest[100]; size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, digest, &size)) { digest[size] = 0; fingerprint_md5 = bin2hex(digest, size); } size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &size)) { digest[size] = 0; fingerprint_sha1 = bin2hex(digest, size); } certificates.push_back(CCertificate( cert_list->data, cert_list->size, activationTime, expirationTime, serial, algoName, bits, fingerprint_md5, fingerprint_sha1, subject, issuer)); cert_list++; } CCertificateNotification *pNotification = new CCertificateNotification( m_pOwner->GetCurrentServer()->GetHost(), m_pOwner->GetCurrentServer()->GetPort(), GetCipherName(), GetMacName(), certificates); m_pOwner->SendAsyncRequest(pNotification); m_pOwner->LogMessage(Status, _("Verifying certificate...")); return FZ_REPLY_WOULDBLOCK; }
static bool bitforce_send_work(struct thr_info *thr, struct work *work) { struct cgpu_info *bitforce = thr->cgpu; unsigned char ob[70]; char buf[BITFORCE_BUFSIZ+1]; int err, amount; char *s; char *cmd; int len; re_send: if (bitforce->nonce_range) { cmd = BITFORCE_SENDRANGE; len = BITFORCE_SENDRANGE_LEN; } else { cmd = BITFORCE_SENDWORK; len = BITFORCE_SENDWORK_LEN; } mutex_lock(&bitforce->device_mutex); if ((err = usb_write(bitforce, cmd, len, &amount, C_REQUESTSENDWORK)) < 0 || amount != len) { mutex_unlock(&bitforce->device_mutex); applog(LOG_ERR, "%s%i: request send work failed (%d:%d)", bitforce->drv->name, bitforce->device_id, amount, err); return false; } if ((err = usb_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_REQUESTSENDWORKSTATUS)) < 0) { mutex_unlock(&bitforce->device_mutex); applog(LOG_ERR, "%s%d: read request send work status failed (%d:%d)", bitforce->drv->name, bitforce->device_id, amount, err); return false; } if (amount == 0 || !buf[0] || !strncasecmp(buf, "B", 1)) { mutex_unlock(&bitforce->device_mutex); nmsleep(WORK_CHECK_INTERVAL_MS); goto re_send; } else if (unlikely(strncasecmp(buf, "OK", 2))) { mutex_unlock(&bitforce->device_mutex); if (bitforce->nonce_range) { applog(LOG_WARNING, "%s%i: Does not support nonce range, disabling", bitforce->drv->name, bitforce->device_id); bitforce->nonce_range = false; bitforce->sleep_ms *= 5; bitforce->kname = KNAME_WORK; goto re_send; } applog(LOG_ERR, "%s%i: Error: Send work reports: %s", bitforce->drv->name, bitforce->device_id, buf); return false; } sprintf((char *)ob, ">>>>>>>>"); memcpy(ob + 8, work->midstate, 32); memcpy(ob + 8 + 32, work->data + 64, 12); if (!bitforce->nonce_range) { sprintf((char *)ob + 8 + 32 + 12, ">>>>>>>>"); work->blk.nonce = bitforce->nonces = 0xffffffff; len = 60; } else { uint32_t *nonce; nonce = (uint32_t *)(ob + 8 + 32 + 12); *nonce = htobe32(work->blk.nonce); nonce = (uint32_t *)(ob + 8 + 32 + 12 + 4); /* Split work up into 1/5th nonce ranges */ bitforce->nonces = 0x33333332; *nonce = htobe32(work->blk.nonce + bitforce->nonces); work->blk.nonce += bitforce->nonces + 1; sprintf((char *)ob + 8 + 32 + 12 + 8, ">>>>>>>>"); len = 68; } if ((err = usb_write(bitforce, (char *)ob, len, &amount, C_SENDWORK)) < 0 || amount != len) { mutex_unlock(&bitforce->device_mutex); applog(LOG_ERR, "%s%i: send work failed (%d:%d)", bitforce->drv->name, bitforce->device_id, amount, err); return false; } if ((err = usb_read_nl(bitforce, buf, sizeof(buf)-1, &amount, C_SENDWORKSTATUS)) < 0) { mutex_unlock(&bitforce->device_mutex); applog(LOG_ERR, "%s%d: read send work status failed (%d:%d)", bitforce->drv->name, bitforce->device_id, amount, err); return false; } mutex_unlock(&bitforce->device_mutex); if (opt_debug) { s = bin2hex(ob + 8, 44); applog(LOG_DEBUG, "%s%i: block data: %s", bitforce->drv->name, bitforce->device_id, s); free(s); } if (amount == 0 || !buf[0]) { applog(LOG_ERR, "%s%i: Error: Send block data returned empty string/timed out", bitforce->drv->name, bitforce->device_id); return false; } if (unlikely(strncasecmp(buf, "OK", 2))) { applog(LOG_ERR, "%s%i: Error: Send block data reports: %s", bitforce->drv->name, bitforce->device_id, buf); return false; } cgtime(&bitforce->work_start_tv); return true; }
/* Read the key identified by GRIP from the private key directory and return it as an gcrypt S-expression object in RESULT. On failure returns an error code and stores NULL at RESULT. */ static gpg_error_t read_key_file (const unsigned char *grip, gcry_sexp_t *result) { int rc; char *fname; estream_t fp; struct stat st; unsigned char *buf; size_t buflen, erroff; gcry_sexp_t s_skey; char hexgrip[40+4+1]; *result = NULL; bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); fp = es_fopen (fname, "rb"); if (!fp) { rc = gpg_error_from_syserror (); if (gpg_err_code (rc) != GPG_ERR_ENOENT) log_error ("can't open '%s': %s\n", fname, strerror (errno)); xfree (fname); return rc; } if (fstat (es_fileno (fp), &st)) { rc = gpg_error_from_syserror (); log_error ("can't stat '%s': %s\n", fname, strerror (errno)); xfree (fname); es_fclose (fp); return rc; } buflen = st.st_size; buf = xtrymalloc (buflen+1); if (!buf) { rc = gpg_error_from_syserror (); log_error ("error allocating %zu bytes for '%s': %s\n", buflen, fname, strerror (errno)); xfree (fname); es_fclose (fp); xfree (buf); return rc; } if (es_fread (buf, buflen, 1, fp) != 1) { rc = gpg_error_from_syserror (); log_error ("error reading %zu bytes from '%s': %s\n", buflen, fname, strerror (errno)); xfree (fname); es_fclose (fp); xfree (buf); return rc; } /* Convert the file into a gcrypt S-expression object. */ rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); xfree (fname); es_fclose (fp); xfree (buf); if (rc) { log_error ("failed to build S-Exp (off=%u): %s\n", (unsigned int)erroff, gpg_strerror (rc)); return rc; } *result = s_skey; return 0; }
void collect_register_as_string (struct regcache *regcache, int n, char *buf) { bin2hex (register_data (regcache, n, 1), buf, register_size (regcache->tdesc, n)); }
//-------------------------------------------------- // Returns the hash to be signed with or without ASN1 // prefix and with or without base64 encoding // pSigInfo - signature address // pBuf - buffer for hash value with or without prefix // pBufLen - pointer to buffer length // enc - return 0=unencoded, 1=base64, 2=hex // bWithAsn1Prefix - return with or without ASN1 prefix 1/0 // return returns error code or ERR_OK //-------------------------------------------------- EXP_OPTION int ddocGetSignedHash(SignatureInfo* pSigInfo, char* pBuf, int* pBufLen, int enc, int bWithAsn1Prefix) { int err = ERR_OK, l1 = 0; char buf1[50]; DigiDocMemBuf *pMBuf; RETURN_IF_NULL_PARAM(pSigInfo); RETURN_IF_NULL_PARAM(pBuf); //RETURN_IF_NOT(err == ERR_OK, err); // TODO: check buflen pMBuf = ddocDigestValue_GetDigestValue(pSigInfo->pSigInfoRealDigest); RETURN_IF_NULL_PARAM(pMBuf); if(enc == 2) { // hex mode if(bWithAsn1Prefix) { if(sizeof(buf1) > sizeof(g_sigPrefix) + pMBuf->nLen) { memcpy(buf1, g_sigPrefix, sizeof(g_sigPrefix)); memcpy(buf1 + sizeof(g_sigPrefix), pMBuf->pMem, pMBuf->nLen); l1 = pMBuf->nLen + sizeof(g_sigPrefix); } else err = ERR_BUF_LEN; } else { if(sizeof(buf1) > (size_t)pMBuf->nLen) { memcpy(buf1, pMBuf->pMem, pMBuf->nLen); l1 = pMBuf->nLen; } else err = ERR_BUF_LEN; } bin2hex((const byte*)buf1, l1, (char*)pBuf, pBufLen); } else if(enc == 1) { // base64 mode if(bWithAsn1Prefix) { if(sizeof(buf1) > sizeof(g_sigPrefix) + (size_t)pMBuf->nLen) { memcpy(buf1, g_sigPrefix, sizeof(g_sigPrefix)); memcpy(buf1 + sizeof(g_sigPrefix), pMBuf->pMem, pMBuf->nLen); l1 = pMBuf->nLen + sizeof(g_sigPrefix); } else err = ERR_BUF_LEN; } else { if(sizeof(buf1) > (size_t)pMBuf->nLen) { memcpy(buf1, pMBuf->pMem, pMBuf->nLen); l1 = pMBuf->nLen; } else err = ERR_BUF_LEN; } encode((const byte*)buf1, l1, (byte*)pBuf, pBufLen); } else { if(bWithAsn1Prefix) { if(*pBufLen > (int)sizeof(g_sigPrefix) + pMBuf->nLen) { memcpy(pBuf, g_sigPrefix, sizeof(g_sigPrefix)); memcpy(pBuf + sizeof(g_sigPrefix), pMBuf->pMem, pMBuf->nLen); *pBufLen = pMBuf->nLen + sizeof(g_sigPrefix); } else err = ERR_BUF_LEN; } else { if(*pBufLen > pMBuf->nLen) { *pBufLen = pMBuf->nLen; memcpy(pBuf, pMBuf->pMem, pMBuf->nLen); } else err = ERR_BUF_LEN; } } return err; }
static void hash2hex(const uint8_t *hash, char *dst) { bin2hex(hash, MD5_DIGEST_LENGTH, dst, 16*2+1); }
/* Search the keyserver identified by URI for keys matching PATTERN. On success R_FP has an open stream to read the data. */ gpg_error_t ks_hkp_search (ctrl_t ctrl, parsed_uri_t uri, const char *pattern, estream_t *r_fp) { gpg_error_t err; KEYDB_SEARCH_DESC desc; char fprbuf[2+40+1]; char *hostport = NULL; char *request = NULL; estream_t fp = NULL; int reselect; unsigned int httpflags; char *httphost = NULL; unsigned int tries = SEND_REQUEST_RETRIES; *r_fp = NULL; /* Remove search type indicator and adjust PATTERN accordingly. Note that HKP keyservers like the 0x to be present when searching by keyid. We need to re-format the fingerprint and keyids so to remove the gpg specific force-use-of-this-key flag ("!"). */ err = classify_user_id (pattern, &desc, 1); if (err) return err; switch (desc.mode) { case KEYDB_SEARCH_MODE_EXACT: case KEYDB_SEARCH_MODE_SUBSTR: case KEYDB_SEARCH_MODE_MAIL: case KEYDB_SEARCH_MODE_MAILSUB: pattern = desc.u.name; break; case KEYDB_SEARCH_MODE_SHORT_KID: snprintf (fprbuf, sizeof fprbuf, "0x%08lX", (ulong)desc.u.kid[1]); pattern = fprbuf; break; case KEYDB_SEARCH_MODE_LONG_KID: snprintf (fprbuf, sizeof fprbuf, "0x%08lX%08lX", (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]); pattern = fprbuf; break; case KEYDB_SEARCH_MODE_FPR16: bin2hex (desc.u.fpr, 16, fprbuf); pattern = fprbuf; break; case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: bin2hex (desc.u.fpr, 20, fprbuf); pattern = fprbuf; break; default: return gpg_error (GPG_ERR_INV_USER_ID); } /* Build the request string. */ reselect = 0; again: { char *searchkey; xfree (hostport); hostport = NULL; xfree (httphost); httphost = NULL; err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect, &hostport, &httpflags, &httphost); if (err) goto leave; searchkey = http_escape_string (pattern, EXTRA_ESCAPE_CHARS); if (!searchkey) { err = gpg_error_from_syserror (); goto leave; } xfree (request); request = strconcat (hostport, "/pks/lookup?op=index&options=mr&search=", searchkey, NULL); xfree (searchkey); if (!request) { err = gpg_error_from_syserror (); goto leave; } } /* Send the request. */ err = send_request (ctrl, request, hostport, httphost, httpflags, NULL, NULL, &fp); if (handle_send_request_error (err, request, &tries)) { reselect = 1; goto again; } if (err) goto leave; err = dirmngr_status (ctrl, "SOURCE", hostport, NULL); if (err) goto leave; /* Peek at the response. */ { int c = es_getc (fp); if (c == -1) { err = es_ferror (fp)?gpg_error_from_syserror ():gpg_error (GPG_ERR_EOF); log_error ("error reading response: %s\n", gpg_strerror (err)); goto leave; } if (c == '<') { /* The document begins with a '<': Assume a HTML response, which we don't support. */ err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING); goto leave; } es_ungetc (c, fp); } /* Return the read stream. */ *r_fp = fp; fp = NULL; leave: es_fclose (fp); xfree (request); xfree (hostport); xfree (httphost); return err; }
void DoEmvTransaction(){ unsigned char transaction_data[4096]; unsigned int transaction_data_len = 0; unsigned char custom_data[1024]; unsigned int custom_data_len = 0; unsigned char hexKsn[21]; unsigned char encryptedHexBuffer[128]; char hex[256]; unsigned char panToken[32]; unsigned char hexToken[32]; char *outputBuffer; char *sesitiveTagBuffer; char *clearTagBuffer; int samSlot = 1; char pToken[32] = {0}; l2bool result = L2FALSE; int rcTransaction = 0; int rcResponse = 0; int rc = 0; int i = 0; int tindex = 0; /* Perform EMVCo L2 transaction */ rcTransaction = l2manager_PerformTransaction(&tp, &onRequestOutcome, &onRestartOutcome, samSlot, pToken); /* Evaluate return value */ printf("\nl2manager_PerformTransaction() returns with %d\n\n", rcTransaction); switch (rcTransaction) { case EMV_OFFLINE_ACCEPT: case EMV_GO_ONLINE: #ifdef DEBUG if (onRequestOutcome.m_bpresent) printf("onRequestOutcome.m_ucmsgid: %d\n", (int)onRequestOutcome.m_ucmsgid); if (onRestartOutcome.m_bpresent) printf("onRestartOutcome.m_ucmsgid: %d\n", (int)onRestartOutcome.m_ucmsgid); #endif if (rcTransaction == EMV_OFFLINE_ACCEPT) { emvSuccessVisualization(); } /* Get transaction data. * Please see description of * rdol_<kernel_id>_emv.txt or rdol_<kernel_id>_ms.txt. */ result = l2manager_GetTransactionData(transaction_data, sizeof(transaction_data), &transaction_data_len); if (result == L2TRUE) { #ifdef DEBUG printf("TRANSACTION DATA:\n"); for (i = 0; i < transaction_data_len; i++) printf("%02X", transaction_data[i]); printf("\n\n"); #endif tlvInfo_t *t=malloc(sizeof(tlvInfo_t)*transaction_data_len); memset(t,0,transaction_data_len); tlvInfo_init(t); tindex = 0; asprintf(&clearTagBuffer, ""); asprintf(&sesitiveTagBuffer, ""); emvparse(transaction_data, transaction_data_len, t, &tindex, 0, &clearTagBuffer, &sesitiveTagBuffer); free(t); //Get PAN Token SHA256_CTX ctx; sha256_init(&ctx); sha256_update(&ctx,sesitiveTagBuffer, strlen(sesitiveTagBuffer)); sha256_final(&ctx,panToken); #ifdef DEBUG printf("hash DATA:\n"); for (i = 0; i < 32; i++) printf("%02X", panToken[i]); printf("\n\n"); #endif //TODO Test PAN Token against deny list here //********** DO DUKPT Crypto dukptEncrypt(hSession, sesitiveTagBuffer, strlen(sesitiveTagBuffer), hexKsn, encryptedHexBuffer); #ifdef DEBUG printf("EMV - Clear Data : %s\n", sesitiveTagBuffer); printf("EMV - KSN : %s\n", hexKsn); printf("EMV - CipherText : %s\n", encryptedHexBuffer); #endif strcpy(hexToken, bin2hex(hex, panToken, 32)); // Output format for CULR call to Creditcall //unsigned short size = sizeof(transaction_data)/sizeof(transaction_data[0]); formatOutputBuffer(&outputBuffer, hexKsn, &clearTagBuffer, encryptedHexBuffer, rcTransaction, hexToken); //Clear out transaction_data buffer that contains sensitive data to zero memset(&transaction_data[0], 0, sizeof(transaction_data)); //TODO Clear out sensitive data to zero memset(&sesitiveTagBuffer[0], 0, strlen(sesitiveTagBuffer)); free(sesitiveTagBuffer); free(clearTagBuffer); printf("%s",outputBuffer); } #ifdef DEBUG /* Get custom data. * Please see description of rdol_clear.txt. */ result = l2manager_GetCustomData(custom_data, sizeof(custom_data), &custom_data_len); if (result == L2TRUE) { printf("RDOL:\n"); for (i = 0; i < custom_data_len; i++) printf("%02X", custom_data[i]); printf("\n\n"); } #endif /** If the return value is EMV_GO_ONLINE you must call the * function l2manager_ProcessOnlineResponse(). **/ if (rcTransaction == EMV_GO_ONLINE) { /** ATTENTION * It is absolutely necessary to call the function * l2manager_ProcessOnlineResponse() if the code * EMV_GO_ONLINE is returned from function * l2manager_PerformTransaction() ! * If you want to abort the transaction, or the backend * is not reachable or something else, you should set * the ucOnlineRespData and OnlineRespDataLen to zero. * In such a case the return code will be * EMV_ONLINE_DECLINE. **/ //NEED to get return buffer //doSslCall(outputBuffer); unsigned char OnlineRespData[1024] = {0}; unsigned int OnlineRespDataLen = 0; #ifdef EMV_ONLINE_SUCCESS /* Successfull Online Verification = 0x30 0x30 */ OnlineRespDataLen = 16; memcpy(OnlineRespData, "\x8A\x02\x30\x30\x91\x0A\x60\x6D\x6C\x6C\x37\xD4\xAC\x51\x30\x30", OnlineRespDataLen); #endif memset(&onRequestOutcome, 0, sizeof(UIRequest)); memset(&onRestartOutcome, 0, sizeof(UIRequest)); rcResponse = l2manager_ProcessOnlineResponse(OnlineRespData, OnlineRespDataLen, &onRequestOutcome, &onRestartOutcome); switch (rcResponse) { case EMV_ONLINE_ACCEPT: printf("%s returns with EMV_ONLINE_ACCEPT\n", "l2manager_ProcessOnlineResponse()"); emvSuccessVisualization(1, 1); disable_bar(); enable_running_led(); break; case EMV_ONLINE_DECLINE: printf("%s returns with EMV_ONLINE_DECLINE\n", "\nl2manager_ProcessOnlineResponse()"); /* EMVCo alert tone. * Buzzer Beep @ 750Hz for 200ms * [On -> Off -> On] */ emvAlertTone(); break; default: printf("%s returns with undefined code (%d)\n", "\nl2manager_ProcessOnlineResponse()", rcTransaction); /* EMVCo alert tone. * Buzzer Beep @ 750Hz for 200ms * [On -> Off -> On] */ emvAlertTone(); break; } } else { /* EMVCo success tone. * Buzzer Beep @ 1500Hz for 500ms */ if (rcTransaction == EMV_OFFLINE_ACCEPT) { if (threadRunning){ //wait for thread to finish WaitEmvThreadFinnish(); } //Create thread for sending data int err; err = pthread_create(&inc_x_thread,NULL,&thread_doSslCall,(void *)outputBuffer); if (err != 0){ printf("\n\n\nCan't create thread...\n"); threadRunning = false; } else { printf("\n\n\nThread created...\n"); threadRunning = true; } disable_bar(); enable_running_led(); ClearTransactionData(); SetTransactionData(); } } break; case EMV_PPSE_NOT_SUPPORTED_BY_CARD: case EMV_NO_MATCHING_APP: /** At this point you could do some "closed loop" processing, * because the EMVCo kernel refuse the card. * Maybe it is no credit card, or the application is not * supported. * The card is still activated and remains in ISO 14443-4 state. */ /* EMVCo alert tone. * Buzzer Beep @ 750Hz for 200ms [On -> Off -> On] */ emvAlertTone(); break; /* case ...: * break; */ default: /* The other codes should be treated as error. */ /* EMVCo alert tone. * Buzzer Beep @ 750Hz for 200ms [On -> Off -> On] */ emvAlertTone(); break; } /* Check TransactionMode */ rc = l2manager_GetTransactionMode(); switch (rc) { case 1: printf("Transaction mode = Magstripe\n"); break; case 2: printf("Transaction mode = Magstripe [CVN_17]\n"); break; case 3: printf("Transaction mode = EMV\n"); break; default: printf("Transaction mode = (%d) - UNKNOWN\n", rc); break; } /* Needed for Mastercard processing */ /* This function is used to clear TORN for paypass transactions */ result = l2manager_ClearTorn(); if (result != L2TRUE) printf("Error in function l2manager_ClearTorn()\n"); }
bool CAlphaCrypt::VerifyAlphaMasterKey(BYTE masterKey[32], BYTE recKey[0x40]) { LPSTR recKeyHex = bin2hex(recKey, 0x40); bool bRetVal = VerifyAlphaMasterKey(masterKey, recKeyHex); if (recKeyHex) delete recKeyHex ; return bRetVal; }
int CTlsSocket::VerifyCertificate() { if (m_tlsState != handshake) { m_pOwner->LogMessage(Debug_Warning, _T("VerifyCertificate called at wrong time")); return FZ_REPLY_ERROR; } m_tlsState = verifycert; if (gnutls_certificate_type_get(m_session) != GNUTLS_CRT_X509) { m_pOwner->LogMessage(::Debug_Warning, _T("Unsupported certificate type")); Failure(0); return FZ_REPLY_ERROR; } unsigned int cert_list_size; const gnutls_datum_t* const cert_list = gnutls_certificate_get_peers(m_session, &cert_list_size); if (!cert_list || !cert_list_size) { m_pOwner->LogMessage(::Debug_Warning, _T("gnutls_certificate_get_peers returned no certificates")); Failure(0); return FZ_REPLY_ERROR; } if (m_implicitTrustedCert.data) { if (m_implicitTrustedCert.size != cert_list[0].size || memcmp(m_implicitTrustedCert.data, cert_list[0].data, cert_list[0].size)) { m_pOwner->LogMessage(::Error, _("Primary connection and data connection certificates don't match.")); Failure(0); return FZ_REPLY_ERROR; } TrustCurrentCert(true); return FZ_REPLY_OK; } gnutls_x509_crt_t cert; if (gnutls_x509_crt_init(&cert)) { m_pOwner->LogMessage(::Debug_Warning, _T("gnutls_x509_crt_init failed")); Failure(0); return FZ_REPLY_ERROR; } if (gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER)) { m_pOwner->LogMessage(::Debug_Warning, _T("gnutls_x509_crt_import failed")); Failure(0); gnutls_x509_crt_deinit(cert); return FZ_REPLY_ERROR; } wxDateTime expirationTime = gnutls_x509_crt_get_expiration_time(cert); wxDateTime activationTime = gnutls_x509_crt_get_activation_time(cert); // Get the serial number of the certificate unsigned char buffer[40]; size_t size = sizeof(buffer); int res = gnutls_x509_crt_get_serial(cert, buffer, &size); wxString serial = bin2hex(buffer, size); unsigned int bits; int algo = gnutls_x509_crt_get_pk_algorithm(cert, &bits); wxString algoName; const char* pAlgo = gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)algo); if (pAlgo) algoName = wxString(pAlgo, wxConvUTF8); //int version = gnutls_x509_crt_get_version(cert); wxString subject, issuer; size = 0; res = gnutls_x509_crt_get_dn(cert, 0, &size); if (size) { char* dn = new char[size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_dn(cert, dn, &size))) { dn[size] = 0; subject = wxString(dn, wxConvUTF8); } else LogError(res); delete [] dn; } else LogError(res); if (subject == _T("")) { m_pOwner->LogMessage(::Debug_Warning, _T("gnutls_x509_get_dn failed")); Failure(0); gnutls_x509_crt_deinit(cert); return FZ_REPLY_ERROR; } size = 0; res = gnutls_x509_crt_get_issuer_dn(cert, 0, &size); if (size) { char* dn = new char[size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_issuer_dn(cert, dn, &size))) { dn[size] = 0; issuer = wxString(dn, wxConvUTF8); } else LogError(res); delete [] dn; } else LogError(res); if (issuer == _T("")) { m_pOwner->LogMessage(::Debug_Warning, _T("gnutls_x509_get_issuer_dn failed")); Failure(0); gnutls_x509_crt_deinit(cert); return FZ_REPLY_ERROR; } wxString fingerprint_md5; wxString fingerprint_sha1; unsigned char digest[100]; size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_MD5, digest, &size)) { digest[size] = 0; fingerprint_md5 = bin2hex(digest, size); } size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &size)) { digest[size] = 0; fingerprint_sha1 = bin2hex(digest, size); } CCertificateNotification *pNotification = new CCertificateNotification( m_pOwner->GetCurrentServer()->GetHost(), m_pOwner->GetCurrentServer()->GetPort(), cert_list->data, cert_list->size, activationTime, expirationTime, serial, algoName, bits, fingerprint_md5, fingerprint_sha1, subject, issuer); pNotification->requestNumber = m_pOwner->GetEngine()->GetNextAsyncRequestNumber(); m_pOwner->GetEngine()->AddNotification(pNotification); m_pOwner->LogMessage(Status, _("Verifying certificate...")); return FZ_REPLY_WOULDBLOCK; }
int bin2hex_main(int argc, char ** argv) { FILE * rand_fh; char lt[256][2]; unsigned int x,y; char * newhex_dest; union { uint32_t u32; uint8_t u8[4]; } random_num; uint16_t i; printf("***************** BIN2HEX *****************\n"); if(bin2hex_init(lt) == 0) { // Fail.. Leave fprintf(stderr, "Unable to init lookup table.\n"); return EXIT_FAILURE; } rand_fh = fopen("/dev/urandom", "r"); if(!rand_fh) { fprintf(stderr, "Unable to open random buffer.\n"); return EXIT_FAILURE; } printf("Table created: \n"); for(i=0; i<256; i++) { printf("%c%c", lt[i][0], lt[i][1]); if(i%15 == 0) printf("\n"); else printf(" "); } // Initialize crazy binary array uint8_t * crazy_hex = malloc(CRAZY_SIZE); for(i=0; i<CRAZY_SIZE-3; i++) { if((fread(&random_num.u32, 4, 1, rand_fh) == 0)) { fprintf(stderr, "Could not read 4 bytes from file.\n"); return EXIT_FAILURE; } crazy_hex[i] = random_num.u8[0]; crazy_hex[i+1] = random_num.u8[1]; crazy_hex[i+2] = random_num.u8[2]; crazy_hex[i+3] = random_num.u8[3]; i += 4; } char hex_dest[2 + 2*CRAZY_SIZE]; hex_dest[0] = '0'; hex_dest[1] = 'x'; GET_CYCLES(x); bin2hex(lt, &hex_dest[2], crazy_hex, CRAZY_SIZE); GET_CYCLES(y); printf("time=%u, ", y-x); printf("Output: %.*s\n", 2 + 2*CRAZY_SIZE, hex_dest); printf("***************** BIN2HEX *****************\n"); printf("***************** BIN2HEX Competition *****************\n"); size_t hex2ascii_len = 256; char** hex2ascii; hex2ascii = malloc(hex2ascii_len*sizeof(char*)); for(i=0; i<hex2ascii_len; i++) { hex2ascii[i] = malloc(3*sizeof(char)); snprintf(hex2ascii[i], 3,"%02X", i); } size_t len = 8; GET_CYCLES(x); newhex_dest = char_to_hex((const unsigned char*)crazy_hex, CRAZY_SIZE, (char**)hex2ascii); GET_CYCLES(y); printf("time=%u, ", y-x); printf("Output: 0x%s\n", newhex_dest); fclose(rand_fh); return EXIT_SUCCESS; }
static struct cgpu_info *gridseed_detect_one(libusb_device *dev, struct usb_find_devices *found) { struct cgpu_info *gridseed; GRIDSEED_INFO *info; int this_option_offset; int baud, freq, chips, modules, usefifo, btcore; int err, wrote; bool configured; unsigned char rbuf[GRIDSEED_READ_SIZE]; unsigned char *p; #if 0 const char detect_cmd[] = "55aa0f01" "4a548fe471fa3a9a1371144556c3f64d" "2500b4826008fe4bbf7698c94eba7946" "ce22a72f4f6726141a0b3287eeeeeeee"; unsigned char detect_data[52]; #else const char detect_cmd[] = "55aac000909090900000000001000000"; unsigned char detect_data[16]; #endif gridseed = usb_alloc_cgpu(&gridseed_drv, GRIDSEED_MINER_THREADS); if (!usb_init(gridseed, dev, found)) goto shin; libusb_reset_device(gridseed->usbdev->handle); baud = GRIDSEED_DEFAULT_BAUD; chips = GRIDSEED_DEFAULT_CHIPS; modules = GRIDSEED_DEFAULT_MODULES; freq = gc3355_find_freq_index(GRIDSEED_DEFAULT_FREQUENCY); usefifo = GRIDSEED_DEFAULT_USEFIFO; btcore = GRIDSEED_DEFAULT_BTCORE; this_option_offset = 0; configured = get_options(this_option_offset, gridseed, opt_gridseed_options, &baud, &freq, &chips, &modules, &usefifo, &btcore); info = (GRIDSEED_INFO*)calloc(sizeof(GRIDSEED_INFO), 1); if (unlikely(!info)) quit(1, "Failed to calloc gridseed_info data"); gridseed->device_data = (void *)info; update_usb_stats(gridseed); //if (configured) { info->baud = baud; info->freq = freq; info->chips = chips; info->modules = modules; info->usefifo = usefifo; info->btcore = btcore; //} gridseed->usbdev->usb_type = USB_TYPE_STD; gridseed_initialise(gridseed, info); /* send testing work to chips */ hex2bin(detect_data, detect_cmd, sizeof(detect_data)); if (gc3355_write_data(gridseed, detect_data, sizeof(detect_data))) { applog(LOG_DEBUG, "Failed to write work data to %i, err %d", gridseed->device_id, err); goto unshin; } /* waiting for return */ if (gc3355_get_data(gridseed, rbuf, GRIDSEED_READ_SIZE)) { applog(LOG_DEBUG, "No response from %i", gridseed->device_id); goto unshin; } if (memcmp(rbuf, "\x55\xaa\xc0\x00\x90\x90\x90\x90", GRIDSEED_READ_SIZE-4) != 0) { applog(LOG_DEBUG, "Bad response from %i", gridseed->device_id); goto unshin; } p = bin2hex(rbuf+GRIDSEED_READ_SIZE-4, 4); applog(LOG_NOTICE, "Device found, firmware version 0x%s, driver version %s", p, gridseed_version); free(p); if (!add_cgpu(gridseed)) goto unshin; return gridseed; unshin: usb_uninit(gridseed); free(gridseed->device_data); gridseed->device_data = NULL; shin: gridseed = usb_free_cgpu(gridseed); return NULL; }
static void mkswap_generate_uuid(uint8_t *buf) { /* http://www.ietf.org/rfc/rfc4122.txt * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | time_low | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | time_mid | time_hi_and_version | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |clk_seq_and_variant | node (0-1) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | node (2-5) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * IOW, uuid has this layout: * uint32_t time_low (big endian) * uint16_t time_mid (big endian) * uint16_t time_hi_and_version (big endian) * version is a 4-bit field: * 1 Time-based * 2 DCE Security, with embedded POSIX UIDs * 3 Name-based (MD5) * 4 Randomly generated * 5 Name-based (SHA-1) * uint16_t clk_seq_and_variant (big endian) * variant is a 3-bit field: * 0xx Reserved, NCS backward compatibility * 10x The variant specified in rfc4122 * 110 Reserved, Microsoft backward compatibility * 111 Reserved for future definition * uint8_t node[6] * * For version 4, these bits are set/cleared: * time_hi_and_version & 0x0fff | 0x4000 * clk_seq_and_variant & 0x3fff | 0x8000 */ pid_t pid; int i; char uuid_string[32]; i = open("/dev/urandom", O_RDONLY); if (i >= 0) { read(i, buf, 16); close(i); } /* Paranoia. /dev/urandom may be missing. * rand() is guaranteed to generate at least [0, 2^15) range, * but lowest bits in some libc are not so "random". */ srand(monotonic_us()); pid = getpid(); while (1) { for (i = 0; i < 16; i++) buf[i] ^= rand() >> 5; if (pid == 0) break; srand(pid); pid = 0; } /* version = 4 */ buf[4 + 2 ] = (buf[4 + 2 ] & 0x0f) | 0x40; /* variant = 10x */ buf[4 + 2 + 2] = (buf[4 + 2 + 2] & 0x3f) | 0x80; bin2hex(uuid_string, (void*) buf, 16); /* f.e. UUID=dfd9c173-be52-4d27-99a5-c34c6c2ff55f */ printf("UUID=%.8s" "-%.4s-%.4s-%.4s-%.12s\n", uuid_string, uuid_string+8, uuid_string+8+4, uuid_string+8+4+4, uuid_string+8+4+4+4 ); }
JNIEXPORT void JNICALL Java_com_lonelycoder_mediaplayer_Core_coreInit(JNIEnv *env, jobject obj, jstring j_settings, jstring j_cachedir, jstring j_sdcard, jstring j_android_id, jint time_24hrs) { char path[PATH_MAX]; trace_arch(TRACE_INFO, "Core", "Native core initializing"); gconf.trace_level = TRACE_DEBUG; gconf.time_format_system = time_24hrs ? TIME_FORMAT_24 : TIME_FORMAT_12; struct timeval tv; gettimeofday(&tv, NULL); srand(tv.tv_usec); const char *settings = (*env)->GetStringUTFChars(env, j_settings, 0); const char *cachedir = (*env)->GetStringUTFChars(env, j_cachedir, 0); const char *sdcard = (*env)->GetStringUTFChars(env, j_sdcard, 0); const char *android_id = (*env)->GetStringUTFChars(env, j_android_id, 0); gconf.persistent_path = strdup(settings); gconf.cache_path = strdup(cachedir); snprintf(path, sizeof(path), "%s/Download", sdcard); mkdir(path, 0770); snprintf(path, sizeof(path), "%s/Download/movian_upgrade.apk", sdcard); gconf.upgrade_path = strdup(path); unlink(gconf.upgrade_path); uint8_t digest[16]; md5_decl(ctx); md5_init(ctx); md5_update(ctx, (const void *)android_id, strlen(android_id)); md5_update(ctx, (const void *)android_serialno, strlen(android_serialno)); md5_final(ctx, digest); bin2hex(gconf.device_id, sizeof(gconf.device_id), digest, sizeof(digest)); (*env)->ReleaseStringUTFChars(env, j_settings, settings); (*env)->ReleaseStringUTFChars(env, j_cachedir, cachedir); (*env)->ReleaseStringUTFChars(env, j_sdcard, sdcard); (*env)->ReleaseStringUTFChars(env, j_android_id, android_id); gconf.concurrency = sysconf(_SC_NPROCESSORS_CONF); setlocale(LC_ALL, ""); signal(SIGPIPE, SIG_IGN); main_init(); jclass c = (*env)->FindClass(env, "com/lonelycoder/mediaplayer/Core"); STCore = (*env)->NewGlobalRef(env, c); prop_jni_init(env); service_create("music", "Music", "file:///sdcard/Music", "music", NULL, 0, 1, SVC_ORIGIN_SYSTEM); service_create("music", "Movies", "file:///sdcard/Movies", "video", NULL, 0, 1, SVC_ORIGIN_SYSTEM); android_nav = nav_spawn(); }
void problem_data_add_basics(problem_data_t *pd) { const char *analyzer = problem_data_get_content_or_NULL(pd, FILENAME_ANALYZER); const char *type = problem_data_get_content_or_NULL(pd, FILENAME_TYPE); if (analyzer == NULL) { analyzer = type ? type : "libreport"; problem_data_add_text_noteditable(pd, FILENAME_ANALYZER, analyzer); } if (type == NULL) problem_data_add_text_noteditable(pd, FILENAME_TYPE, analyzer); /* If application didn't provide dupe hash, we generate it * from all components, so we at least eliminate the exact same * reports * * We don't want to generate DUPHASH file because it is usually generated * later in some "analyze_*" event. DUPHASH was originally designed as * global problem identifier and generating of global identifier requires * more space and data. On the contrary UUID was originally designed as * local problem identifier. It means that this identifier is weaker (e.g. * a hash generated from a coredump without debuginfo - there can be many * similar backtraces without line numbers and function names). */ if (problem_data_get_content_or_NULL(pd, FILENAME_UUID) == NULL) { /* If application provided DUPHASH, we should use it in UUID as well. * Otherwise we compute hash from all problem's data. */ const char *const duphash = problem_data_get_content_or_NULL(pd, FILENAME_DUPHASH); if (duphash != NULL) problem_data_add_text_noteditable(pd, FILENAME_UUID, duphash); else { /* start hash */ sha1_ctx_t sha1ctx; sha1_begin(&sha1ctx); /* * To avoid spurious hash differences, sort keys so that elements are * always processed in the same order: */ GList *list = g_hash_table_get_keys(pd); list = g_list_sort(list, (GCompareFunc)strcmp); GList *l = list; while (l) { const char *key = l->data; l = l->next; struct problem_item *item = g_hash_table_lookup(pd, key); /* do not hash items which are binary (item->flags & CD_FLAG_BIN). * Their ->content is full file name, with path. Path is always * different and will make hash differ even if files are the same. */ if (item->flags & CD_FLAG_BIN) continue; sha1_hash(&sha1ctx, item->content, strlen(item->content)); } g_list_free(list); /* end hash */ char hash_bytes[SHA1_RESULT_LEN]; sha1_end(&sha1ctx, hash_bytes); char hash_str[SHA1_RESULT_LEN*2 + 1]; bin2hex(hash_str, hash_bytes, SHA1_RESULT_LEN)[0] = '\0'; problem_data_add_text_noteditable(pd, FILENAME_UUID, hash_str); } } }
/* * Attempt to parse a data blob for a key as an X509 certificate. */ static int x509_key_preparse(struct key_preparsed_payload *prep) { struct asymmetric_key_ids *kids; struct x509_certificate *cert; const char *q; size_t srlen, sulen; char *desc = NULL, *p; int ret; cert = x509_cert_parse(prep->data, prep->datalen); if (IS_ERR(cert)) return PTR_ERR(cert); pr_devel("Cert Issuer: %s\n", cert->issuer); pr_devel("Cert Subject: %s\n", cert->subject); if (cert->pub->pkey_algo >= PKEY_ALGO__LAST || cert->sig.pkey_algo >= PKEY_ALGO__LAST || cert->sig.pkey_hash_algo >= PKEY_HASH__LAST || !pkey_algo[cert->pub->pkey_algo] || !pkey_algo[cert->sig.pkey_algo] || !hash_algo_name[cert->sig.pkey_hash_algo]) { ret = -ENOPKG; goto error_free_cert; } pr_devel("Cert Key Algo: %s\n", pkey_algo_name[cert->pub->pkey_algo]); pr_devel("Cert Valid period: %lld-%lld\n", cert->valid_from, cert->valid_to); pr_devel("Cert Signature: %s + %s\n", pkey_algo_name[cert->sig.pkey_algo], hash_algo_name[cert->sig.pkey_hash_algo]); cert->pub->algo = pkey_algo[cert->pub->pkey_algo]; cert->pub->id_type = PKEY_ID_X509; /* Check the signature on the key if it appears to be self-signed */ if ((!cert->akid_skid && !cert->akid_id) || asymmetric_key_id_same(cert->skid, cert->akid_skid) || asymmetric_key_id_same(cert->id, cert->akid_id)) { ret = x509_check_signature(cert->pub, cert); /* self-signed */ if (ret < 0) goto error_free_cert; } else if (!prep->trusted) { ret = x509_validate_trust(cert, get_system_trusted_keyring()); if (ret) ret = x509_validate_trust(cert, get_ima_mok_keyring()); if (!ret) prep->trusted = 1; } /* Propose a description */ sulen = strlen(cert->subject); if (cert->raw_skid) { srlen = cert->raw_skid_size; q = cert->raw_skid; } else { srlen = cert->raw_serial_size; q = cert->raw_serial; } ret = -ENOMEM; desc = kmalloc(sulen + 2 + srlen * 2 + 1, GFP_KERNEL); if (!desc) goto error_free_cert; p = memcpy(desc, cert->subject, sulen); p += sulen; *p++ = ':'; *p++ = ' '; p = bin2hex(p, q, srlen); *p = 0; kids = kmalloc(sizeof(struct asymmetric_key_ids), GFP_KERNEL); if (!kids) goto error_free_desc; kids->id[0] = cert->id; kids->id[1] = cert->skid; /* We're pinning the module by being linked against it */ __module_get(public_key_subtype.owner); prep->payload.data[asym_subtype] = &public_key_subtype; prep->payload.data[asym_key_ids] = kids; prep->payload.data[asym_crypto] = cert->pub; prep->description = desc; prep->quotalen = 100; /* We've finished with the certificate */ cert->pub = NULL; cert->id = NULL; cert->skid = NULL; desc = NULL; ret = 0; error_free_desc: kfree(desc); error_free_cert: x509_free_certificate(cert); return ret; }
/** * Received a connection request. * @param fd: file descriptor to parse from (client) * @param sd: client session * @param command: packet type sent * @param ip: ipv4 address (client) * S 0064 <version>.L <username>.24B <password>.24B <clienttype>.B * S 0277 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B * S 02b0 <version>.L <username>.24B <password>.24B <clienttype>.B <ip address>.16B <adapter address>.13B <g_isGravityID>.B * S 01dd <version>.L <username>.24B <password hash>.16B <clienttype>.B * S 01fa <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.B(index of the connection in the clientinfo file (+10 if the command-line contains "pc")) * S 027c <version>.L <username>.24B <password hash>.16B <clienttype>.B <?>.13B(junk) * S 0825 <packetsize>.W <version>.L <clienttype>.B <userid>.24B <password>.27B <mac>.17B <ip>.15B <token>.(packetsize - 0x5C)B * @param fd: fd to parse from (client fd) * @return 0 failure, 1 success */ static int logclif_parse_reqauth(int fd, struct login_session_data *sd, int command, char* ip){ size_t packet_len = RFIFOREST(fd); if( (command == 0x0064 && packet_len < 55) || (command == 0x0277 && packet_len < 84) || (command == 0x02b0 && packet_len < 85) || (command == 0x01dd && packet_len < 47) || (command == 0x01fa && packet_len < 48) || (command == 0x027c && packet_len < 60) || (command == 0x0825 && (packet_len < 4 || packet_len < RFIFOW(fd, 2))) ) return 0; else { int result; char username[NAME_LENGTH]; char password[PASSWD_LENGTH]; unsigned char passhash[16]; uint8 clienttype; bool israwpass = (command==0x0064 || command==0x0277 || command==0x02b0 || command == 0x0825); // Shinryo: For the time being, just use token as password. if(command == 0x0825) { char *accname = RFIFOCP(fd, 9); char *token = RFIFOCP(fd, 0x5C); size_t uAccLen = strlen(accname); size_t uTokenLen = RFIFOREST(fd) - 0x5C; if(uAccLen > NAME_LENGTH - 1 || uAccLen == 0 || uTokenLen > NAME_LENGTH - 1 || uTokenLen == 0) { logclif_auth_failed(sd, 3); return 0; } safestrncpy(username, accname, uAccLen + 1); safestrncpy(password, token, uTokenLen + 1); clienttype = RFIFOB(fd, 8); } else { safestrncpy(username, RFIFOCP(fd,6), NAME_LENGTH); if( israwpass ) { safestrncpy(password, RFIFOCP(fd,30), PASSWD_LENGTH); clienttype = RFIFOB(fd,54); } else { memcpy(passhash, RFIFOP(fd,30), 16); clienttype = RFIFOB(fd,46); } } RFIFOSKIP(fd,RFIFOREST(fd)); // assume no other packet was sent sd->clienttype = clienttype; safestrncpy(sd->userid, username, NAME_LENGTH); if( israwpass ) { ShowStatus("Request for connection of %s (ip: %s)\n", sd->userid, ip); safestrncpy(sd->passwd, password, NAME_LENGTH); if( login_config.use_md5_passwds ) MD5_String(sd->passwd, sd->passwd); sd->passwdenc = 0; } else { ShowStatus("Request for connection (passwdenc mode) of %s (ip: %s)\n", sd->userid, ip); bin2hex(sd->passwd, passhash, 16); // raw binary data here! sd->passwdenc = PASSWORDENC; } if( sd->passwdenc != 0 && login_config.use_md5_passwds ) { logclif_auth_failed(sd, 3); // send "rejected from server" return 0; } result = login_mmo_auth(sd, false); if( result == -1 ) logclif_auth_ok(sd); else logclif_auth_failed(sd, result); } return 1; }
/** * x509_request_asymmetric_key - Request a key by X.509 certificate params. * @keyring: The keys to search. * @id: The issuer & serialNumber to look for or NULL. * @skid: The subjectKeyIdentifier to look for or NULL. * @partial: Use partial match if true, exact if false. * * Find a key in the given keyring by identifier. The preferred identifier is * the issuer + serialNumber and the fallback identifier is the * subjectKeyIdentifier. If both are given, the lookup is by the former, but * the latter must also match. */ struct key *x509_request_asymmetric_key(struct key *keyring, const struct asymmetric_key_id *id, const struct asymmetric_key_id *skid, bool partial) { struct key *key; key_ref_t ref; const char *lookup; char *req, *p; int len; if (id) { lookup = id->data; len = id->len; } else { lookup = skid->data; len = skid->len; } /* Construct an identifier "id:<keyid>". */ p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL); if (!req) return ERR_PTR(-ENOMEM); if (partial) { *p++ = 'i'; *p++ = 'd'; } else { *p++ = 'e'; *p++ = 'x'; } *p++ = ':'; p = bin2hex(p, lookup, len); *p = 0; pr_debug("Look up: \"%s\"\n", req); ref = keyring_search(make_key_ref(keyring, 1), &key_type_asymmetric, req); if (IS_ERR(ref)) pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref)); kfree(req); if (IS_ERR(ref)) { switch (PTR_ERR(ref)) { /* Hide some search errors */ case -EACCES: case -ENOTDIR: case -EAGAIN: return ERR_PTR(-ENOKEY); default: return ERR_CAST(ref); } } key = key_ref_to_ptr(ref); if (id && skid) { const struct asymmetric_key_ids *kids = asymmetric_key_ids(key); if (!kids->id[1]) { pr_debug("issuer+serial match, but expected SKID missing\n"); goto reject; } if (!asymmetric_key_id_same(skid, kids->id[1])) { pr_debug("issuer+serial match, but SKID does not\n"); goto reject; } } pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key)); return key; reject: key_put(key); return ERR_PTR(-EKEYREJECTED); }
int popmaildir_main(int argc UNUSED_PARAM, char **argv) { char *buf; unsigned nmsg; char *hostname; pid_t pid; const char *retr; #if ENABLE_FEATURE_POPMAILDIR_DELIVERY const char *delivery; #endif unsigned opt_nlines = 0; enum { OPT_b = 1 << 0, // -b binary mode. Ignored OPT_d = 1 << 1, // -d,-dd,-ddd debug. Ignored OPT_m = 1 << 2, // -m show ugsed memory. Ignored OPT_V = 1 << 3, // -V version. Ignored OPT_c = 1 << 4, // -c use tcpclient. Ignored OPT_a = 1 << 5, // -a use APOP protocol OPT_s = 1 << 6, // -s skip authorization OPT_T = 1 << 7, // -T get messages with TOP instead with RETR OPT_k = 1 << 8, // -k keep retrieved messages on the server OPT_t = 1 << 9, // -t90 set timeout to 90 sec OPT_R = 1 << 10, // -R20000 remove old messages on the server >= 20000 bytes (requires -k). Ignored OPT_Z = 1 << 11, // -Z11-23 remove messages from 11 to 23 (dangerous). Ignored OPT_L = 1 << 12, // -L50000 not retrieve new messages >= 50000 bytes. Ignored OPT_H = 1 << 13, // -H30 type first 30 lines of a message; (-L12000 -H30). Ignored OPT_M = 1 << 14, // -M\"program arg1 arg2 ...\"; deliver by program. Treated like -F OPT_F = 1 << 15, // -F\"program arg1 arg2 ...\"; filter by program. Treated like -M }; // init global variables INIT_G(); // parse options opt_complementary = "-1:dd:t+:R+:L+:H+"; opts = getopt32(argv, "bdmVcasTkt:" "R:Z:L:H:" IF_FEATURE_POPMAILDIR_DELIVERY("M:F:"), &timeout, NULL, NULL, NULL, &opt_nlines IF_FEATURE_POPMAILDIR_DELIVERY(, &delivery, &delivery) // we treat -M and -F the same ); //argc -= optind; argv += optind; // get auth info if (!(opts & OPT_s)) get_cred_or_die(STDIN_FILENO); // goto maildir xchdir(*argv++); // launch connect helper, if any if (*argv) launch_helper((const char **)argv); // get server greeting pop3_checkr(NULL, NULL, &buf); // authenticate (if no -s given) if (!(opts & OPT_s)) { // server supports APOP and we want it? if ('<' == buf[0] && (opts & OPT_a)) { union { // save a bit of stack md5_ctx_t ctx; char hex[16 * 2 + 1]; } md5; uint32_t res[16 / 4]; char *s = strchr(buf, '>'); if (s) s[1] = '\0'; // get md5 sum of "<stamp>password" string md5_begin(&md5.ctx); md5_hash(&md5.ctx, buf, strlen(buf)); md5_hash(&md5.ctx, G.pass, strlen(G.pass)); md5_end(&md5.ctx, res); *bin2hex(md5.hex, (char*)res, 16) = '\0'; // APOP s = xasprintf("%s %s", G.user, md5.hex); pop3_check("APOP %s", s); free(s); free(buf); // server ignores APOP -> use simple text authentication } else { // USER pop3_check("USER %s", G.user); // PASS pop3_check("PASS %s", G.pass); } } // get mailbox statistics pop3_checkr("STAT", NULL, &buf); // prepare message filename suffix hostname = safe_gethostname(); pid = getpid(); // get messages counter // NOTE: we don't use xatou(buf) since buf is "nmsg nbytes" // we only need nmsg and atoi is just exactly what we need // if atoi fails to convert buf into number it returns 0 // in this case the following loop simply will not be executed nmsg = atoi(buf); free(buf); // loop through messages retr = (opts & OPT_T) ? xasprintf("TOP %%u %u", opt_nlines) : "RETR %u"; for (; nmsg; nmsg--) { char *filename; char *target; char *answer; FILE *fp; #if ENABLE_FEATURE_POPMAILDIR_DELIVERY int rc; #endif // generate unique filename filename = xasprintf("tmp/%llu.%u.%s", monotonic_us(), (unsigned)pid, hostname); // retrieve message in ./tmp/ unless filter is specified pop3_check(retr, (const char *)(ptrdiff_t)nmsg); #if ENABLE_FEATURE_POPMAILDIR_DELIVERY // delivery helper ordered? -> setup pipe if (opts & (OPT_F|OPT_M)) { // helper will have $FILENAME set to filename xsetenv("FILENAME", filename); fp = popen(delivery, "w"); unsetenv("FILENAME"); if (!fp) { bb_perror_msg("delivery helper"); break; } } else #endif // create and open file filename fp = xfopen_for_write(filename); // copy stdin to fp (either filename or delivery helper) while ((answer = xmalloc_fgets_str(stdin, "\r\n")) != NULL) { char *s = answer; if ('.' == answer[0]) { if ('.' == answer[1]) s++; else if ('\r' == answer[1] && '\n' == answer[2] && '\0' == answer[3]) break; } //*strchrnul(s, '\r') = '\n'; fputs(s, fp); free(answer); } #if ENABLE_FEATURE_POPMAILDIR_DELIVERY // analyse delivery status if (opts & (OPT_F|OPT_M)) { rc = pclose(fp); if (99 == rc) // 99 means bail out break; // if (rc) // !0 means skip to the next message goto skip; // // 0 means continue } else { // close filename fclose(fp); } #endif // delete message from server if (!(opts & OPT_k)) pop3_check("DELE %u", (const char*)(ptrdiff_t)nmsg); // atomically move message to ./new/ target = xstrdup(filename); strncpy(target, "new", 3); // ... or just stop receiving on failure if (rename_or_warn(filename, target)) break; free(target); #if ENABLE_FEATURE_POPMAILDIR_DELIVERY skip: #endif free(filename); } // Bye pop3_check("QUIT", NULL); if (ENABLE_FEATURE_CLEAN_UP) { free(G.user); free(G.pass); } return EXIT_SUCCESS; }
int main(int argc, char *argv[]) { DIR *dfd; char **files = NULL; struct dirent *dp; uint32_t fno = 0; uint8_t *out; char *output; int shake = 0, sha = 0, quiet = 0; unsigned long bytes = 0; char *dirname = ""; // parse arguments for (int i = 1; i < argc; i++) { if (strcmp("--shake128", argv[i]) == 0) { shake = 128; sha = 0; } else if (strcmp("--shake256", argv[i]) == 0) { shake = 256; sha = 0; } else if (strcmp("--sha3-224", argv[i]) == 0) { sha = 224; shake = 0; } else if (strcmp("--sha3-256", argv[i]) == 0) { sha = 256; shake = 0; } else if (strcmp("--sha3-384", argv[i]) == 0) { sha = 384; shake = 0; } else if (strcmp("--sha3-512", argv[i]) == 0) { sha = 512; shake = 0; } else if (strcmp("--quiet", argv[i]) == 0) { quiet = 1; } else if (strcmp("--bytes", argv[i]) == 0) { char **invalid; invalid = malloc(sizeof(char **)); bytes = strtoul(argv[i + 1], invalid, 10); if (bytes == 0 && argv[i + 1] == *invalid) { printf("--bytes must be followed by the amount of bytes " "desired as output."); free(invalid); return -1; } i++; free(invalid); continue; } else if (strcmp("--help", argv[i]) == 0) { usage(argv[0]); exit(EXIT_SUCCESS); } else { if (strlen(argv[i]) > 2) { if ((argv[i][0] == '-') && (argv[i][1] == '-')) { printf("Unknown option '%s'\n", argv[i]); return -1; } } if (strlen(dirname) > 1) { printf("Cannot specify more than one directory.\n"); return -1; } dirname = argv[i]; } } // open directory if ((dfd = opendir(dirname)) == NULL) { panic(argv[0], "cannot find directory '%s' or read access denied.", 1, dirname); } // build array of files while ((dp = readdir(dfd)) != NULL) { if (dp->d_name[0] == '.') { continue; } // resolve path: dirname + '/' + dp->d_name + '\0' char *file = malloc(strlen(dirname) + 1 + strlen(dp->d_name) + 1); snprintf(file, strlen(dirname) + 1 + strlen(dp->d_name) + 1, "%s/%s", dirname, dp->d_name); // add file to list files = realloc(files, sizeof(char *) * (fno + 1)); files[fno] = file; fno++; } if (shake != 0) { // we are asked for a shake hash (extensible output) switch (shake) { case 128: if (bytes == 0) { bytes = 32; } out = malloc(bytes); shakef128(out, bytes, files, fno); break; default: if (bytes == 0) { bytes = 64; } out = malloc(bytes); shakef256(out, bytes, files, fno); } } else { // we are asked for a SHA3 hash (fixed-length output) if (bytes != 0) { printf("Cannot specify output bytes with fixed-size SHA3 " "functions.\n"); return -1; } switch (sha) { case 224: bytes = 28; out = malloc(bytes); sha3f_224(out, 28, files, fno); break; case 384: bytes = 48; out = malloc(bytes); sha3f_384(out, 48, files, fno); break; case 512: bytes = 64; out = malloc(bytes); sha3f_512(out, 64, files, fno); break; default: bytes = 32; out = malloc(bytes); sha3f_256(out, 32, files, fno); } } // convert to hex and print bin2hex(&output, out, (int)bytes); if (quiet) { printf("%s\n", output); } else { printf("%s - %s\n", output, dirname); } free(files); closedir(dfd); free(out); free(output); return EXIT_SUCCESS; }
/* Get the key described key the KEYSPEC string from the keyserver identified by URI. On success R_FP has an open stream to read the data. The data will be provided in a format GnuPG can import (either a binary OpenPGP message or an armored one). */ gpg_error_t ks_hkp_get (ctrl_t ctrl, parsed_uri_t uri, const char *keyspec, estream_t *r_fp) { gpg_error_t err; KEYDB_SEARCH_DESC desc; char kidbuf[2+40+1]; const char *exactname = NULL; char *searchkey = NULL; char *hostport = NULL; char *request = NULL; estream_t fp = NULL; int reselect; char *httphost = NULL; unsigned int httpflags; unsigned int tries = SEND_REQUEST_RETRIES; *r_fp = NULL; /* Remove search type indicator and adjust PATTERN accordingly. Note that HKP keyservers like the 0x to be present when searching by keyid. We need to re-format the fingerprint and keyids so to remove the gpg specific force-use-of-this-key flag ("!"). */ err = classify_user_id (keyspec, &desc, 1); if (err) return err; switch (desc.mode) { case KEYDB_SEARCH_MODE_SHORT_KID: snprintf (kidbuf, sizeof kidbuf, "0x%08lX", (ulong)desc.u.kid[1]); break; case KEYDB_SEARCH_MODE_LONG_KID: snprintf (kidbuf, sizeof kidbuf, "0x%08lX%08lX", (ulong)desc.u.kid[0], (ulong)desc.u.kid[1]); break; case KEYDB_SEARCH_MODE_FPR20: case KEYDB_SEARCH_MODE_FPR: /* This is a v4 fingerprint. */ kidbuf[0] = '0'; kidbuf[1] = 'x'; bin2hex (desc.u.fpr, 20, kidbuf+2); break; case KEYDB_SEARCH_MODE_EXACT: exactname = desc.u.name; break; case KEYDB_SEARCH_MODE_FPR16: log_error ("HKP keyservers do not support v3 fingerprints\n"); default: return gpg_error (GPG_ERR_INV_USER_ID); } searchkey = http_escape_string (exactname? exactname : kidbuf, EXTRA_ESCAPE_CHARS); if (!searchkey) { err = gpg_error_from_syserror (); goto leave; } reselect = 0; again: /* Build the request string. */ xfree (hostport); hostport = NULL; xfree (httphost); httphost = NULL; err = make_host_part (ctrl, uri->scheme, uri->host, uri->port, reselect, &hostport, &httpflags, &httphost); if (err) goto leave; xfree (request); request = strconcat (hostport, "/pks/lookup?op=get&options=mr&search=", searchkey, exactname? "&exact=on":"", NULL); if (!request) { err = gpg_error_from_syserror (); goto leave; } /* Send the request. */ err = send_request (ctrl, request, hostport, httphost, httpflags, NULL, NULL, &fp); if (handle_send_request_error (err, request, &tries)) { reselect = 1; goto again; } if (err) goto leave; err = dirmngr_status (ctrl, "SOURCE", hostport, NULL); if (err) goto leave; /* Return the read stream and close the HTTP context. */ *r_fp = fp; fp = NULL; leave: es_fclose (fp); xfree (request); xfree (hostport); xfree (httphost); xfree (searchkey); return err; }
int ddocLocateSlotWithSignatureCert(LIBHANDLE pLibrary, CK_SLOT_ID* slotids, CK_SLOT_ID* pSlotId, X509** ppCert, char idData[20], int* pIdLen, int nSlot, int* pIdx) { int err = ERR_PRIVKEY_READ, i, j, nMatch, l3; CK_RV rv; CK_SESSION_HANDLE hSession = 0; CK_OBJECT_HANDLE objects[10]; CK_BYTE buf2[20], buf3[40]; CK_ULONG ulObjectCount = sizeof(objects)/sizeof(CK_OBJECT_HANDLE), ulCount = 0, l1 = 0, l2 = 0; CK_OBJECT_CLASS ObjClass = CKO_CERTIFICATE; CK_ATTRIBUTE Template1[] = { { CKA_CLASS, &ObjClass, sizeof(ObjClass) } }; CK_ATTRIBUTE Template2[] = { { CKA_VALUE, (void*)0, l1 }, { CKA_ID, (void*)0, sizeof(buf2)} }; char buf1[3000]; X509* pCert; RETURN_IF_NULL_PARAM(pLibrary); RETURN_IF_NULL_PARAM(pSlotId); RETURN_IF_NULL_PARAM(slotids); RETURN_IF_NULL_PARAM(idData); RETURN_IF_NULL_PARAM(ppCert); // mark as not found memset(idData, 0, *pIdLen); ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Driver handle: %d err = %d", pLibrary, err); // now check every slot for(i = 0, nMatch = 0; (i < 20) && !(*ppCert); i++) { if(slotids[i] != INVALID_SLOTIID) { ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Checking slot nr: %d id: %d", i, slotids[i]); // open session to slot but no login since we just need the cert rv = (*ckFunc->C_OpenSession)(slotids[i], CKF_SERIAL_SESSION,0,0,&hSession); ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Login rv: %ld session: %ld", rv, hSession); if(rv == CKR_OK) { ulCount = sizeof(Template1)/sizeof(CK_ATTRIBUTE); rv = (*ckFunc->C_FindObjectsInit)(hSession, Template1, ulCount); if(rv == CKR_OK) { rv = (*ckFunc->C_FindObjects)(hSession, objects, ulObjectCount, &ulObjectCount); ddocDebug(3, "ddocLocateSlotWithSignatureCert", "slot id: %ld, objects: %ld", slotids[i], ulObjectCount); if(rv == CKR_OK && ulObjectCount > 0) { ulCount = sizeof(Template2) / sizeof(CK_ATTRIBUTE); for(j = 0; j < (int)ulObjectCount; j++) { l1 = sizeof(buf1); memset(buf1, 0, l1); l2 = sizeof(buf2); memset(buf2, 0, l2); //Template2[0].pValue = 0; // check length first rv = (*ckFunc->C_GetAttributeValue)(hSession, objects[j], Template2, ulCount); if(rv == CKR_OK && Template2[0].ulValueLen < sizeof(buf1)) { l1 = Template2[0].ulValueLen; // now get cert data Template2[0].pValue = buf1; Template2[1].pValue = buf2; rv = (*ckFunc->C_GetAttributeValue)(hSession, objects[j], Template2, ulCount); ddocDebug(3, "ddocLocateSlotWithSignatureCert", "slot id: %ld, object: %ld cert-len: %ld rv: %ld", slotids[i], j, l1, rv); pCert = 0; err = ddocDecodeX509Data(&pCert, (const byte*)buf1, l1); if(pCert) { if(ddocCertCheckKeyUsage(pCert, KUIDX_NON_REPUDIATION)) { if((!nSlot || nSlot == nMatch) && !(*ppCert)) { l3 = sizeof(buf3); memset(buf3, 0, l3); bin2hex((const byte*)buf2, (int)Template2[1].ulValueLen, (char*)buf3, &l3); ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Selecting slot: %d id: %d key-id %s", i, slotids[i], buf3); *pSlotId = slotids[i]; *pIdx = i; // keep this cert for signing if(*ppCert) X509_free(*ppCert); (*ppCert) = pCert; pCert = NULL; // mark as used memcpy(idData, buf2, Template2[1].ulValueLen); *pIdLen = Template2[1].ulValueLen; err = ERR_OK; // found it } else { // useable slot but not a match by slot id ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Useable slot: %d but search: %d", nMatch, nSlot); nMatch++; } } // if non-repu cert } // if pCert if(pCert) X509_free(pCert); pCert = 0; } // if get-attribute ok } // for j < ulObjectCount } // if found any certs } // if find-init ok rv = (*ckFunc->C_FindObjectsFinal)(hSession); } // if login ok rv = (*ckFunc->C_CloseSession)(hSession); } // if slotid } // for i return err; }
/**************** * Decrypt the data, specified by ED with the key DEK. */ int decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek) { decode_filter_ctx_t dfx; byte *p; int rc=0, c, i; byte temp[32]; unsigned blocksize; unsigned nprefix; dfx = xtrycalloc (1, sizeof *dfx); if (!dfx) return gpg_error_from_syserror (); dfx->refcount = 1; if ( opt.verbose && !dek->algo_info_printed ) { if (!openpgp_cipher_test_algo (dek->algo)) log_info (_("%s encrypted data\n"), openpgp_cipher_algo_name (dek->algo)); else log_info (_("encrypted with unknown algorithm %d\n"), dek->algo ); dek->algo_info_printed = 1; } { char buf[20]; snprintf (buf, sizeof buf, "%d %d", ed->mdc_method, dek->algo); write_status_text (STATUS_DECRYPTION_INFO, buf); } if (opt.show_session_key) { char numbuf[25]; char *hexbuf; snprintf (numbuf, sizeof numbuf, "%d:", dek->algo); hexbuf = bin2hex (dek->key, dek->keylen, NULL); if (!hexbuf) { rc = gpg_error_from_syserror (); goto leave; } log_info ("session key: '%s%s'\n", numbuf, hexbuf); write_status_strings (STATUS_SESSION_KEY, numbuf, hexbuf, NULL); xfree (hexbuf); } rc = openpgp_cipher_test_algo (dek->algo); if (rc) goto leave; blocksize = openpgp_cipher_get_algo_blklen (dek->algo); if ( !blocksize || blocksize > 16 ) log_fatal ("unsupported blocksize %u\n", blocksize ); nprefix = blocksize; if ( ed->len && ed->len < (nprefix+2) ) { /* An invalid message. We can't check that during parsing because we may not know the used cipher then. */ rc = gpg_error (GPG_ERR_INV_PACKET); goto leave; } if ( ed->mdc_method ) { if (gcry_md_open (&dfx->mdc_hash, ed->mdc_method, 0 )) BUG (); if ( DBG_HASHING ) gcry_md_debug (dfx->mdc_hash, "checkmdc"); } rc = openpgp_cipher_open (&dfx->cipher_hd, dek->algo, GCRY_CIPHER_MODE_CFB, (GCRY_CIPHER_SECURE | ((ed->mdc_method || dek->algo >= 100)? 0 : GCRY_CIPHER_ENABLE_SYNC))); if (rc) { /* We should never get an error here cause we already checked * that the algorithm is available. */ BUG(); } /* log_hexdump( "thekey", dek->key, dek->keylen );*/ rc = gcry_cipher_setkey (dfx->cipher_hd, dek->key, dek->keylen); if ( gpg_err_code (rc) == GPG_ERR_WEAK_KEY ) { log_info(_("WARNING: message was encrypted with" " a weak key in the symmetric cipher.\n")); rc=0; } else if( rc ) { log_error("key setup failed: %s\n", gpg_strerror (rc) ); goto leave; } if (!ed->buf) { log_error(_("problem handling encrypted packet\n")); goto leave; } gcry_cipher_setiv (dfx->cipher_hd, NULL, 0); if ( ed->len ) { for (i=0; i < (nprefix+2) && ed->len; i++, ed->len-- ) { if ( (c=iobuf_get(ed->buf)) == -1 ) break; else temp[i] = c; } } else { for (i=0; i < (nprefix+2); i++ ) if ( (c=iobuf_get(ed->buf)) == -1 ) break; else temp[i] = c; } gcry_cipher_decrypt (dfx->cipher_hd, temp, nprefix+2, NULL, 0); gcry_cipher_sync (dfx->cipher_hd); p = temp; /* log_hexdump( "prefix", temp, nprefix+2 ); */ if (dek->symmetric && (p[nprefix-2] != p[nprefix] || p[nprefix-1] != p[nprefix+1]) ) { rc = gpg_error (GPG_ERR_BAD_KEY); goto leave; } if ( dfx->mdc_hash ) gcry_md_write (dfx->mdc_hash, temp, nprefix+2); dfx->refcount++; dfx->partial = ed->is_partial; dfx->length = ed->len; if ( ed->mdc_method ) iobuf_push_filter ( ed->buf, mdc_decode_filter, dfx ); else iobuf_push_filter ( ed->buf, decode_filter, dfx ); if (opt.unwrap_encryption) { char *filename; estream_t fp; rc = get_output_file ("", 0, ed->buf, &filename, &fp); if (! rc) { iobuf_t output = iobuf_esopen (fp, "w", 0); armor_filter_context_t *afx = NULL; if (opt.armor) { afx = new_armor_context (); push_armor_filter (afx, output); } iobuf_copy (output, ed->buf); if ((rc = iobuf_error (ed->buf))) log_error (_("error reading '%s': %s\n"), filename, gpg_strerror (rc)); else if ((rc = iobuf_error (output))) log_error (_("error writing '%s': %s\n"), filename, gpg_strerror (rc)); iobuf_close (output); if (afx) release_armor_context (afx); } } else proc_packets (ctrl, procctx, ed->buf ); ed->buf = NULL; if (dfx->eof_seen > 1 ) rc = gpg_error (GPG_ERR_INV_PACKET); else if ( ed->mdc_method ) { /* We used to let parse-packet.c handle the MDC packet but this turned out to be a problem with compressed packets: With old style packets there is no length information available and the decompressor uses an implicit end. However we can't know this implicit end beforehand (:-) and thus may feed the decompressor with more bytes than actually needed. It would be possible to unread the extra bytes but due to our weird iobuf system any unread is non reliable due to filters already popped off. The easy and sane solution is to care about the MDC packet only here and never pass it to the packet parser. Fortunatley the OpenPGP spec requires a strict format for the MDC packet so that we know that 22 bytes are appended. */ int datalen = gcry_md_get_algo_dlen (ed->mdc_method); log_assert (dfx->cipher_hd); log_assert (dfx->mdc_hash); gcry_cipher_decrypt (dfx->cipher_hd, dfx->defer, 22, NULL, 0); gcry_md_write (dfx->mdc_hash, dfx->defer, 2); gcry_md_final (dfx->mdc_hash); if ( dfx->defer[0] != '\xd3' || dfx->defer[1] != '\x14' || datalen != 20 || memcmp (gcry_md_read (dfx->mdc_hash, 0), dfx->defer+2, datalen)) rc = gpg_error (GPG_ERR_BAD_SIGNATURE); /* log_printhex("MDC message:", dfx->defer, 22); */ /* log_printhex("MDC calc:", gcry_md_read (dfx->mdc_hash,0), datalen); */ } leave: release_dfx_context (dfx); return rc; }
/* * Ask the GPG Agent for the passphrase. * Mode 0: Allow cached passphrase * 1: No cached passphrase; that is we are asking for a new passphrase * FIXME: Only partially implemented * * Note that TRYAGAIN_TEXT must not be translated. If CANCELED is not * NULL, the function does set it to 1 if the user canceled the * operation. If CACHEID is not NULL, it will be used as the cacheID * for the gpg-agent; if is NULL and a key fingerprint can be * computed, this will be used as the cacheid. */ static char * passphrase_get ( u32 *keyid, int mode, const char *cacheid, int repeat, const char *tryagain_text, const char *custom_description, const char *custom_prompt, int *canceled) { int rc; char *atext = NULL; char *pw = NULL; PKT_public_key *pk = xmalloc_clear( sizeof *pk ); byte fpr[MAX_FINGERPRINT_LEN]; int have_fpr = 0; char *orig_codeset; char *my_prompt; char hexfprbuf[20*2+1]; const char *my_cacheid; int check = (mode == 1); if (canceled) *canceled = 0; #if MAX_FINGERPRINT_LEN < 20 #error agent needs a 20 byte fingerprint #endif memset (fpr, 0, MAX_FINGERPRINT_LEN ); if( keyid && get_pubkey( pk, keyid ) ) { if (pk) free_public_key( pk ); pk = NULL; /* oops: no key for some reason */ } orig_codeset = i18n_switchto_utf8 (); if (custom_description) atext = native_to_utf8 (custom_description); else if ( !mode && pk && keyid ) { char *uid; size_t uidlen; const char *algo_name = openpgp_pk_algo_name (pk->pubkey_algo); const char *timestr; char *maink; if ( !algo_name ) algo_name = "?"; #define KEYIDSTRING _(" (main key ID %s)") maink = xmalloc ( strlen (KEYIDSTRING) + keystrlen() + 20 ); if( keyid[2] && keyid[3] && keyid[0] != keyid[2] && keyid[1] != keyid[3] ) sprintf( maink, KEYIDSTRING, keystr(&keyid[2]) ); else *maink = 0; uid = get_user_id ( keyid, &uidlen ); timestr = strtimestamp (pk->timestamp); #undef KEYIDSTRING #define PROMPTSTRING _("Please enter the passphrase to unlock the" \ " secret key for the OpenPGP certificate:\n" \ "\"%.*s\"\n" \ "%u-bit %s key, ID %s,\n" \ "created %s%s.\n" ) atext = xmalloc ( 100 + strlen (PROMPTSTRING) + uidlen + 15 + strlen(algo_name) + keystrlen() + strlen (timestr) + strlen (maink) ); sprintf (atext, PROMPTSTRING, (int)uidlen, uid, nbits_from_pk (pk), algo_name, keystr(&keyid[0]), timestr, maink ); xfree (uid); xfree (maink); #undef PROMPTSTRING { size_t dummy; fingerprint_from_pk( pk, fpr, &dummy ); have_fpr = 1; } } else atext = xstrdup ( _("Enter passphrase\n") ); if (!mode && cacheid) my_cacheid = cacheid; else if (!mode && have_fpr) my_cacheid = bin2hex (fpr, 20, hexfprbuf); else my_cacheid = NULL; if (tryagain_text) tryagain_text = _(tryagain_text); my_prompt = custom_prompt ? native_to_utf8 (custom_prompt): NULL; rc = agent_get_passphrase (my_cacheid, tryagain_text, my_prompt, atext, repeat, check, &pw); xfree (my_prompt); xfree (atext); atext = NULL; i18n_switchback (orig_codeset); if (!rc) ; else if ( gpg_err_code (rc) == GPG_ERR_CANCELED ) { log_info (_("cancelled by user\n") ); if (canceled) *canceled = 1; } else { log_error (_("problem with the agent: %s\n"), gpg_strerror (rc)); /* Due to limitations in the API of the upper layers they consider an error as no passphrase entered. This works in most cases but not during key creation where this should definitely not happen and let it continue without requiring a passphrase. Given that now all the upper layers handle a cancel correctly, we simply set the cancel flag now for all errors from the agent. */ if (canceled) *canceled = 1; write_status_error ("get_passphrase", rc); } if (pk) free_public_key( pk ); if (rc) { xfree (pw); return NULL; } return pw; }
/* Include the implementation of map_spwq_error. */ MAP_SPWQ_ERROR_IMPL static void preset_passphrase (const char *keygrip) { int rc; char *line; /* FIXME: Use secure memory. */ char passphrase[500]; char *passphrase_esc; if (!opt_passphrase) { rc = read (0, passphrase, sizeof (passphrase) - 1); if (rc < 0) { log_error ("reading passphrase failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); return; } passphrase[rc] = '\0'; line = strchr (passphrase, '\n'); if (line) { if (line > passphrase && line[-1] == '\r') line--; *line = '\0'; } /* FIXME: How to handle empty passwords? */ } { const char *s = opt_passphrase ? opt_passphrase : passphrase; passphrase_esc = bin2hex (s, strlen (s), NULL); } if (!passphrase_esc) { log_error ("can not escape string: %s\n", gpg_strerror (gpg_error_from_syserror ())); return; } rc = asprintf (&line, "PRESET_PASSPHRASE %s -1 %s\n", keygrip, passphrase_esc); wipememory (passphrase_esc, strlen (passphrase_esc)); xfree (passphrase_esc); if (rc < 0) { log_error ("caching passphrase failed: %s\n", gpg_strerror (gpg_error_from_syserror ())); return; } if (!opt_passphrase) wipememory (passphrase, sizeof (passphrase)); rc = map_spwq_error (simple_query (line)); if (rc) { log_error ("caching passphrase failed: %s\n", gpg_strerror (rc)); return; } wipememory (line, strlen (line)); xfree (line); }
/* Return a new DEK object Using the string-to-key sepcifier S2K. Use KEYID and PUBKEY_ALGO to prompt the user. Returns NULL is the user selected to cancel the passphrase entry and if CANCELED is not NULL, sets it to true. MODE 0: Allow cached passphrase 1: Ignore cached passphrase 2: Ditto, but create a new key 3: Allow cached passphrase; use the S2K salt as the cache ID 4: Ditto, but create a new key */ DEK * passphrase_to_dek_ext (u32 *keyid, int pubkey_algo, int cipher_algo, STRING2KEY *s2k, int mode, const char *tryagain_text, const char *custdesc, const char *custprompt, int *canceled) { char *pw = NULL; DEK *dek; STRING2KEY help_s2k; int dummy_canceled; char s2k_cacheidbuf[1+16+1], *s2k_cacheid = NULL; if (!canceled) canceled = &dummy_canceled; *canceled = 0; if ( !s2k ) { assert (mode != 3 && mode != 4); /* This is used for the old rfc1991 mode * Note: This must match the code in encode.c with opt.rfc1991 set */ s2k = &help_s2k; s2k->mode = 0; s2k->hash_algo = S2K_DIGEST_ALGO; } /* Create a new salt or what else to be filled into the s2k for a new key. */ if ((mode == 2 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3)) { gcry_randomize (s2k->salt, 8, GCRY_STRONG_RANDOM); if ( s2k->mode == 3 ) { /* We delay the encoding until it is really needed. This is if we are going to dynamically calibrate it, we need to call out to gpg-agent and that should not be done during option processing in main(). */ if (!opt.s2k_count) opt.s2k_count = encode_s2k_iterations (0); s2k->count = opt.s2k_count; } } /* If we do not have a passphrase available in NEXT_PW and status information are request, we print them now. */ if ( !next_pw && is_status_enabled() ) { char buf[50]; if ( keyid ) { u32 used_kid[2]; char *us; if ( keyid[2] && keyid[3] ) { used_kid[0] = keyid[2]; used_kid[1] = keyid[3]; } else { used_kid[0] = keyid[0]; used_kid[1] = keyid[1]; } us = get_long_user_id_string ( keyid ); write_status_text ( STATUS_USERID_HINT, us ); xfree(us); snprintf (buf, sizeof buf -1, "%08lX%08lX %08lX%08lX %d 0", (ulong)keyid[0], (ulong)keyid[1], (ulong)used_kid[0], (ulong)used_kid[1], pubkey_algo ); write_status_text ( STATUS_NEED_PASSPHRASE, buf ); } else { snprintf (buf, sizeof buf -1, "%d %d %d", cipher_algo, s2k->mode, s2k->hash_algo ); write_status_text ( STATUS_NEED_PASSPHRASE_SYM, buf ); } } /* If we do have a keyID, we do not have a passphrase available in NEXT_PW, we are not running in batch mode and we do not want to ignore the passphrase cache (mode!=1), print a prompt with information on that key. */ if ( keyid && !opt.batch && !next_pw && mode!=1 ) { PKT_public_key *pk = xmalloc_clear( sizeof *pk ); char *p; p = get_user_id_native(keyid); tty_printf ("\n"); tty_printf (_("You need a passphrase to unlock the secret key for\n" "user: \"%s\"\n"),p); xfree(p); if ( !get_pubkey( pk, keyid ) ) { const char *s = openpgp_pk_algo_name (pk->pubkey_algo); tty_printf (_("%u-bit %s key, ID %s, created %s"), nbits_from_pk( pk ), s?s:"?", keystr(keyid), strtimestamp(pk->timestamp) ); if ( keyid[2] && keyid[3] && keyid[0] != keyid[2] && keyid[1] != keyid[3] ) { if ( keystrlen () > 10 ) { tty_printf ("\n"); tty_printf (_(" (subkey on main key ID %s)"), keystr(&keyid[2]) ); } else tty_printf ( _(" (main key ID %s)"), keystr(&keyid[2]) ); } tty_printf("\n"); } tty_printf("\n"); if (pk) free_public_key( pk ); } if ( next_pw ) { /* Simply return the passphrase we already have in NEXT_PW. */ pw = next_pw; next_pw = NULL; } else if ( have_static_passphrase () ) { /* Return the passphrase we have stored in FD_PASSWD. */ pw = xmalloc_secure ( strlen(fd_passwd)+1 ); strcpy ( pw, fd_passwd ); } else { if ((mode == 3 || mode == 4) && (s2k->mode == 1 || s2k->mode == 3)) { memset (s2k_cacheidbuf, 0, sizeof s2k_cacheidbuf); *s2k_cacheidbuf = 'S'; bin2hex (s2k->salt, 8, s2k_cacheidbuf + 1); s2k_cacheid = s2k_cacheidbuf; } /* Divert to the gpg-agent. */ pw = passphrase_get (keyid, mode == 2, s2k_cacheid, (mode == 2 || mode == 4)? opt.passphrase_repeat : 0, tryagain_text, custdesc, custprompt, canceled); if (*canceled) { xfree (pw); write_status( STATUS_MISSING_PASSPHRASE ); return NULL; } } if ( !pw || !*pw ) write_status( STATUS_MISSING_PASSPHRASE ); /* Hash the passphrase and store it in a newly allocated DEK object. Keep a copy of the passphrase in LAST_PW for use by get_last_passphrase(). */ dek = xmalloc_secure_clear ( sizeof *dek ); dek->algo = cipher_algo; if ( (!pw || !*pw) && (mode == 2 || mode == 4)) dek->keylen = 0; else hash_passphrase (dek, pw, s2k); if (s2k_cacheid) memcpy (dek->s2k_cacheid, s2k_cacheid, sizeof dek->s2k_cacheid); xfree(last_pw); last_pw = pw; return dek; }
/* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP should be the hex encoded keygrip of that key to be used with the caching mechanism. DESC_TEXT may be set to override the default description used for the pinentry. If LOOKUP_TTL is given this function is used to lookup the default ttl. If R_PASSPHRASE is not NULL, the function succeeded and the key was protected the used passphrase (entered or from the cache) is stored there; if not NULL will be stored. The caller needs to free the returned passphrase. */ static int unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, unsigned char **keybuf, const unsigned char *grip, cache_mode_t cache_mode, lookup_ttl_t lookup_ttl, char **r_passphrase) { struct pin_entry_info_s *pi; struct try_unprotect_arg_s arg; int rc; unsigned char *result; size_t resultlen; char hexgrip[40+1]; if (r_passphrase) *r_passphrase = NULL; bin2hex (grip, 20, hexgrip); /* Initially try to get it using a cache nonce. */ if (cache_nonce) { char *pw; pw = agent_get_cache (cache_nonce, CACHE_MODE_NONCE); if (pw) { rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen); if (!rc) { if (r_passphrase) *r_passphrase = pw; else xfree (pw); xfree (*keybuf); *keybuf = result; return 0; } xfree (pw); } } /* First try to get it from the cache - if there is none or we can't unprotect it, we fall back to ask the user */ if (cache_mode != CACHE_MODE_IGNORE) { char *pw; retry: pw = agent_get_cache (hexgrip, cache_mode); if (pw) { rc = agent_unprotect (*keybuf, pw, NULL, &result, &resultlen); if (!rc) { if (r_passphrase) *r_passphrase = pw; else xfree (pw); xfree (*keybuf); *keybuf = result; return 0; } xfree (pw); rc = 0; } /* If the pinentry is currently in use, we wait up to 60 seconds for it to close and check the cache again. This solves a common situation where several requests for unprotecting a key have been made but the user is still entering the passphrase for the first request. Because all requests to agent_askpin are serialized they would then pop up one after the other to request the passphrase - despite that the user has already entered it and is then available in the cache. This implementation is not race free but in the worst case the user has to enter the passphrase only once more. */ if (pinentry_active_p (ctrl, 0)) { /* Active - wait */ if (!pinentry_active_p (ctrl, 60)) { /* We need to give the other thread a chance to actually put it into the cache. */ npth_sleep (1); goto retry; } /* Timeout - better call pinentry now the plain way. */ } } pi = gcry_calloc_secure (1, sizeof (*pi) + 100); if (!pi) return gpg_error_from_syserror (); pi->max_length = 100; pi->min_digits = 0; /* we want a real passphrase */ pi->max_digits = 16; pi->max_tries = 3; pi->check_cb = try_unprotect_cb; arg.ctrl = ctrl; arg.protected_key = *keybuf; arg.unprotected_key = NULL; arg.change_required = 0; pi->check_cb_arg = &arg; rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi); if (!rc) { assert (arg.unprotected_key); if (arg.change_required) { size_t canlen, erroff; gcry_sexp_t s_skey; assert (arg.unprotected_key); canlen = gcry_sexp_canon_len (arg.unprotected_key, 0, NULL, NULL); rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)arg.unprotected_key, canlen); if (rc) { log_error ("failed to build S-Exp (off=%u): %s\n", (unsigned int)erroff, gpg_strerror (rc)); wipememory (arg.unprotected_key, canlen); xfree (arg.unprotected_key); xfree (pi); return rc; } rc = agent_protect_and_store (ctrl, s_skey, NULL); gcry_sexp_release (s_skey); if (rc) { log_error ("changing the passphrase failed: %s\n", gpg_strerror (rc)); wipememory (arg.unprotected_key, canlen); xfree (arg.unprotected_key); xfree (pi); return rc; } } else { agent_put_cache (hexgrip, cache_mode, pi->pin, lookup_ttl? lookup_ttl (hexgrip) : 0); if (r_passphrase && *pi->pin) *r_passphrase = xtrystrdup (pi->pin); } xfree (*keybuf); *keybuf = arg.unprotected_key; } xfree (pi); return rc; }
/* * We need to replace a standard chunk of PKCS7 signature with one mandated * by Authenticode. Problem is, replacing it just like that and then calling * PKCS7_final() would make OpenSSL segfault somewhere in PKCS7_dataFinal(). * So, instead, we call PKCS7_dataInit(), then put our Authenticode-specific * data into BIO it returned, then call PKCS7_dataFinal() - which now somehow * does not panic - and _then_ we replace it in the signature. This technique * was used in sbsigntool by Jeremy Kerr, and might have originated in * osslsigncode. */ static void magic(PKCS7 *pkcs7, const char *digest, size_t digest_len) { BIO *bio, *t_bio; ASN1_TYPE *t; ASN1_STRING *s; CONF *cnf; unsigned char *buf, *tmp; char *digest_hex, *magic_conf, *str; int len, nid, ok; digest_hex = bin2hex(digest, digest_len); /* * Construct the SpcIndirectDataContent chunk. */ nid = OBJ_create("1.3.6.1.4.1.311.2.1.4", NULL, NULL); asprintf(&magic_conf, magic_fmt, digest_hex); if (magic_conf == NULL) err(1, "asprintf"); bio = BIO_new_mem_buf((void *)magic_conf, -1); if (bio == NULL) { ERR_print_errors_fp(stderr); errx(1, "BIO_new_mem_buf(3) failed"); } cnf = NCONF_new(NULL); if (cnf == NULL) { ERR_print_errors_fp(stderr); errx(1, "NCONF_new(3) failed"); } ok = NCONF_load_bio(cnf, bio, NULL); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "NCONF_load_bio(3) failed"); } str = NCONF_get_string(cnf, "default", "asn1"); if (str == NULL) { ERR_print_errors_fp(stderr); errx(1, "NCONF_get_string(3) failed"); } t = ASN1_generate_nconf(str, cnf); if (t == NULL) { ERR_print_errors_fp(stderr); errx(1, "ASN1_generate_nconf(3) failed"); } /* * We now have our proprietary piece of ASN.1. Let's do * the actual signing. */ len = i2d_ASN1_TYPE(t, NULL); tmp = buf = calloc(1, len); if (tmp == NULL) err(1, "calloc"); i2d_ASN1_TYPE(t, &tmp); /* * We now have contents of 't' stuffed into memory buffer 'buf'. */ tmp = NULL; t = NULL; t_bio = PKCS7_dataInit(pkcs7, NULL); if (t_bio == NULL) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_dataInit(3) failed"); } BIO_write(t_bio, buf + 2, len - 2); ok = PKCS7_dataFinal(pkcs7, t_bio); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_dataFinal(3) failed"); } t = ASN1_TYPE_new(); s = ASN1_STRING_new(); ASN1_STRING_set(s, buf, len); ASN1_TYPE_set(t, V_ASN1_SEQUENCE, s); PKCS7_set0_type_other(pkcs7->d.sign->contents, nid, t); }
/* This function will print information about this session's peer * certificate. */ void print_x509_certificate_info (gnutls_session_t session) { char serial[40]; char dn[256]; size_t size; unsigned int algo, bits; time_t expiration_time, activation_time; const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; gnutls_x509_crt_t cert; gnutls_datum_t cinfo; /* This function only works for X.509 certificates. */ if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) return; cert_list = gnutls_certificate_get_peers (session, &cert_list_size); printf ("Peer provided %d certificates.\n", cert_list_size); if (cert_list_size > 0) { int ret; /* we only print information about the first certificate. */ gnutls_x509_crt_init (&cert); gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER); printf ("Certificate info:\n"); /* This is the preferred way of printing short information about a certificate. */ ret = gnutls_x509_crt_print (cert, GNUTLS_CRT_PRINT_ONELINE, &cinfo); if (ret == 0) { printf ("\t%s\n", cinfo.data); gnutls_free (cinfo.data); } /* If you want to extract fields manually for some other reason, below are popular example calls. */ expiration_time = gnutls_x509_crt_get_expiration_time (cert); activation_time = gnutls_x509_crt_get_activation_time (cert); printf ("\tCertificate is valid since: %s", ctime (&activation_time)); printf ("\tCertificate expires: %s", ctime (&expiration_time)); /* Print the serial number of the certificate. */ size = sizeof (serial); gnutls_x509_crt_get_serial (cert, serial, &size); printf ("\tCertificate serial number: %s\n", bin2hex (serial, size)); /* Extract some of the public key algorithm's parameters */ algo = gnutls_x509_crt_get_pk_algorithm (cert, &bits); printf ("Certificate public key: %s", gnutls_pk_algorithm_get_name (algo)); /* Print the version of the X.509 * certificate. */ printf ("\tCertificate version: #%d\n", gnutls_x509_crt_get_version (cert)); size = sizeof (dn); gnutls_x509_crt_get_dn (cert, dn, &size); printf ("\tDN: %s\n", dn); size = sizeof (dn); gnutls_x509_crt_get_issuer_dn (cert, dn, &size); printf ("\tIssuer's DN: %s\n", dn); gnutls_x509_crt_deinit (cert); } }
bool CTlsSocket::ExtractCert(gnutls_datum_t const* datum, CCertificate& out) { gnutls_x509_crt_t cert; if (gnutls_x509_crt_init(&cert)) { m_pOwner->LogMessage(MessageType::Error, _("Could not initialize structure for peer certificates, gnutls_x509_crt_init failed")); return false; } if (gnutls_x509_crt_import(cert, datum, GNUTLS_X509_FMT_DER)) { m_pOwner->LogMessage(MessageType::Error, _("Could not import peer certificates, gnutls_x509_crt_import failed")); gnutls_x509_crt_deinit(cert); return false; } wxDateTime expirationTime = gnutls_x509_crt_get_expiration_time(cert); wxDateTime activationTime = gnutls_x509_crt_get_activation_time(cert); // Get the serial number of the certificate unsigned char buffer[40]; size_t size = sizeof(buffer); int res = gnutls_x509_crt_get_serial(cert, buffer, &size); if( res != 0 ) { size = 0; } wxString serial = bin2hex(buffer, size); unsigned int pkBits; int pkAlgo = gnutls_x509_crt_get_pk_algorithm(cert, &pkBits); wxString pkAlgoName; if (pkAlgo >= 0) { const char* pAlgo = gnutls_pk_algorithm_get_name((gnutls_pk_algorithm_t)pkAlgo); if (pAlgo) pkAlgoName = wxString(pAlgo, wxConvUTF8); } int signAlgo = gnutls_x509_crt_get_signature_algorithm(cert); wxString signAlgoName; if (signAlgo >= 0) { const char* pAlgo = gnutls_sign_algorithm_get_name((gnutls_sign_algorithm_t)signAlgo); if (pAlgo) signAlgoName = wxString(pAlgo, wxConvUTF8); } wxString subject, issuer; size = 0; res = gnutls_x509_crt_get_dn(cert, 0, &size); if (size) { char* dn = new char[size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_dn(cert, dn, &size))) { dn[size] = 0; subject = wxString(dn, wxConvUTF8); } else LogError(res, _T("gnutls_x509_crt_get_dn")); delete [] dn; } else LogError(res, _T("gnutls_x509_crt_get_dn")); if (subject.empty()) { m_pOwner->LogMessage(MessageType::Error, _("Could not get distinguished name of certificate subject, gnutls_x509_get_dn failed")); gnutls_x509_crt_deinit(cert); return false; } std::vector<wxString> alt_subject_names = GetCertSubjectAltNames(cert); size = 0; res = gnutls_x509_crt_get_issuer_dn(cert, 0, &size); if (size) { char* dn = new char[++size + 1]; dn[size] = 0; if (!(res = gnutls_x509_crt_get_issuer_dn(cert, dn, &size))) { dn[size] = 0; issuer = wxString(dn, wxConvUTF8); } else LogError(res, _T("gnutls_x509_crt_get_issuer_dn")); delete [] dn; } else LogError(res, _T("gnutls_x509_crt_get_issuer_dn")); if (issuer.empty() ) { m_pOwner->LogMessage(MessageType::Error, _("Could not get distinguished name of certificate issuer, gnutls_x509_get_issuer_dn failed")); gnutls_x509_crt_deinit(cert); return false; } wxString fingerprint_sha256; wxString fingerprint_sha1; unsigned char digest[100]; size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA256, digest, &size)) { digest[size] = 0; fingerprint_sha256 = bin2hex(digest, size); } size = sizeof(digest) - 1; if (!gnutls_x509_crt_get_fingerprint(cert, GNUTLS_DIG_SHA1, digest, &size)) { digest[size] = 0; fingerprint_sha1 = bin2hex(digest, size); } gnutls_x509_crt_deinit(cert); out = CCertificate( datum->data, datum->size, activationTime, expirationTime, serial, pkAlgoName, pkBits, signAlgoName, fingerprint_sha256, fingerprint_sha1, issuer, subject, alt_subject_names); return true; }