zxid

 view release on metacpan or  search on metacpan

zxsig.c  view on Meta::CPAN

    ERR("Symmetric key decryption failure. Perhaps symmetric key derived from assymmetric level is wrong, i.e. certificate used for encryption does not match the private key %d", 0);
    zxlog(cf, 0, 0, 0, 0, 0, 0, 0, "N", "C", "ECRYPT", 0, "symmetric decrypt failed");
    return 0;
  }
  ZX_FREE(cf->ctx, raw.s);
  DD("plain(%.*s)", ss->len, ss->s);
  D_XML_BLOB(cf, "PLAIN", ss->len, ss->s);
  return ss;

 wrong_key_len:
  ZX_FREE(cf->ctx, raw.s);
  ERR("Wrong key length %d for algo(%.*s)", symkey->len, ss->len, ss->s);
  zxlog(cf, 0, 0, 0, 0, 0, 0, 0, "N", "C", "ECRYPT", 0, "wrong key length");
  return 0;

 backwards_compat_disa:
  ERR("Backwards compatibility not enabled, old key transformation method(%.*s) blocked", ss->len, ss->s);
  zxlog(cf, 0, 0, 0, 0, 0, 0, 0, "N", "C", "EBC", 0, "backwards compatible method not enabled");
  return 0;
}

/*() Private key decryption using XML-ENC. The encryption algorithm is
 * auto-detected from the XML-ENC data. The private key is looked up
 * from the configuration object.
 *
 * cf:: ZXID configuration object, used for memory allocation
 * ed:: Encrypted data as XML data structure
 * ek:: Symmetric encryption key data structure. If not supplied, the EncryptedKey
 *     element from EncryptedData is used
 * return:: Decrypted data as zx_str. Caller should free this memory. */

/* Called by:  zxid_dec_a7n, zxid_decrypt_nameid, zxid_decrypt_newnym, zxid_get_ses_sso_a7n */
struct zx_str* zxenc_privkey_dec(zxid_conf* cf, struct zx_xenc_EncryptedData_s* ed, struct zx_xenc_EncryptedKey_s* ek)
{
  EVP_PKEY* enc_pkey;
  RSA* rsa;
  struct zx_str raw;
  struct zx_str* symkey;
  struct zx_str* ss;
  char* lim;

  if (!ed) {
    ERR("Missing or malformed EncryptedData %d", 0);
    return 0;
  }

  if (!ek && ed->KeyInfo)
    ek = ed->KeyInfo->EncryptedKey;  /* Nested EncryptionKey method (Shib 2010) */
  if (!ek || !ek->CipherData || !(ss = ZX_GET_CONTENT(ek->CipherData->CipherValue)) || !ss->len) {
    ERR("EncryptedKey element not found or malformed %p", ek->CipherData);
    zxlog(cf, 0, 0, 0, 0, 0, 0, 0, "N", "C", "EMISS", 0, "EncryptedKey not found");
    return 0;
  }
  
  raw.s = ZX_ALLOC(cf->ctx, SIMPLE_BASE64_PESSIMISTIC_DECODE_LEN(ss->len));
  lim = unbase64_raw(ss->s, ss->s+ss->len, raw.s, zx_std_index_64);
  raw.len = lim - raw.s;
  
  LOCK(cf->mx, "zxenc_privkey_dec");      
  if (!(enc_pkey = cf->enc_pkey))
    enc_pkey = cf->enc_pkey = zxid_read_private_key(cf, "enc-nopw-cert.pem");
  UNLOCK(cf->mx, "zxenc_privkey_dec");      
  if (!enc_pkey)
    return 0;
  
  if (!ek->EncryptionMethod || !(ss = &ek->EncryptionMethod->Algorithm->g) || !ss->len) {
    ERR("Missing or malformed EncryptionMethod %p", ek->EncryptionMethod);
    return 0;
  }
  
  if (sizeof(ENC_KEYTRAN_RSA_1_5)-1 == ss->len
      && !memcmp(ENC_KEYTRAN_RSA_1_5, ss->s, sizeof(ENC_KEYTRAN_RSA_1_5)-1)) {
    if (!(cf->backwards_compat_ena & ZXID_BACKWARDS_COMPAT_ACCEPT)) {
      ERR("PKCS#1 v1.5 disabled to prevent Backwards Compatibility Attacks (see http://www.nds.ruhr-uni-bochum.de/research/publications/backwards-compatibility/) %d",0);
      zxlog(cf, 0, 0, 0, 0, 0, 0, 0, "N", "C", "EBC", 0, "Ciphersuite rejected to prevent backwards compatibility attacks");
      return 0;
    }
    rsa = EVP_PKEY_get1_RSA(enc_pkey);
    symkey = zx_rsa_priv_dec(cf->ctx, &raw, rsa, RSA_PKCS1_PADDING);
  } else if (sizeof(ENC_KEYTRAN_RSA_OAEP)-1 == ss->len
	     && !memcmp(ENC_KEYTRAN_RSA_OAEP, ss->s, sizeof(ENC_KEYTRAN_RSA_OAEP)-1)) {
    rsa = EVP_PKEY_get1_RSA(enc_pkey);
    symkey = zx_rsa_priv_dec(cf->ctx, &raw, rsa, RSA_PKCS1_OAEP_PADDING);
  } else {
    ERR("Unsupported key transformation method(%.*s)", ss->len, ss->s);
    zxlog(cf, 0, 0, 0, 0, 0, 0, 0, "N", "C", "ECRYPT", 0, "unsupported key transformation method");
    return 0;
  }
  ZX_FREE(cf->ctx, raw.s);
  if (symkey) {
    ss = zxenc_symkey_dec(cf, ed, symkey);
    zx_str_free(cf->ctx, symkey);
    return ss;
  } else
    return 0;
}

/*() Symmetric key encryption using XML-ENC. The encryption algorith is
 * auto-detected from the XML-ENC data.
 *
 * cf:: ZXID configuration object, used for memory allocation
 * data:: Data blob to encrypt. Typically serialized XML
 * ed_id:: The value of the ~Id~ XML attribute of the <EncryptedData> element
 * symkey:: Raw symmetric key used for encryption
 * symkey_id:: The value of the ~Id~ XML attribute of the <EncryptedKey> element
 * return:: Encrypted data as XML data structure. Caller should free this memory.
 *
 * *Example of XML-ENC encrypted data using RetrievalMethod pointing to EncryptedID Id="EK38"*
 *
 *   <sa:EncryptedID>
 *     <e:EncryptedData
 *         xmlns:e="http://www.w3.org/2001/04/xmlenc#"
 *         Id="ED38"
 *         Type="http://www.w3.org/2001/04/xmlenc#Element">
 *       <e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-gcm"/>
 *       <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
 *         <ds:RetrievalMethod
 *             Type="http://www.w3.org/2001/04/xmlenc#EncryptedKey"
 *             URI="#EK38"/></>                                            # N.B. hash
 *       <e:CipherData>
 *         <e:CipherValue>FWfOV7aytBE2xIMe...YTA3ImLf9JCM/vdLIMizMf1</></></>



( run in 0.811 second using v1.01-cache-2.11-cpan-71847e10f99 )