STACK_OF(X509) *get_cert_store(int *ids){ STACK_OF(X509) *store = sk_X509_new(NULL); while(ids && ((*ids) != -1)){ sk_X509_push(store, get_cert(*ids)); ids++; } return store; }
/* called before every test case starts */ static void init_tcase(void) { /* Add algorithms and init random pool */ OpenSSL_add_all_algorithms(); s_rsakey = keygen_create(1024); s_certs = sk_X509_new(NULL); memset(&s_info, 0, sizeof(s_info)); s_info.userFriendlyName = "friendlytestdevice"; }
/* called before every test case starts */ static void init_tcase(void) { s_rsakey = keygen_create(1024); s_certs = sk_X509_new(NULL); memset(&s_info, 0, sizeof(s_info)); s_info.userFriendlyName = "friendlytestdevice"; s_ssl_cb_hitcount = 0; s_data_cb_hitcount = 0; }
/* * Wrap data in PKCS#7 envelopes and base64-encode the result. * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in * GetCert and GETCrl. */ int pkcs7_wrap(struct scep *s, struct sscep_ctx *ctx, struct sscep_operation_info *op_info) { BIO *databio = NULL; BIO *encbio = NULL; BIO *pkcs7bio = NULL; BIO *memorybio = NULL; BIO *outbio = NULL; unsigned char *buffer = NULL; int len = 0; STACK_OF(X509) *recipients = NULL; PKCS7 *p7enc = NULL; PKCS7_SIGNER_INFO *si; STACK_OF(X509_ATTRIBUTE) *attributes; X509 *signercert = NULL; EVP_PKEY *signerkey = NULL; int ret = SCEP_PKISTATUS_P7; char *payload = NULL; int payload_len; /* Create a new sender nonce for all messages * XXXXXXXXXXXXXX should it be per transaction? */ s->sender_nonce_len = 16; free(s->sender_nonce);/* Clean up from previous runs */ s->sender_nonce = (char *)malloc(s->sender_nonce_len * sizeof(char)); RAND_bytes((unsigned char *) s->sender_nonce, s->sender_nonce_len); /* Prepare data payload */ switch (s->request_type) { case SCEP_REQUEST_PKCSREQ: /* * Set printable message type * We set this later as an autheticated attribute * "messageType". */ s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating inner PKCS#7"); } /* Read request in memory bio */ databio = BIO_new(BIO_s_mem()); if (i2d_X509_REQ_bio(databio, op_info->request) <= 0) { qeo_log_e("error writing certificate request in bio"); goto error; } (void)BIO_flush(databio); break; case SCEP_REQUEST_GETCERTINIT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating inner PKCS#7"); } /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if (i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) { qeo_log_e("error writing GetCertInitial data in bio"); goto error; } (void)BIO_flush(databio); break; } /* Below this is the common code for all request_type */ /* Read in the payload */ payload_len = BIO_get_mem_data(databio, &payload); if (ctx->verbose){ qeo_log_i("data payload size: %d bytes", payload_len); } /* Create encryption certificate stack */ if ((recipients = sk_X509_new(NULL) ) == NULL) { qeo_log_e("error creating certificate stack"); goto error; } if (sk_X509_push(recipients, op_info->racert) <= 0) { qeo_log_e("error adding recipient encryption certificate"); goto error; } /* Create BIO for encryption */ if ((encbio = BIO_new_mem_buf(payload, payload_len)) == NULL ) { qeo_log_e("error creating data bio"); goto error; } /* Encrypt */ if (!(p7enc = PKCS7_encrypt(recipients, encbio, ctx->enc_alg, PKCS7_BINARY))) { qeo_log_e("request payload encrypt failed"); goto error; } if (ctx->verbose){ qeo_log_i("successfully encrypted payload"); } /* Write encrypted data */ memorybio = BIO_new(BIO_s_mem()); if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { qeo_log_e("error writing encrypted data"); goto error; } (void)BIO_flush(memorybio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); len = BIO_get_mem_data(memorybio, &buffer); BIO_free(memorybio); memorybio=NULL; if (ctx->verbose){ qeo_log_i("envelope size: %d bytes", len); } if (ctx->debug) { qeo_log_i("printing PEM fomatted PKCS#7"); PEM_write_PKCS7(stdout, p7enc); } /* Create outer PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating outer PKCS#7"); } s->request_p7 = PKCS7_new(); if (s->request_p7 == NULL ) { qeo_log_e("failed creating PKCS#7 for signing"); goto error; } if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { qeo_log_e("failed setting PKCS#7 type"); goto error; } /* Add signer certificate and signature */ PKCS7_add_certificate(s->request_p7, signercert); if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, ctx->sig_alg)) == NULL ) { qeo_log_e("error adding PKCS#7 signature"); goto error; } if (ctx->verbose){ qeo_log_i("signature added successfully"); } /* Set signed attributes */ if (ctx->verbose){ qeo_log_i("adding signed attributes"); } attributes = sk_X509_ATTRIBUTE_new_null(); add_attribute_string(attributes, ctx->nid_transId, s->transaction_id, ctx); add_attribute_string(attributes, ctx->nid_messageType, s->request_type_str, ctx); add_attribute_octet(attributes, ctx->nid_senderNonce, s->sender_nonce, s->sender_nonce_len, ctx); PKCS7_set_signed_attributes(si, attributes); sk_X509_ATTRIBUTE_pop_free(attributes, X509_ATTRIBUTE_free); /* Add contentType */ if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { qeo_log_e("error adding NID_pkcs9_contentType"); goto error; } /* Create new content */ if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { qeo_log_e("failed setting PKCS#7 content type"); goto error; } /* Write data */ pkcs7bio = PKCS7_dataInit(s->request_p7, NULL ); if (pkcs7bio == NULL ) { qeo_log_e("error opening bio for writing PKCS#7 data"); goto error; } if (len != BIO_write(pkcs7bio, buffer, len)) { qeo_log_e("error writing PKCS#7 data"); goto error; } if (ctx->verbose){ qeo_log_i("PKCS#7 data written successfully"); } /* Finalize PKCS#7 */ if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { qeo_log_e("error finalizing outer PKCS#7"); goto error; } if (ctx->debug) { qeo_log_i("printing PEM fomatted PKCS#7"); PEM_write_PKCS7(stdout, s->request_p7); } /* base64-encode the data */ if (ctx->verbose){ qeo_log_i("applying base64 encoding"); } /* Create base64 filtering bio */ memorybio = BIO_new(BIO_s_mem()); outbio = BIO_push(BIO_new(BIO_f_base64()), memorybio); /* Copy PKCS#7 */ i2d_PKCS7_bio(outbio, s->request_p7); (void)BIO_flush(outbio); payload_len = BIO_get_mem_data(memorybio, &payload); s->request_payload = (char*) malloc(sizeof(char)*payload_len); if (!s->request_payload){ goto error; } s->request_len = payload_len; memcpy(s->request_payload, payload, s->request_len); if (ctx->verbose){ qeo_log_i("base64 encoded payload size: %d bytes", payload_len); } ret = 0; error: BIO_free(databio); BIO_free(encbio); BIO_free_all(pkcs7bio); BIO_free(memorybio); BIO_free(outbio); if (recipients != NULL){ sk_X509_free(recipients);/* Only free the stack, not the certificates */ } PKCS7_free(p7enc); OPENSSL_free(buffer); return ret; }
/* * Wrap data in PKCS#7 envelopes and base64-encode the result. * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in * GetCert and GETCrl. */ int pkcs7_wrap(struct scep *s) { BIO *databio = NULL; BIO *encbio = NULL; BIO *pkcs7bio = NULL; BIO *memorybio = NULL; BIO *outbio = NULL; BIO *base64bio = NULL; unsigned char *buffer = NULL; int rc, len = 0; STACK_OF(X509) *recipients; PKCS7 *p7enc; PKCS7_SIGNER_INFO *si; STACK_OF(X509_ATTRIBUTE) *attributes; X509 *signercert = NULL; EVP_PKEY *signerkey = NULL; /* Create a new sender nonce for all messages * XXXXXXXXXXXXXX should it be per transaction? */ s->sender_nonce_len = 16; s->sender_nonce = (unsigned char *)malloc(s->sender_nonce_len); RAND_bytes(s->sender_nonce, s->sender_nonce_len); /* Prepare data payload */ switch(s->request_type) { case SCEP_REQUEST_PKCSREQ: /* * Set printable message type * We set this later as an autheticated attribute * "messageType". */ s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (v_flag) printf("%s: creating inner PKCS#7\n", pname); /* Read request in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_X509_REQ_bio(databio, request)) <= 0) { fprintf(stderr, "%s: error writing " "certificate request in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; case SCEP_REQUEST_GETCERTINIT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (v_flag) printf("%s: creating inner PKCS#7\n", pname); /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) <= 0) { fprintf(stderr, "%s: error writing " "GetCertInitial data in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; case SCEP_REQUEST_GETCERT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERT_STR; /* Signer cert */ signercert = localcert; signerkey = rsa; /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, s->ias_getcert)) <= 0) { fprintf(stderr, "%s: error writing " "GetCert data in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; case SCEP_REQUEST_GETCRL: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCRL_STR; /* Signer cert */ signercert = localcert; signerkey = rsa; /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, s->ias_getcrl)) <= 0) { fprintf(stderr, "%s: error writing " "GetCert data in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; } /* Below this is the common code for all request_type */ /* Read in the payload */ s->request_len = BIO_get_mem_data(databio, &s->request_payload); if (v_flag) printf("%s: data payload size: %d bytes\n", pname, s->request_len); BIO_free(databio); /* Create encryption certificate stack */ if ((recipients = sk_X509_new(NULL)) == NULL) { fprintf(stderr, "%s: error creating " "certificate stack\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Use different CA cert for encryption if requested */ if (e_flag) { if (sk_X509_push(recipients, encert) <= 0) { fprintf(stderr, "%s: error adding recipient encryption " "certificate\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Use same CA cert also for encryption */ } else { if (sk_X509_push(recipients, cacert) <= 0) { fprintf(stderr, "%s: error adding recipient encryption " "certificate\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } } /* Create BIO for encryption */ if ((encbio = BIO_new_mem_buf(s->request_payload, s->request_len)) == NULL) { fprintf(stderr, "%s: error creating data " "bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Encrypt */ if (!(p7enc = PKCS7_encrypt(recipients, encbio, enc_alg, PKCS7_BINARY))) { fprintf(stderr, "%s: request payload encrypt failed\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (v_flag) printf("%s: successfully encrypted payload\n", pname); /* Write encrypted data */ memorybio = BIO_new(BIO_s_mem()); if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { fprintf(stderr, "%s: error writing encrypted data\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(memorybio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); len = BIO_get_mem_data(memorybio, &buffer); if (v_flag) printf("%s: envelope size: %d bytes\n", pname, len); if (d_flag) { printf("%s: printing PEM fomatted PKCS#7\n", pname); PEM_write_PKCS7(stdout, p7enc); } BIO_free(memorybio); /* Create outer PKCS#7 */ if (v_flag) printf("%s: creating outer PKCS#7\n", pname); s->request_p7 = PKCS7_new(); if (s->request_p7 == NULL) { fprintf(stderr, "%s: failed creating PKCS#7 for signing\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { fprintf(stderr, "%s: failed setting PKCS#7 type\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Add signer certificate and signature */ PKCS7_add_certificate(s->request_p7, signercert); if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, sig_alg)) == NULL) { fprintf(stderr, "%s: error adding PKCS#7 signature\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (v_flag) printf("%s: signature added successfully\n", pname); /* Set signed attributes */ if (v_flag) printf("%s: adding signed attributes\n", pname); attributes = sk_X509_ATTRIBUTE_new_null(); add_attribute_string(attributes, nid_transId, s->transaction_id); add_attribute_string(attributes, nid_messageType, s->request_type_str); add_attribute_octet(attributes, nid_senderNonce, s->sender_nonce, s->sender_nonce_len); PKCS7_set_signed_attributes(si, attributes); /* Add contentType */ if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { fprintf(stderr, "%s: error adding NID_pkcs9_contentType\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Create new content */ if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { fprintf(stderr, "%s: failed setting PKCS#7 content type\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Write data */ pkcs7bio = PKCS7_dataInit(s->request_p7, NULL); if (pkcs7bio == NULL) { fprintf(stderr, "%s: error opening bio for writing PKCS#7 " "data\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (len != BIO_write(pkcs7bio, buffer, len)) { fprintf(stderr, "%s: error writing PKCS#7 data\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (v_flag) printf("%s: PKCS#7 data written successfully\n", pname); /* Finalize PKCS#7 */ if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { fprintf(stderr, "%s: error finalizing outer PKCS#7\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (d_flag) { printf("%s: printing PEM fomatted PKCS#7\n", pname); PEM_write_PKCS7(stdout, s->request_p7); } /* base64-encode the data */ if (v_flag) printf("%s: applying base64 encoding\n",pname); /* Create base64 filtering bio */ memorybio = BIO_new(BIO_s_mem()); base64bio = BIO_new(BIO_f_base64()); outbio = BIO_push(base64bio, memorybio); /* Copy PKCS#7 */ i2d_PKCS7_bio(outbio, s->request_p7); BIO_flush(outbio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); s->request_len = BIO_get_mem_data(memorybio, &s->request_payload); if (v_flag) printf("%s: base64 encoded payload size: %d bytes\n", pname, s->request_len); BIO_free(outbio); return (0); }
int SCEP_MSG_encrypt( SCEP_MSG *msg, X509 *recip_cert, EVP_CIPHER cipher ) { BIO *inbio = NULL; int ret = 0; int len = 0; BIO *debug_bio = NULL; if ((debug_bio=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(debug_bio,stderr,BIO_NOCLOSE|BIO_FP_TEXT); // printf("%s:%d Debug... *** ENCRYPT ***\n", __FILE__, __LINE__ ); /* Create the stack of the recipient(s) certificate(s) */ if( recip_cert ) { STACK_OF(X509) *sk = NULL; if((sk = sk_X509_new(NULL)) == NULL) goto err; sk_X509_push( sk, recip_cert ); msg->env_data.recip_info.sk_recip_certs = sk; } else { return 0; } inbio = BIO_new ( BIO_s_mem()); /* Any message type has different data to be encrypted * and checks to be done */ switch ( msg->messageType ) { case MSG_PKCSREQ: /* There must be a request added to the msg */ if(! msg->env_data.content.req ) goto err; /* Write the request to the inbio */ if( i2d_X509_REQ_bio( inbio, msg->env_data.content.req ) <= 0) goto err; break; case MSG_GETCRL: case MSG_GETCERT: if( !msg->env_data.content.ias ) goto err; len = i2d_PKCS7_ias_bio( inbio, msg->env_data.content.ias); if( len <= 0 ) goto err; break; case MSG_CERTREP: // printf("%s:%d: Debug ... Case: MSG_CERTREP\n", // __FILE__, __LINE__ ); /* if ( msg->env_data.content.issued_cert ) { len = i2d_X509_bio ( inbio, msg->env_data.content.issued_cert ); } */ if ( msg->env_data.p7 ) len = i2d_PKCS7_bio( inbio, msg->env_data.p7 ); break; default: printf("%s:%d Unsupported MessageType %d (%s)\n", __FILE__, __LINE__, msg->messageType, SCEP_type2str(msg->messageType) ); } BIO_flush( inbio ); BIO_set_flags( inbio, BIO_FLAGS_MEM_RDONLY ); /* Check for the recipients certs presence */ if( !msg->env_data.recip_info.sk_recip_certs ) goto err; /* If already present an encoded pkcs7, let's free */ if( msg->env_data.p7env ) PKCS7_free( msg->env_data.p7env ); /* Encrypt Data */ msg->env_data.p7env = PKCS7_encrypt( msg->env_data.recip_info.sk_recip_certs, inbio, &cipher, PKCS7_BINARY ); ERR_clear_error(); /* If an error occourred pkcs7 is empty */ if( msg->env_data.p7env == NULL ) goto err; ret = 1; err: if (inbio) BIO_free( inbio ); return ret; }