PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst) { PKCS7_SIGNER_INFO *si = NULL; if (dgst == NULL) { int def_nid; if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) goto err; dgst = EVP_get_digestbynid(def_nid); if (dgst == NULL) { PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST); goto err; } } if ((si = PKCS7_SIGNER_INFO_new()) == NULL) goto err; if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) goto err; if (!PKCS7_add_signer(p7, si)) goto err; return (si); err: PKCS7_SIGNER_INFO_free(si); return (NULL); }
void openssl_pkcs7_sign() { int len; BIO *in; X509 *x; FILE *fp; PKCS7 *p7; X509_ALGOR *md; PKCS7_SIGNER_INFO *si; char name[MAX1_LEN], tmp[MAX1_LEN]; unsigned char *der, *p, buf[SHA_DIGEST_LENGTH] = "pkcs7 sign"; p7 = PKCS7_new(); PKCS7_set_type(p7, NID_pkcs7_data); ASN1_OCTET_STRING_set(p7->d.data, buf, SHA_DIGEST_LENGTH); len = i2d_PKCS7(p7, NULL); der = (unsigned char *)malloc(len); p = der; len = i2d_PKCS7(p7, &p); fp = fopen("/tmp/test.cer", "wb"); fwrite(der, 1, len, fp); fclose(fp); free(der); PKCS7_free(p7); p7 = PKCS7_new(); PKCS7_set_type(p7, NID_pkcs7_signed); p7->d.sign->cert = sk_X509_new_null(); in = BIO_new_file("/tmp/test.cer", "r"); x = PEM_read_bio_X509(in, NULL, NULL, NULL); sk_X509_push(p7->d.sign->cert, x); BIO_free(in); md = X509_ALGOR_new(); md->algorithm = OBJ_nid2obj(NID_md5); sk_X509_ALGOR_push(p7->d.sign->md_algs, md); si = PKCS7_SIGNER_INFO_new(); ASN1_INTEGER_set(si->version, 2); ASN1_INTEGER_set(si->issuer_and_serial->serial, 333); sk_PKCS7_SIGNER_INFO_push(p7->d.sign->signer_info, si); len = i2d_PKCS7(p7, NULL); der = (unsigned char *)malloc(len); p = der; len = i2d_PKCS7(p7, &p); fp = fopen("/tmp/test.cer", "wb"); fwrite(der, 1, len, fp); fclose(fp); free(der); fp = fopen("/tmp/test.cer", "rb"); len = fread(tmp, 1, MAX1_LEN, fp); fclose(fp); p = (unsigned char *)&tmp; d2i_PKCS7(&p7, (const unsigned char **)&p, len); OBJ_obj2txt(name, MAX1_LEN, p7->type, 0); PKCS7_free(p7); }
int main(){ PKCS7 *p7; int len; unsigned char *der,*p; FILE *fp; X509 *x; BIO *in; X509_ALGOR *md; PKCS7_SIGNER_INFO *si; p7=PKCS7_new(); PKCS7_set_type(p7,NID_pkcs7_signed); p7->d.sign->cert=sk_X509_new_null(); in=BIO_new_file("b64cert.cer","r"); x=PEM_read_bio_X509(in,NULL,NULL,NULL); sk_X509_push(p7->d.sign->cert,x); md=X509_ALGOR_new(); md->algorithm=OBJ_nid2obj(NID_md5); sk_X509_ALGOR_push(p7->d.sign->md_algs,md); si=PKCS7_SIGNER_INFO_new(); ASN1_INTEGER_set(si->version,2); ASN1_INTEGER_set(si->issuer_and_serial->serial,333); sk_PKCS7_SIGNER_INFO_push(p7->d.sign->signer_info,si); len=i2d_PKCS7(p7,NULL); der=(unsigned char *)malloc(len); p=der; len=i2d_PKCS7(p7,&p); fp=fopen("p7_sign.cer","wb"); fwrite(der,1,len,fp); fclose(fp); free(der); PKCS7_free(p7); return 0; }
/* * Public * (MADE PRIVATE UNTIL SOMEBODY WILL NEED THEM) */ static VALUE ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si) { PKCS7_SIGNER_INFO *pkcs7; VALUE obj; pkcs7 = p7si ? PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new(); if (!pkcs7) ossl_raise(ePKCS7Error, NULL); WrapPKCS7si(cPKCS7Signer, obj, pkcs7); return obj; }
PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, EVP_MD *dgst) { PKCS7_SIGNER_INFO *si; if ((si=PKCS7_SIGNER_INFO_new()) == NULL) goto err; if (!PKCS7_SIGNER_INFO_set(si,x509,pkey,dgst)) goto err; if (!PKCS7_add_signer(p7,si)) goto err; return(si); err: return(NULL); }
/* * SIGNER INFO */ static VALUE ossl_pkcs7si_alloc(VALUE klass) { PKCS7_SIGNER_INFO *p7si; VALUE obj; if (!(p7si = PKCS7_SIGNER_INFO_new())) { ossl_raise(ePKCS7Error, NULL); } WrapPKCS7si(klass, obj, p7si); return obj; }
static VALUE ossl_pkcs7si_new(PKCS7_SIGNER_INFO *p7si) { PKCS7_SIGNER_INFO *pkcs7; VALUE obj; obj = NewPKCS7si(cPKCS7Signer); pkcs7 = p7si ? ossl_PKCS7_SIGNER_INFO_dup(p7si) : PKCS7_SIGNER_INFO_new(); if (!pkcs7) ossl_raise(ePKCS7Error, NULL); SetPKCS7si(obj, pkcs7); return obj; }
/* Allocate the SCEP_MSG structures */ SCEP_MSG *SCEP_MSG_new( int messageType, X509 *cert, EVP_PKEY *pkey, X509 *recip_cert, SCEP_MSG *inMsg, X509_REQ *req, X509 *issued_cert, SCEP_ISSUER_AND_SUBJECT *cert_info, PKCS7_ISSUER_AND_SERIAL *ias, X509_CRL *crl, X509 *cacert, EVP_CIPHER cipher ) { SCEP_MSG *msg = NULL; PKCS7_SIGNER_INFO *si = NULL; EVP_MD *dgst=NULL; unsigned char *raw_data = NULL; int envelope = 0; long raw_len = 0; BIO *debug_bio = NULL; BIO *p7ebio = NULL; BIO *inbio = NULL; char buf[256]; if ((debug_bio=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(debug_bio,stderr,BIO_NOCLOSE|BIO_FP_TEXT); //if( !cert || !pkey || !recip_cert ) if( !cert || !pkey ) return NULL; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Generating New SCEP-Message...\n", __FILE__, __LINE__); /* Allocate memory and initialize structures */ if((msg = SCEP_MSG_new_null()) == NULL) return NULL; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Allocate memory\n", __FILE__, __LINE__); /* Signed Infos */ dgst = (EVP_MD *) EVP_get_digestbyname("md5"); if( (si = PKCS7_SIGNER_INFO_new()) == NULL ) goto err; if(!PKCS7_SIGNER_INFO_set(si, cert, pkey, dgst)) goto err; sk_PKCS7_SIGNER_INFO_push( msg->sk_signer_info, si ); msg->signer_ias = si->issuer_and_serial; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] signer infos set\n", __FILE__, __LINE__); /* If pkey, let's add to the message structure to ease * message encryption (enveloped data content creation) */ SCEP_MSG_set_pkey ( msg, pkey ); // msg->signer_pkey = pkey; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] encryption key set\n", __FILE__, __LINE__); /* If not explicit, we guess the certificate to be present * in the passed inMsg structure, if any. Otherwise ERROR! */ if( !recip_cert && inMsg ) recip_cert = inMsg->signer_cert; /* Set the messageType */ SCEP_set_messageType ( msg, messageType ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] message type set\n", __FILE__, __LINE__); switch( messageType ) { case MSG_CERTREP: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for CERTREP\n", __FILE__, __LINE__); msg->env_data.NID_p7data = NID_pkcs7_signed; msg->env_data.p7 = PKCS7_new(); PKCS7_set_type( msg->env_data.p7, NID_pkcs7_signed ); PKCS7_content_new( msg->env_data.p7, NID_pkcs7_data ); if( issued_cert ) { if (debug) BIO_printf( debug_bio, "%s:%d: creating inner degenerated PKCS7... \n", __FILE__, __LINE__); /* Adds issued certificate */ PKCS7_add_certificate( msg->env_data.p7, issued_cert ); // PKCS7_add_certificate( msg->env_data.p7, cert ); envelope = 1; if (debug) BIO_printf( debug_bio, "%s:%d: done \n", __FILE__, __LINE__); } else if( crl ) { if (debug) BIO_printf( debug_bio, "%s:%d: Adding CRL ... \n", __FILE__, __LINE__); /* Adds crl */ PKCS7_add_crl( msg->env_data.p7, crl ); envelope = 1; if (debug) BIO_printf( debug_bio, "%s:%d: done \n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_PKCSREQ: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for PKCSREQ\n", __FILE__, __LINE__); /* The inner pkcs7 structure is signed * and enveloped and the data is to be * the X509_REQ passed */ msg->env_data.NID_p7data = NID_pkcs7_signedAndEnveloped; if( req ) { msg->env_data.content.req = req; /* Ask for the data p7 to be generated and * encrypted */ envelope = 1; } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_GETCRL: if (debug) { BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCRL\n", __FILE__, __LINE__); BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } break; case MSG_GETCERT: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCERT\n", __FILE__, __LINE__); msg->env_data.NID_p7data = NID_pkcs7_signedAndEnveloped; /* If it is a query for a general certificate * the CAcert should be included in the enveloped * data*/ /* Otherwise, if it is a request for its own * certificate, the self-signed certificate should * be included */ // if( cacert ) // msg->env_data.cacert = cacert; /* Issuer and Serial should be present ! */ if( !ias ) goto err; msg->env_data.content.ias = ias; envelope = 1; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_GETCERTINITIAL: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCERTINITIAL\n", __FILE__, __LINE__); msg->env_data.NID_p7data = NID_pkcs7_signed; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_V2REQUEST: /* Not currently handled */ if (debug) { BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for V2REQUEST\n", __FILE__, __LINE__); BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } default: goto err; } if (debug) BIO_printf( debug_bio, "%s:%d: Debug ... \n", __FILE__, __LINE__); /* If different from NULL, we have to encode something */ if( envelope == 1 ) { if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] encode\n", __FILE__, __LINE__); /* Encrypt the message data */ if( !SCEP_MSG_encrypt( msg, recip_cert, cipher )) goto err; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] add sign-cert to structure\n", __FILE__, __LINE__); /* Signer certificate */ msg->signer_cert = cert; if (debug) PEM_write_bio_SCEP_MSG( debug_bio, msg, pkey ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] add attributes\n", __FILE__, __LINE__); /* Set message attributes, if any */ if ( inMsg ) { char *tmp = NULL; int len = 0; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] take data from request\n", __FILE__, __LINE__); switch ( msg->messageType ) { default: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set transId\n", __FILE__, __LINE__); /* The transId is ever required */ tmp = SCEP_get_string_attr_by_name( inMsg->attrs, "transId"); if( tmp ) { SCEP_set_transId( msg, tmp, strlen(tmp)); OPENSSL_free( tmp ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set recipient nonce (sendernonce from req)\n", __FILE__, __LINE__); /* Copy the sendernonce to the recipient nonce and * generate a new sendernonce for the generated msg */ tmp = SCEP_get_octect_attr_by_name( inMsg->attrs, "senderNonce", &len); if( tmp ) { if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] %d\n", __FILE__, __LINE__, tmp); SCEP_set_recipientNonce( msg, tmp, len ); OPENSSL_free( tmp ); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set sender nonce\n", __FILE__, __LINE__); SCEP_set_senderNonce_new(msg); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set pki_status\n", __FILE__, __LINE__); SCEP_set_pkiStatus ( msg, PKI_PENDING ); if (debug) { BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } } else { if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] generate new data\n", __FILE__, __LINE__); SCEP_set_senderNonce_new ( msg ); SCEP_set_recipientNonce_new ( msg ); SCEP_set_transId_new ( msg ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) PEM_write_bio_SCEP_MSG( debug_bio, msg, pkey ); return (msg); err: ERR_print_errors_fp(stderr); return(NULL); }