More details on how the 'quirk' came into being.
 
We have provided our end users the ability to pass into PKCS7 Encryption any 
cipher that was allowed. We do not recommend or dissuade them from using any 
cipher that is available. While it may not be a good idea, our end users (large 
numbers) may have used the unwise cipher choice and we would like to avoid 
regressing their implementation. 
 
It seems that several ciphers are prevented from being used by PKCS7 
encryption, via the settings in obj_dat.h as it is processed via the  following 
code path: 
 
we call PKCS7_encrypt() passing in an evp_cipher_st 
 
crypto/pkcs7/pk7_smime.c -- PKCS7_encrypt() hits:
 if(!PKCS7_set_cipher(p7, cipher)) {
  PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
  goto err;
 } 
 
crypto/pkcs7/pk7_lib.c -- PKCS7_set_cipher() hits:
 /* Check cipher OID exists and has data in it*/
 i = EVP_CIPHER_type(cipher);
 if(i == NID_undef) {
  PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
  return(0);
 }
 
crypto/evp/evp_lib.c -- EVP_CIPHER_type() hits: 
  default:
  /* Check it has an OID and it is valid */
  otmp = OBJ_nid2obj(nid);
 
crypto/objects/obj_dat.c -- OBJ_nid2obj() hits: 
  return((ASN1_OBJECT *)&(nid_objs[n]));
 
we return to:
crypto/evp/evp_lib.c -- EVP_CIPHER_type() and hit:
  if(!otmp || !otmp->data) nid = NID_undef;
  ASN1_OBJECT_free(otmp);
  return nid;
  
And for any Ciphers where otmp->data is NULL, then the PKCS7 Encryption does 
not proceed.
 
So, looking at crypto/objects/obj_dat.h, we can see which DES ciphers will or 
won't work:
 
{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[187]),0},
{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[192]),0},
{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[197]),0},
{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[202]),0},
{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL},
{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL},
{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[236]),0},
{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[244]),0},
{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL},
{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL},
{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL},
{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL},
 
So, it seems the ability to prevent a cipher from being used in PKCS7 is 
available and is being used in some cases. The settings while inconsistent, are 
deterministic for this process. Can we define the ability to use des-ecb and 
des-ede is as a Bug or a Feature? If it is a bug, then what is the impact of 
fixing it (in our case it is large, since we will have to keep the capability 
in place to decrypt everything first, then remove the capability and rebuild 
the encryption definition and re-encrypt). If it is a Feature, then the 9.8m 
(and other releases?) release regressed this Feature and should have a fix 
applied.


More details on how the 'quirk' came into being.
 
We have provided our end users the ability to pass into PKCS7 Encryption any cipher that was allowed. We do not recommend or dissuade them from using any cipher that is available. While it may not be a good idea, our end users (large numbers) may have used the unwise cipher choice and we would like to avoid regressing their implementation.
 
It seems that several ciphers are prevented from being used by PKCS7 encryption, via the settings in obj_dat.h as it is processed via the  following code path:
 
we call PKCS7_encrypt() passing in an evp_cipher_st
 
crypto/pkcs7/pk7_smime.c -- PKCS7_encrypt() hits:
 if(!PKCS7_set_cipher(p7, cipher)) {
  PKCS7err(PKCS7_F_PKCS7_ENCRYPT,PKCS7_R_ERROR_SETTING_CIPHER);
  goto err;
 } 
 
crypto/pkcs7/pk7_lib.c -- PKCS7_set_cipher() hits:
 /* Check cipher OID exists and has data in it*/
 i = EVP_CIPHER_type(cipher);
 if(i == NID_undef) {
  PKCS7err(PKCS7_F_PKCS7_SET_CIPHER,PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
  return(0);
 }
 
crypto/evp/evp_lib.c -- EVP_CIPHER_type() hits: 
  default:
  /* Check it has an OID and it is valid */
  otmp = OBJ_nid2obj(nid);
 
crypto/objects/obj_dat.c -- OBJ_nid2obj() hits: 
  return((ASN1_OBJECT *)&(nid_objs[n]));
 
we return to:
crypto/evp/evp_lib.c -- EVP_CIPHER_type() and hit:
  if(!otmp || !otmp->data) nid = NID_undef;
  ASN1_OBJECT_free(otmp);
  return nid;
  
And for any Ciphers where otmp->data is NULL, then the PKCS7 Encryption does not proceed.
 
So, looking at crypto/objects/obj_dat.h, we can see which DES ciphers will or won't work:
 
{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[187]),0},
{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[192]),0},
{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[197]),0},
{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[202]),0},
{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL},
{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL},
{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[236]),0},
{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[244]),0},
{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL},
{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL},
{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL},
{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL},
 
So, it seems the ability to prevent a cipher from being used in PKCS7 is available and is being used in some cases. The settings while inconsistent, are deterministic for this process. Can we define the ability to use des-ecb and des-ede is as a Bug or a Feature? If it is a bug, then what is the impact of fixing it (in our case it is large, since we will have to keep the capability in place to decrypt everything first, then remove the capability and rebuild the encryption definition and re-encrypt). If it is a Feature, then the 9.8m (and other releases?) release regressed this Feature and should have a fix applied.

Reply via email to