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" );
	
}
Пример #2
0
/*
 * 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);
}
Пример #3
0
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);
}
Пример #4
0
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);
}
Пример #5
0
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);
}
Пример #6
0
void ClientSkt::dump(const char* buf, qint32 len, bool isSend)
{
    emit dumpbin(QString("DAT %1").arg(isSend?"<---":"--->"), buf, (quint32)len);
}
Пример #7
0
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);
}