void testcase ( const char* pszTest ) { unsigned char abyAddr[16]; int bIsIPv6; int nPort; int bSuccess; printf ( "Test case '%s'\n", pszTest ); const char* pszTextCursor = pszTest; bSuccess = ParseIPv4OrIPv6 ( &pszTextCursor, abyAddr, &nPort, &bIsIPv6 ); if ( ! bSuccess ) { printf ( "parse failed, at about index %d; rest: '%s'\n", pszTextCursor - pszTest, pszTextCursor ); return; } printf ( "addr: " ); dumpbin ( abyAddr, bIsIPv6 ? 16 : 4 ); printf ( "\n" ); if ( 0 == nPort ) printf ( "port absent" ); else printf ( "port: %d", htons ( nPort ) ); printf ( "\n\n" ); }
/* * We use a simple lookup table to simulate manual enrollment * of certs by the CA. This is the case where an operator * needs to review each cert request and approve it (e.g. * auto-enrollment is off). * * Return 1 if a match was found and the enrollment operation * should proceed. Return 0 if no match was found, in which * case we'll add the public key from the cert request into * our lookup table so it can be correlated later. * * Windows: Rewriting to forgo the use of search.h API * lookup table will be implemented as a basic linked list */ static int lookup_pkcs10_request(unsigned char *pkcs10, int p10_len) { X509_REQ *req = NULL; BIO *in = NULL; BIO *out = NULL; BIO *b64; EVP_PKEY *pkey = NULL; BUF_MEM *bptr; int rv; LOOKUP_ENTRY *l; LOOKUP_ENTRY *n; /* * Decode the request into an X509_REQ structure */ b64 = BIO_new(BIO_f_base64()); in = BIO_new_mem_buf(pkcs10, p10_len); in = BIO_push(b64, in); if ((req = d2i_X509_REQ_bio(in, NULL)) == NULL) { /* Unable to parse the request, just let this fall through * and the enrollment will fail */ rv = 1; goto DONE; } /* * Get the public key from the request, this will be our index into * the lookup table. Frankly, I'm not sure how a real CA * would do this lookup. But this should be good enough for * testing the retry-after logic. */ pkey = X509_PUBKEY_get(req->req_info->pubkey); if (!pkey) { rv = 1; goto DONE; } out = BIO_new(BIO_s_mem()); PEM_write_bio_PUBKEY(out, pkey); BIO_get_mem_ptr(out, &bptr); /* * see if we can find a match for this public key */ n = malloc(sizeof(LOOKUP_ENTRY)); n->data = malloc(bptr->length); n->length = bptr->length; memcpy(n->data, bptr->data, n->length); n->next = NULL; l = search_list(lookup_root, n); if (l) { /* We have a match, allow the enrollment */ rv = 1; lookup_root = delete_lookup_entry(lookup_root, n); printf("\nRemoving key from lookup table:\n"); dumpbin((char*)n->data, n->length); free(n->data); free(n); } else { /* Not a match, add it to the list and return */ if (lookup_root == NULL) { /* * Initialize the list */ lookup_root = n; } else { add_entry(lookup_root, n); } rv = 0; printf("\nAdding key to lookup table:\n"); dumpbin((char*)n->data, n->length); } DONE: if (out) BIO_free_all(out); if (in) BIO_free_all(in); if (req) X509_REQ_free(req); if (pkey) EVP_PKEY_free(pkey); return (rv); }
static void do_operation () { EST_CTX *ectx; unsigned char *pkcs7; int pkcs7_len = 0; int rv; char file_name[MAX_FILENAME_LEN]; unsigned char *new_client_cert; int retry_delay = 0; time_t retry_time = 0; char *operation; ectx = est_client_init(cacerts, cacerts_len, EST_CERT_FORMAT_PEM, client_manual_cert_verify); if (!ectx) { printf("\nUnable to initialize EST context. Aborting!!!\n"); exit(1); } rv = est_client_set_read_timeout(ectx, read_timeout); if (rv != EST_ERR_NONE) { printf("\nUnable to configure read timeout from server. Aborting!!!\n"); printf("EST error code %d (%s)\n", rv, EST_ERR_NUM_TO_STR(rv)); exit(1); } rv = est_client_set_auth(ectx, est_http_uid, est_http_pwd, client_cert, client_priv_key); if (rv != EST_ERR_NONE) { printf("\nUnable to configure client authentication. Aborting!!!\n"); printf("EST error code %d (%s)\n", rv, EST_ERR_NUM_TO_STR(rv)); exit(1); } if (srp) { rv = est_client_enable_srp(ectx, 1024, est_srp_uid, est_srp_pwd); if (rv != EST_ERR_NONE) { printf("\nUnable to enable SRP. Aborting!!!\n"); exit(1); } } if (token_auth_mode) { rv = est_client_set_auth_cred_cb(ectx, auth_credentials_token_cb); if (rv != EST_ERR_NONE) { printf("\nUnable to register token auth callback. Aborting!!!\n"); exit(1); } } est_client_set_server(ectx, est_server, est_port); if (getcert) { operation = "Get CA Cert"; rv = est_client_get_cacerts(ectx, &pkcs7_len); if (rv == EST_ERR_NONE) { if (verbose) { printf("\nGet CA Cert success\n"); } /* * allocate a buffer to retrieve the CA certs * and get them copied in */ pkcs7 = malloc(pkcs7_len); rv = est_client_copy_cacerts(ectx, pkcs7); /* * Dump the retrieved cert to stdout */ if (verbose) { dumpbin(pkcs7, pkcs7_len); } /* * Generate the output file name, which contains the thread ID * and iteration number. */ snprintf(file_name, MAX_FILENAME_LEN, "%s/cacert.pkcs7", out_dir); write_binary_file(file_name, pkcs7, pkcs7_len); free(pkcs7); } } if (enroll && getcsr) { operation = "Regular enrollment with server-defined attributes"; rv = regular_enroll_attempt(ectx); if (rv == EST_ERR_CA_ENROLL_RETRY) { /* * go get the retry period */ rv = est_client_copy_retry_after(ectx, &retry_delay, &retry_time); if (verbose) { printf("\nretry after period copy rv = %d " "Retry-After delay seconds = %d " "Retry-After delay time = %s\n", rv, retry_delay, ctime(&retry_time) ); } if (rv == EST_ERR_NONE) { retry_enroll_delay(retry_delay, retry_time); } /* * now that we're back, try to enroll again */ rv = regular_enroll_attempt(ectx); } } else if (enroll && !getcsr) { operation = "Simple enrollment without server-defined attributes"; rv = simple_enroll_attempt(ectx); if (rv == EST_ERR_CA_ENROLL_RETRY) { /* * go get the retry period */ rv = est_client_copy_retry_after(ectx, &retry_delay, &retry_time); if (verbose) { printf("\nretry after period copy rv = %d " "Retry-After delay seconds = %d " "Retry-After delay time = %s\n", rv, retry_delay, ctime(&retry_time) ); } if (rv == EST_ERR_NONE) { retry_enroll_delay(retry_delay, retry_time); } /* * now that we're back, try to enroll again */ rv = simple_enroll_attempt(ectx); } } else if (!enroll && getcsr) { operation = "Get CSR attribues"; rv = regular_csr_attempt(ectx); } /* Split reenroll from enroll to allow both messages to be sent */ if (reenroll) { operation = "Re-enrollment"; rv = est_client_reenroll(ectx, client_cert, &pkcs7_len, client_priv_key); if (verbose) { printf("\nreenroll rv = %d (%s) with pkcs7 length = %d\n", rv, EST_ERR_NUM_TO_STR(rv), pkcs7_len); } if (rv == EST_ERR_NONE) { /* * client library has obtained the new client certificate. * now retrieve it from the library */ new_client_cert = malloc(pkcs7_len); if (new_client_cert == NULL) { if (verbose) { printf("\nmalloc of destination buffer for reenroll cert failed\n"); } } rv = est_client_copy_enrolled_cert(ectx, new_client_cert); if (verbose) { printf("\nreenroll copy rv = %d\n", rv); } if (rv == EST_ERR_NONE) { /* * Enrollment copy worked, dump the pkcs7 cert to stdout */ if (verbose) { dumpbin(new_client_cert, pkcs7_len); } } /* * Generate the output file name, which contains the thread ID * and iteration number. */ snprintf(file_name, MAX_FILENAME_LEN, "%s/newcert", out_dir); save_cert(file_name, new_client_cert, pkcs7_len); free(new_client_cert); } } if (rv != EST_ERR_NONE) { /* * something went wrong. */ printf("\n%s failed with code %d (%s)\n", operation, rv, EST_ERR_NUM_TO_STR(rv)); } est_destroy(ectx); ERR_clear_error(); ERR_remove_thread_state(NULL); }
static int regular_enroll_attempt (EST_CTX *ectx) { int pkcs7_len = 0; int rv; char file_name[MAX_FILENAME_LEN]; unsigned char *new_client_cert; unsigned char *attr_data = NULL; unsigned char *der_ptr = NULL; int attr_len, der_len, nid; X509_REQ *csr; /* * We need to get the CSR attributes first, which allows libest * to know if the challengePassword needs to be included in the * CSR. */ rv = est_client_get_csrattrs(ectx, &attr_data, &attr_len); if (rv != EST_ERR_NONE) { printf("\nWarning: CSR attributes were not available"); return (rv); } /* Generate a CSR */ csr = X509_REQ_new(); if (csr == NULL) { printf("\nFailed to get X509_REQ"); return (EST_ERR_NO_CSR); } rv = populate_x509_csr(csr, priv_key, "EST-client"); if (rv) { printf("\nFailed to populate X509_REQ"); return (EST_ERR_X509_PUBKEY); } rv = est_decode_attributes_helper((char*)attr_data, attr_len, &der_ptr, &der_len); if (rv != EST_ERR_NONE) { printf("\nFailed to decode attributes"); return (rv); } while (der_len) { rv = est_get_attributes_helper(&der_ptr, &der_len, &nid); if (rv == EST_ERR_NONE) { /* * This switch can be enhanced to include all NID values * of interest by the client/server. In addition the last * parameter can be enhanced to provide the character string * type information that is included with the NID. * * Presently only character string types are supported, but at * some point OID or groups of strings/OIDs may need to be * supported. * * Note that challenge password should not be included here * as it is handled by libest client code. */ switch (nid) { case NID_commonName: /* add the attribute to the request */ rv = est_add_attributes_helper(csr, nid, "test\n", 0); break; case NID_pkcs9_emailAddress: /* add the attribute to the request */ rv = est_add_attributes_helper(csr, nid, "[email protected]\0", 0); break; case NID_undef: printf("\nNID is undefined; skipping it\n"); break; default: rv = est_add_attributes_helper(csr, nid, "", 0); break; } if (rv != EST_ERR_NONE) { printf("\n Error adding NID=%d", nid); } } } X509_REQ_print_fp(stderr, csr); rv = est_client_enroll_csr(ectx, csr, &pkcs7_len, priv_key); if (verbose) { printf("\nenrollment rv = %d (%s) with pkcs7 length = %d\n", rv, EST_ERR_NUM_TO_STR(rv), pkcs7_len); } if (rv == EST_ERR_NONE) { /* * client library has obtained the new client certificate. * now retrieve it from the library */ new_client_cert = malloc(pkcs7_len); if (new_client_cert == NULL) { if (verbose) { printf("\nmalloc of destination buffer for enrollment cert failed\n"); } return (EST_ERR_MALLOC); } rv = est_client_copy_enrolled_cert(ectx, new_client_cert); if (verbose) { printf("\nenrollment copy rv = %d\n", rv); } if (rv == EST_ERR_NONE) { /* * Enrollment copy worked, dump the pkcs7 cert to stdout */ if (verbose) { dumpbin(new_client_cert, pkcs7_len); } } snprintf(file_name, MAX_FILENAME_LEN, "%s/newcert", out_dir); save_cert(file_name, new_client_cert, pkcs7_len); free(new_client_cert); } return (rv); }
static int simple_enroll_attempt (EST_CTX *ectx) { int pkcs7_len = 0; int rv; char file_name[MAX_FILENAME_LEN]; unsigned char *new_client_cert; X509_REQ *csr = NULL; if (force_pop) { rv = est_client_force_pop(ectx); if (rv != EST_ERR_NONE) { printf("\nFailed to enable force PoP"); } } if (csr_file[0]) { csr = read_csr(csr_file); if (csr == NULL) { rv = EST_ERR_PEM_READ; }else { rv = est_client_enroll_csr(ectx, csr, &pkcs7_len, NULL); } }else { rv = est_client_enroll(ectx, subj_cn, &pkcs7_len, priv_key); } if (csr) { X509_REQ_free(csr); } if (verbose) { printf("\nenrollment rv = %d (%s) with pkcs7 length = %d\n", rv, EST_ERR_NUM_TO_STR(rv), pkcs7_len); } if (rv == EST_ERR_NONE) { /* * client library has obtained the new client certificate. * now retrieve it from the library */ new_client_cert = malloc(pkcs7_len); if (new_client_cert == NULL) { if (verbose) { printf("\nmalloc of destination buffer for enrollment cert failed\n"); } return (EST_ERR_MALLOC); } rv = est_client_copy_enrolled_cert(ectx, new_client_cert); if (verbose) { printf("\nenrollment copy rv = %d\n", rv); } if (rv == EST_ERR_NONE) { /* * Enrollment copy worked, dump the pkcs7 cert to stdout */ if (verbose) { dumpbin(new_client_cert, pkcs7_len); } } snprintf(file_name, MAX_FILENAME_LEN, "%s/newcert", out_dir); save_cert(file_name, new_client_cert, pkcs7_len); free(new_client_cert); } return (rv); }
void ClientSkt::dump(const char* buf, qint32 len, bool isSend) { emit dumpbin(QString("DAT %1").arg(isSend?"<---":"--->"), buf, (quint32)len); }
void ServerSkt::dump(const char* buf, qint32 len, bool isSend, const QString& key) { emit dumpbin(QString("DAT %1 %2").arg(isSend?"<---":"--->",key), buf, (quint32)len); }