Hi Andy,

You where right about the version 0.9.3(a).
I made the following relevant modifications:

  - changed the sign.c/verify.c and enc.c/dec.c to be functions 
    callable by a program. (I also made a small testprogram
    calling these functions.)
  - modified the 'envelopedData' handling as it didn't comply with 
    the S/MIME specification.
  - tested to change (bigger) the read buffer size in 'dec' to see if this
    would decrease the time, but without luck (it's 100K in the example).
  - Finally I also changed the input/output format from PEM to DER, as this
    is what we want in the calling application.

I also tried to dig down in the decryption code but gave up, )its really
magic). So if you have any idea where to look I would be very greatful.

Thanks for your support.
/Bo

Code extracts from dec:
------dec start--------
 int dec_verify_callback(int ok, X509_STORE_CTX *ctx);

BIO *dec_bio_err=NULL;

int dtc_dec(char *encFile, char *docFile, char* certFile, char *keyFile, char* caFile){
BIO *in = NULL;
 FILE *out = NULL;
 EVP_PKEY *pkey;
 X509 *x509;
 PKCS7 *p7 = NULL;
 PKCS7_SIGNER_INFO *si;
 X509_STORE_CTX cert_ctx;
 X509_STORE *cert_store=NULL;
 BIO *data = NULL,*detached=NULL,*p7bio=NULL;
 char buf[102400*4];
 int i,printit=0;
 STACK *sk;

 SSLeay_add_all_algorithms();
 dec_bio_err=BIO_new_fp(stderr,BIO_NOCLOSE);

 data=BIO_new(BIO_s_file());
 if (!BIO_read_filename(data, encFile)) goto err;
 
        if ((out = fopen(docFile,"w")) == NULL) goto err;
 
        if ((in=BIO_new_file(certFile,"r")) == NULL) goto err;
        if ((x509=PEM_read_bio_X509(in,NULL,NULL)) == NULL) goto err;
        BIO_free(in);
 in = NULL;

        if ((in=BIO_new_file(keyFile,"r")) == NULL) goto err;
        if ((pkey=PEM_read_bio_PrivateKey(in,NULL,NULL)) == NULL) goto err;
        BIO_free(in);
 in = NULL;

 /* Load the PKCS7 object from a file */
 if ((p7=d2i_PKCS7_bio(data,NULL)) == NULL) goto err;

 
 /* This stuff is being setup for certificate verification.
  * When using SSL, it could be replaced with a 
  * cert_stre=SSL_CTX_get_cert_store(ssl_ctx); */
 cert_store=X509_STORE_new();
 X509_STORE_set_default_paths(cert_store);

 X509_STORE_load_locations(cert_store, caFile, NULL);
 X509_STORE_set_verify_cb_func(cert_store,dec_verify_callback);

 ERR_clear_error();

 /* We need to process the data */
 /* We cannot support detached encryption */
 p7bio=PKCS7_dataDecode(p7,pkey,detached,x509);
 
 if (p7bio == NULL)
  {
  printf("problems decoding\n");
  goto err;
  }

 /* We now have to 'read' from p7bio to calculate digests etc. */
 for (;;)
  {
  i=BIO_read(p7bio,buf,sizeof(buf));
  /* print it? */
  if (i <= 0) break;
  fwrite(buf,1, i, out);
  }

 /* We can now verify signatures */
 sk=PKCS7_get_signer_info(p7);
 if (sk != NULL)
  {
  /* Ok, first we need to, for each subject entry,
   * see if we can verify */
  ERR_clear_error();
  for (i=0; i<sk_num(sk); i++)
   {
   si=(PKCS7_SIGNER_INFO *)sk_value(sk,i);
   i=PKCS7_dataVerify(cert_store,&cert_ctx,p7bio,p7,si);
   if (i <= 0)
    goto err;
   else
    fprintf(stderr,"Signature verified\n");
   }
  }
 X509_STORE_free(cert_store);
/* 
 PKCS7_free(p7);
*/
 BIO_free(data);
 BIO_free(p7bio);
 
 fclose(out);
 return(0);
err:
 ERR_load_crypto_strings();
 ERR_print_errors_fp(stderr);

 if(cert_store != NULL) X509_STORE_free(cert_store);
/*
   if(p7 != NULL) PKCS7_free(p7);
*/
 if(in != NULL) BIO_free(in);
 if(data != NULL) BIO_free(data);
 if(p7bio != NULL) BIO_free(p7bio);
 if(out != NULL) fclose(out);
 
 return(1);
 }

/* should be X509 * but we can just have them as char *. */
int dec_verify_callback(int ok, X509_STORE_CTX *ctx)
 {
 char buf[256];
 X509 *err_cert;
 int err,depth;

 err_cert=X509_STORE_CTX_get_current_cert(ctx);
 err= X509_STORE_CTX_get_error(ctx);
 depth= X509_STORE_CTX_get_error_depth(ctx);

 X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);
 BIO_printf(dec_bio_err,"depth=%d %s\n",depth,buf);
 if (!ok)
  {
  BIO_printf(dec_bio_err,"verify error:num=%d:%s\n",err,
   X509_verify_cert_error_string(err));
  if (depth < 6)
   {
   ok=1;
   X509_STORE_CTX_set_error(ctx,X509_V_OK);
   }
  else
   {
   ok=0;
   X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
   }
  }
 switch (ctx->error)
  {
 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
  X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,256);
  BIO_printf(dec_bio_err,"issuer= %s\n",buf);
  break;
 case X509_V_ERR_CERT_NOT_YET_VALID:
 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
  BIO_printf(dec_bio_err,"notBefore=");
  ASN1_UTCTIME_print(dec_bio_err,X509_get_notBefore(ctx->current_cert));
  BIO_printf(dec_bio_err,"\n");
  break;
 case X509_V_ERR_CERT_HAS_EXPIRED:
 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
  BIO_printf(dec_bio_err,"notAfter=");
  ASN1_UTCTIME_print(dec_bio_err,X509_get_notAfter(ctx->current_cert));
  BIO_printf(dec_bio_err,"\n");
  break;
  }
 BIO_printf(dec_bio_err,"verify return:%d\n",ok);
 return(ok);
 }
------START end--------

------START pkcs7 related ASN.1 code (from /crypto/asn1: p7_enc_c.c ,p7_evp.c and 
p7_lib.c )-----
/* it is this function that is changed the other ASN.1 related functions below is just 
to make the
call to this function using the 'dtc_' prefix. (I havent changed the original 
functions, but added
this as 'my own' overriding the original openssl code.*/
int dtc_i2d_PKCS7_ENC_CONTENT(PKCS7_ENC_CONTENT *a, unsigned char **pp)
{
   M_ASN1_I2D_vars(a);

 M_ASN1_I2D_len(a->content_type,i2d_ASN1_OBJECT);
 M_ASN1_I2D_len(a->algorithm,i2d_X509_ALGOR);
 /* dtc compensation for INF SEQ in ENC_CONTENT */
 ret += 4;
 /* dtc_ M_ASN1_I2D_len_IMP_opt(a->enc_data,i2d_ASN1_OCTET_STRING);
  * is replaced by: */
  M_ASN1_I2D_len(a->enc_data,i2d_ASN1_OCTET_STRING); 
 M_ASN1_I2D_seq_total();

 /* dtc_ changed due to the fact that Netscape Messenger and
  * WorldSecure are using 'data' instead of 'encryptedData' */
 a->content_type->data[8] = OBJ_pkcs7_data;
 
   M_ASN1_I2D_put(a->content_type,i2d_ASN1_OBJECT);

 /* dtc_ Restoring it to avoid problems */
 a->content_type->data[8] = OBJ_pkcs7_encrypted;
 
 M_ASN1_I2D_put(a->algorithm,i2d_X509_ALGOR);
 M_ASN1_I2D_INF_seq_start(0,V_ASN1_CONTEXT_SPECIFIC);
 /* dtc_ M_ASN1_I2D_put_IMP_opt(a->enc_data,i2d_ASN1_OCTET_STRING,0);
  * is replaced by: */
 M_ASN1_I2D_put(a->enc_data,i2d_ASN1_OCTET_STRING);
 M_ASN1_I2D_INF_seq_end();
 M_ASN1_I2D_finish();
}

/* From: crypto/asn1/p7_evp.c */
/* 
 * This function replaces the corresponding i2d_PKCS7_ENVELOPE
 * function in the crypto/asn1/p7_evp.c module. It is replaced
 * due to a bug in the i2d_PKCS7_ENC_CONTENT part, called below.
 */

int dtc_i2d_PKCS7_ENVELOPE(PKCS7_ENVELOPE *a, unsigned char **pp)
 {
 M_ASN1_I2D_vars(a);

 M_ASN1_I2D_len(a->version,i2d_ASN1_INTEGER);
 M_ASN1_I2D_len_SET(a->recipientinfo,i2d_PKCS7_RECIP_INFO);
 /* Replaced i2d_PKCS7_ENC_CONTENT */
 M_ASN1_I2D_len(a->enc_data,dtc_i2d_PKCS7_ENC_CONTENT);

 M_ASN1_I2D_seq_total();

 M_ASN1_I2D_put(a->version,i2d_ASN1_INTEGER);
 M_ASN1_I2D_put_SET(a->recipientinfo,i2d_PKCS7_RECIP_INFO);
 /* Replaced i2d_PKCS7_ENC_CONTENT */
   M_ASN1_I2D_put(a->enc_data,dtc_i2d_PKCS7_ENC_CONTENT);

 M_ASN1_I2D_finish();
 }


/* From: crypto/asn1/p7_lib.c */
/* 
 * This function replaces the corresponding i2d_PKCS7 function
 * in the crypto/asn1/p7_lib.c module. It is replaced due to a
 * bug in the i2d_PKCS7_ENC_CONTENT part, which is called by the
 * i2d_PKCS7_ENVELOPE below.
 */

int dtc_i2d_PKCS7(PKCS7 *a, unsigned char **pp)
 {
 M_ASN1_I2D_vars(a);

 if (a->asn1 != NULL)
  {
  if (pp == NULL)
   return((int)a->length);
  memcpy(*pp,a->asn1,(int)a->length);
  *pp+=a->length;
  return((int)a->length);
  }

 ret+=4; /* sequence, BER header plus '0 0' end padding */
 M_ASN1_I2D_len(a->type,i2d_ASN1_OBJECT);
 if (a->d.ptr != NULL)
  {
  ret+=4; /* explicit tag [ 0 ] BER plus '0 0' */
  switch (OBJ_obj2nid(a->type))
   {
  case NID_pkcs7_data:
   M_ASN1_I2D_len(a->d.data,i2d_ASN1_OCTET_STRING);
   break;
  case NID_pkcs7_signed:
   M_ASN1_I2D_len(a->d.sign,i2d_PKCS7_SIGNED);
   break;
  case NID_pkcs7_enveloped:
   /* Replaced i2d_PKCS7_ENVELOPE */
   M_ASN1_I2D_len(a->d.enveloped,dtc_i2d_PKCS7_ENVELOPE);
   break;
  case NID_pkcs7_signedAndEnveloped:
   M_ASN1_I2D_len(a->d.signed_and_enveloped,
    i2d_PKCS7_SIGN_ENVELOPE);
   break;
  case NID_pkcs7_digest:
   M_ASN1_I2D_len(a->d.digest,i2d_PKCS7_DIGEST);
   break;
  case NID_pkcs7_encrypted:
   M_ASN1_I2D_len(a->d.encrypted,i2d_PKCS7_ENCRYPT);
   break;
  default:
   break;
   }
  }
 r=ret;
 if (pp == NULL) return(r);
 p= *pp;
 M_ASN1_I2D_INF_seq_start(V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
 M_ASN1_I2D_put(a->type,i2d_ASN1_OBJECT);

 if (a->d.ptr != NULL)
  {
  M_ASN1_I2D_INF_seq_start(0,V_ASN1_CONTEXT_SPECIFIC);
  switch (OBJ_obj2nid(a->type))
   {
  case NID_pkcs7_data:
   M_ASN1_I2D_put(a->d.data,i2d_ASN1_OCTET_STRING);
   break;
  case NID_pkcs7_signed:
   M_ASN1_I2D_put(a->d.sign,i2d_PKCS7_SIGNED);
   break;
  case NID_pkcs7_enveloped:
   /* Replaced i2d_PKCS7_ENVELOPE */
   M_ASN1_I2D_put(a->d.enveloped,dtc_i2d_PKCS7_ENVELOPE);
   break;
  case NID_pkcs7_signedAndEnveloped:
   M_ASN1_I2D_put(a->d.signed_and_enveloped,
    i2d_PKCS7_SIGN_ENVELOPE);
   break;
  case NID_pkcs7_digest:
   M_ASN1_I2D_put(a->d.digest,i2d_PKCS7_DIGEST);
   break;
  case NID_pkcs7_encrypted:
   M_ASN1_I2D_put(a->d.encrypted,i2d_PKCS7_ENCRYPT);
   break;
  default:
   break;
   }
  M_ASN1_I2D_INF_seq_end();
  }
 M_ASN1_I2D_INF_seq_end();
 M_ASN1_I2D_finish();
 }

---- END pkcs7 ASN.1 related code------
 

----- Ursprungligt meddelande ----- 
Från: Andy Polyakov <[EMAIL PROTECTED]>
Till: <[EMAIL PROTECTED]>
Skickat: den 13 augusti 1999 15:35
Ämne: Re: Performance


> > >> I am using a partly modified PKCS7 enc.c and dec.c for
> > >> encrypting and decrypting documents.
> > >> When encrypting an 8,5MB file it takes about 1 minute,
> > >> however when decrypting it the time runs up to 20  minutes.
> > >Which platform? Which compiler? What does './config -t' say?
> > './config -t' says:
> >   Operating system: sun4u-sun-solaris2
> >   gcc version egcs-2.90.x
> >   Configuring for solaris-usparc-oldgcc
> I managed to reproduce it on 0.9.3[a] as this's what you must have. This
> -oldgcc thing was fixed and usparc was changed to sparcv9 in 0.9.4. I
> experience much bigger differences in execution times. I managed to
> ./crypto/pkc7/enc 12MB file in 8 seconds, while dec took over 8 minutes.
> You mentioned it was "partly modified". Can you post your code? If it's
> big, then post it to me, I'll summarize. Did you try it with 0.9.4? I
> didn't manage to compile ./crypto/pkc7/[enc|dec].c just yet...
> 
> Andy.
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> Development Mailing List                       [EMAIL PROTECTED]
> Automated List Manager                           [EMAIL PROTECTED]
> 

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [EMAIL PROTECTED]
Automated List Manager                           [EMAIL PROTECTED]

Reply via email to