pax_global_header00006660000000000000000000000064132614500000014501gustar00rootroot0000000000000052 comment=c9d526fe0d3a82d8768010f5e7d2583247337e9a jss-4.4.3/jss/000077500000000000000000000000001326145000000131075ustar00rootroot00000000000000jss-4.4.3/jss/.classpath000066400000000000000000000004411326145000000150710ustar00rootroot00000000000000 jss-4.4.3/jss/.gitignore000066400000000000000000000000041326145000000150710ustar00rootroot00000000000000bin jss-4.4.3/jss/.hgignore000066400000000000000000000000621326145000000147100ustar00rootroot00000000000000syntax: glob *~ *OPT.OBJ/* *DBG.OBJ/* *DBG.OBJD/* jss-4.4.3/jss/.hgtags000066400000000000000000002337301326145000000143750ustar00rootroot000000000000002fb3cc431eaf7fb2a5f2ebd725919a2b2d2a3538 NSS_3_13_6_BETA1 632a7d5f5979af88c35c83aab811167b48f28264 ANGELON_MOZ12_N7_BASE 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030825N10_WIN_MAC 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0b2_RC1 fab631d240c1f62f5f0c57606807d1a85b7965d8 FIREFOX_1_5rc3_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_8_RC2 a37448e7fc6b6e74bbf541d948d64f4f5b53492b NSS_3_14_3_RTM 6e5d2811a1fd06b384305de025b9bcc83c8800ce MOZILLA_1_4_2_RELEASE d25943fa7e9356faf6f34d54b3366286b52aab0f SUN_SECURITY_3_3_5_BETA cf7a207a21764cdb0302283aa60c0b6728eadf76 NSS_3_14_BETA1 3b30df21c44697dafbcc72a852b6d0981884ad1d NSS_3_13_1_BETA2 e4b85ba92b45eccb1cd002bdfa65561dc21d98df WEB_CONTENT_HANDLING_20070621_POSTMERGE_20070719_FIXED 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 MOZILLA_1_8_0_5_RC2 97484fae41d7178c9b49c0061a54e08bea6ac1e2 MAIL_05312002_BASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba NSS_3_11_10_RC2 8c8fa0bf2716618abab883b21238b5e75d3f96ba NSS_3_11_10_RC3 088c8995ec01f0d5bef81ef05d7d8394e20ca95d NSS_CLIENT_TAG_20031219 4743208e8b17df941141129a2a52c29e0fd9f623 FIREFOX_1_1a2_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba CAMINO_1_6_4_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_14_RELEASE 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d NSS_3_11_20060831_TAG 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 MOZILLA_1_8_0_5_RC4 cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0rc2_RELEASE b0a5cce2b8eac43a93b1ebeb559539ee30b90d29 DBM_1_6_BETA1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_5_RC3 b490a04b5901c40325759a9d291c5483dec80f9c NSS_MULTIACCESS_DB_TAG_20020818_1 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030424N6_WIN_FREEZE 72576aea622fc2605c022255a6d9676a59fb0bc8 SECURITY_3_3_10_RTM 93db6ac782a7674f778e13e6fd76e476e976d6dd MOZILLA_0_9_6_BASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a NSS_3_9_5_RTM 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_5_RC5 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_5_RC4 369f0fdceee9efd93e2370fbc8bff1c64ac19951 MOZILLA_1_5_RELEASE d202384960644e05f4ca75f108017bce4c42e126 NSS_HEAD_20090409 474365e481fc8ff4aa0669da721959f624f5ba60 THUNDERBIRD_0_6_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_5_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba SUNBIRD_0_9_RELEASE b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa ISHMAIL_1_0_BASE 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 NSS_3_11_20060731_TAG 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_5_RELEASE e814268c0ce62a142d9a59bb1b40b409f9c7fdb3 FIREFOX_3_0_2_RELEASE 264f48fd2c146761f28f37cf85f7735ee1ab9306 NSS_3_14_1_WITH_CKBI_1_93_RTM c6c861c531c7bfb5f9bff4cd5c6e26d098c58ffe FIREFOX_3_0_3_RELEASE 6774cb4dcc18c8528af7e17fcd63bbb4b0cb7958 JSS_3_1_2_BETA2 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_5_RELEASE 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d NSS_3_11_20060905_TAG 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_6_RELEASE 9fe276bab59d7de37147289da0d44cca59523a86 SURESH_IM_STANDALONE_BASE b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa ANYTHING_FOR_PUTTERMAN_BASE dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_1_RELEASE c090553817020bebc7add9feda962a345f684bd1 MOZILLA_1_9a1_RELEASE dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_14_RELEASE b01a450f67bd88834edf82106f29346b1f3f83c0 NSS_3_13_6_WITH_CKBI_1_93_RTM 3a12a09b9afe3042c7b8ed9a076dd510aabc1ab6 NSS_3_14_1_BASE a7fe654cbee1b2528d82593abb3caedf92843349 MOZILLA_0_9_2_RELEASE 8f32a794dcaff756e5f4f5e4529f6b2cf97a410d MOZILLA_1_7a_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_15_BUILD3 93db6ac782a7674f778e13e6fd76e476e976d6dd MOZILLA_0_9_6_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 MOZILLA_1_7_BASE 691c29469688bd15b333087f9a8086042eea06b6 FIREFOX_2_0a2_RELEASE 24871f0a1700d3269f22c2b28fceb085a8f663d8 NSS_3_6_1_BETA1 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_14_RC1 ed51dfb14b02e3961dbad2de05cc2dcb5150b02f before_moz_pkg_names_20001218 9a9a6ec088da5b2ee90e01c3a24009307ed62cda NSS_3_6_1_BETA2 df4a3ec73cb2dce3f42dd6b9d31f9ad5780d02ac NSS_3_12_4_WITH_CKBI_1_77_RTM 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_17_RELEASE 597d9f501aa4a70676abda23b8d7e6baeb61639f PSM_2_2_DEV_20010917_BASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a SVRCORE_4_0_RTM 93db6ac782a7674f778e13e6fd76e476e976d6dd IFRAME_20011127_BASE 737048adb0e92456eb6e2914b26f054446d59f94 NSS_3_8_2_BETA2 9789d4aa9367a124f482a4ebb98496dfaf0f6630 NSS_3_3_3_BETA121402 c15a1e49702c907b26363c8ecc1d6cef3a1da7cc NSS31Beta1 32cacbe05614087fcd9109a3148745bb0d8ea895 NSS_3_12_3_RTM dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_18_BUILD1 d045187f1235aa4a7094d10a7d62c1e4ef2b4aab FIREFOX_3_0rc2_RELEASE d0086334bef987740efaa62c6511b992e7260f42 SUN_SECURITY_3_3_7_RTM cd197f30360fbaeb9c9412cb2ec41b3f48245a87 SAFEBROWSING_20060516_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_5_WITH_CKBI_1_65_RTM abe5f161a5874a2680c85db7c748330b2500aa62 REFLOW_20020422_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_7_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_7_RC3 485086fb339e3b813eef1336abf55a3129d5f47b THUNDERBIRD_0_5_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 MOZILLA_1_8a1_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_14_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_3_RELEASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df WEB_CONTENT_HANDLING_20070621_PREMERGE_20070607 4823072b9c679ac0b2eb4908b881656b5f92fde5 NSS_3_8_WTC_TMP 8dd789b87431dc7e8ac9a6cbeb6eb68368f7b8ab PSM20_M_2_TAG d7060989b2f556ce82d71cf66c3c5c41c3f2c924 JSS_3_7_RTM 6774cb4dcc18c8528af7e17fcd63bbb4b0cb7958 JSS_3_1_2_RTM 54aea9e2ed498d9201646731b5edac6a1d163237 SPLITWINDOW_20050714_INITIAL_TRUNK_LANDING 0d07d48542dd4e1b8127eab176aab3a22163dcbb MOZILLA_1_3_20030221_BASE 51ddfae95b1776e2395a71a4369aa7f138e296d4 FOLDER_OUTLINER_20010410_BASE 9efa376193ee3365a73882c2382638160f47055d MOZILLA_1_8b1_RELEASE fab631d240c1f62f5f0c57606807d1a85b7965d8 MOZILLA_1_8rc3_RELEASE cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0rc2_RC2 922ddfce3701316680c3ec20337b75ee7af19a6c FIREFOX_3_0_1_BUILD1 cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0rc2_RC1 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_9_RTM f634131089455dc7b3e7da9e1018071fe88e2cc8 SVRCORE_4_0_2_RTM 169da8dbc3f4a04e90d260e1c3c21d72bc7bf266 NSS_3_2_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_4_RELEASE e3138e74f881e36c14a7e94dd9b8fcbce0e398e8 NSS_3_12_RC4 d8707eaece03546c530f9625a8d8031b2e06bfc8 NSS_CLIENT_TAG_20020319 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_4_RC1 3a1dec3b9f837bc402545b4cf439cf3ce039fcb9 JSS_3_1_2_2_BETA1217_3 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 XULRUNNER_1_8_0_4_RELEASE 597d9f501aa4a70676abda23b8d7e6baeb61639f NETSCAPE_6_2_1_RELEASE 04d233c0cd1533f14b0f3c817a396213e53831c8 FIREFOX_3_0_7_RELEASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a XFORMS_20050106_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_14_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_2_RELEASE f379a9a8f9d3e74980ff5df7cafe65e6e7498662 NSS_3_7_1_BETA1 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 NSS_3_7_1_BETA2 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 NSS_3_7_1_BETA3 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_15_RELEASE 1e6c0f58db4358aa75c5874376ac0e466170493d NSS_3_2_REF 1b3dd88a855b13580872fa17e5361649434e5c41 SUN_SECURITY_3_3_5_WEBSERVER 3f122baa125c1d690bb64c1b3593f0387a20f24b NSS_3_12_ALPHA1B dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_B4_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 SEAMONKEY_1_0_7_RELEASE 228c7981035c84d9da192e4c0cf9e03d275d2cc6 moz_ux_20021026 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 NSS_3_7_2_BETA1 7e73a7c12464d8e5b01fc5d7200a4d21d9bdc48f NSS_3_12_RC1 389321fc597ddd31f1720fcbc7658289b617346c SUNBIRD_0_3a1_RELEASE 91ca64ab57f4d6761211c539ec57f836152fe41d nss_20021204 279746f8384085c604dcc5b67acaf7be298422d2 CAMINO_0_8_1_RELEASE 597d9f501aa4a70676abda23b8d7e6baeb61639f PSM_2_2_DEV_20011015 dd723df8492284680e8f08f6691c9addf356c259 THUNDERBIRD_2_0_0_24_RELEASE e479d669fd2b9ae586498139a692f22f515e37e4 NSS_3_10_1_BASE 8feb0a60ee6a2f8bb2fa4c68ad0910c25ac7cffa NSS_CLIENT_TAG_20020308 3ddbf2b0a2475cd9350c683cd7e3d96c3cafd328 PSM_1_2_RTM 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_8_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_12_RC1 8d919d9bda87abee1a8612df91562c99e7199fa7 MOZILLA_1_0_0_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_12_RC3 fab631d240c1f62f5f0c57606807d1a85b7965d8 THUNDERBIRD_1_5rc2_20051107-UNUSED_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_6_BYPASS_BASE 3c0bf75907571df309f6f316af8d021189ae3364 FIREFOX_3_0b5_RELEASE a4906c15406111f37a1501c42ee2f5d1acff42a4 JSS_4_2_4_RTM 448dcd4b0c94bcd577e6d39679ee0bef943c2e19 NSS_3_9_RTM 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e Accessible_052901_Base4 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d SUNBIRD_0_3_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_4_RC3 851f232cff3928c82cd61b23e2c8304cc696efbb EVENTSREWRITE_20000211_BASE 691c29469688bd15b333087f9a8086042eea06b6 MOZILLA_1_8_1a1_RELEASE f379a9a8f9d3e74980ff5df7cafe65e6e7498662 ROGC_20030211PR_FREEZE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_3_1_RC2 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d SUNBIRD_0_3_1_RC1 32fc3d2b031082c374a86c3202775ac45e28ba9b MOZILLA_1_5a_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_16_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_14_RELEASE 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 NSS_FIPS_20060524 787b56d6239861bffe5cb714063d8e7a8f8dd774 JSS_4_2_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_4_RELEASE 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e SeaMonkey_2001052912_BASE 7d2fb104141c99c172aad98e0215f782da485712 THUNDERBIRD_3_0a1_RELEASE dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_15_RELEASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a LDAPCSDK_20050510_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_13_RELEASE f379a9a8f9d3e74980ff5df7cafe65e6e7498662 MOZILLA_1_3b_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R7 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R6 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R5 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R4 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R3 d7a4b5edd8e12826ae5f996b4992bcbe08d7a884 NSS_3_6_1_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R1 358961e4d00c7411d5e9847717addb3b7a0b9e3f NSS_3_12_ALPHA1A 8030de1b73547ed91a4062b10bc2e0f3bdc592e2 JSS_3_4_1_RTM b210188ed7b4c5e49ae6bb1ccccf8b1bc1fc0969 nsstip_nt_20020228 8c8fa0bf2716618abab883b21238b5e75d3f96ba NSS_3_11_9_RTM c090553817020bebc7add9feda962a345f684bd1 NSS_3_11_4_BETA1 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R9 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_7_RELEASE cc014b41cf51e27104db1aaf9cd79675e2ce3b6e MOZILLA_1_8_1_RELEASE 054926bd102b364c1e741a00ac50fd569b863b49 SUN_SECURITY_3_9_3_RC2 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 DOM_AGNOSTIC3_PRE_MERGE c090553817020bebc7add9feda962a345f684bd1 SVRCORE_4_0_3_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_7_RC2 474365e481fc8ff4aa0669da721959f624f5ba60 MOZILLA_1_8a3_RELEASE f379a9a8f9d3e74980ff5df7cafe65e6e7498662 ROGC_20030115_FREEZE 4743208e8b17df941141129a2a52c29e0fd9f623 MOZILLA_1_8_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_12_RC2 dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_18_RELEASE 29e6e619c3980735fa0c3879d65cf37b83662c37 PHOENIX_0_2_RELEASE 2ac9b0ee034fd6efeebddccf409f40014977e2bf MOZILLA_1_9a7_RELEASE a4f86ba5a977bada7ea56288ea5e453070c79f87 CAMINO_1_0_1_RELEASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a COMMANDLINES_20050109_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_6_B1_RELEASE a4f86ba5a977bada7ea56288ea5e453070c79f87 FIREFOX_1_5_0_2_RELEASE 6323c742414abe3c6e0e6ce02619812cde5b275f THUNDERBIRD_0_9_RELEASE 42d206ebec789ce314913f244d5c30d62894b99d NSS_3_13_1_BETA1 7827ce6a450349ead987c490f31ccf9be566a32d NSS_3_12_3_WITH_CKBI_1_75_RTM 43fb21fdd37baa7651039fd6a7d7ac286cede513 FIREFOX_2_0a3_RELEASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df WEB_CONTENT_HANDLING_20070621_PREMERGE_20070719 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_5_RC2 b728d2aa81cd2f7473e7a0b13ec9b040e474289c NSS_OTIS_BETA_1 d9960f74c5a9046a95f0065fcec923b35342e34c NSS_OTIS_BETA_2 8c8fa0bf2716618abab883b21238b5e75d3f96ba CAMINO_1_6_3_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_5_RC1 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 NSS_3_11_20060609_TAG 79dbb7def28b57865024b453d0e243136327c9fa THREADS_20060307_BASE 9c045506ec36ea01b2564bfa84ab59bd937a899c MOZILLA_0_9_7_RELEASE 8256dda1535f71be791a3d619587f438129a776b THUNDERBIRD_1_0_5_RELEASE 7bd814d34b8dbc6f2d0cae04e04256e6c5b156f5 FIREFOX_0_8_RELEASE 0a3f4e7640735d620f5e9d6a65c0457525e41eaf NSS_TIP_20020503 7069a75b360766bf38f03b06f8c5d30a67ba84fb ROMAXA_20070529_GTK2_THEBES_BASE a138b79eaf0807c33b9e947f96cf6f319b7045dd NSS_PRE_PKIX_MERGE 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_19_BUILD2 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e REPLY_PERF_20010608_BASE 447639965dc87ad0c58b7ef358cef3a47f321b45 moz_win_20021203 47d3861f80303728a104477a608d70d8beb5555f moz_win_20021202 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_7_BETA2 b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_2002082307_TAG 597d9f501aa4a70676abda23b8d7e6baeb61639f MOZILLA_0_9_4_2_RELEASE 8196415a257308f20098ac6288cd60cb511d14c7 MOZILLA_0_8_1_2001031617_BASE 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_2_RTM 5338b9d52d72810a58abd6065e9bf3eeb4d6ff03 NSS_3_2_BETA3 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_0_6_RELEASE 5b6c53f2d6c78c9307728bd15ff21d66c55417db NSS_3_12_4_FIPS5 c090553817020bebc7add9feda962a345f684bd1 THUNDERBIRD_2_0b1_RC1 a5eaf0899fe90795ba65ea97465921e409ebbfc3 CAMINO_1_0_RELEASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a MOZILLA_1_8a6_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_12_RC4 bd38642ff528089ac09939c3fcd668053b947006 NSS_3_12_2_WITH_CKBI_1_73_RTM 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_8_RTM 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d NSS_3_11_3_BETA1 fab631d240c1f62f5f0c57606807d1a85b7965d8 MOZILLA_1_8rc2_RELEASE 8424f6bb99542451e06c7ac468ba711ae2351d04 NSS_3_12_7_BETA2 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 PHT_20030227PR_FREEZE 3a7b9572e1ee1e2c9c5d5cc612a11940d6967969 PHOENIX_0_4_RELEASE 07b346a9bb7d69b846a687eaca30eb759586f37c NSS_PHB_POST_FORTEZZA 59d4871fd5b4a28cf0af38c760f5d00f829b2603 FOLDER_PANE_20010807_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a3_RELEASE b00a8970848e13a4c67e59c7b61aabe19616bcf1 NSS_3_12_11_BETA2 788d2a263d365e317c152781c63d104e046d6866 NSS_3_11_5_BETA1 279746f8384085c604dcc5b67acaf7be298422d2 FIREFOX_0_9_2_RELEASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_3_RELEASE 4f564e658b0fa1df6b47d6315432adbe1e0fb13d NSS_3_11_20060403_TAG 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_8_RELEASE 079703aaefe1a57a00f6357702e4f6509e10b280 NSS_3_12_RC2 92e2642c8145b48ee5c3f060dc176ed6dc956677 NSS_3_12_RC3 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 NSS_3_7_1_RTM bbfbcc372d3b65a02ea958328e32f6e93428a016 XPCDOM_20010223_BASE b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_20020912_TAG dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_14_BUILD1 dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_17_BUILD1 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_5_RC1 279746f8384085c604dcc5b67acaf7be298422d2 FIREFOX_0_9_RELEASE db91c79180255524231b675bb24cec62c3d9edd9 NSS_3_12_3_2_RC0 4240508b6497c8f12937da214a6a22ef5fe339ee NSS_CLIENT_TAG_20041008 b84a182ad514cd82bb54f1dac71709330210f616 NSS_3_10_2_BETA2 8b8c1e2f90f9609e2a7a7a3f65dbdce16850e9eb NSS_3_2_BETA5 a800b83221d5e4f5871bd36c97685ed2a2261707 NSS_3_2_BETA4 a8becee2b8fe09d10ac31d952e017c8cf67d02f8 MOZILLA_0_9_9_20020301 8229508fef1ef0eac669f3b7048900dcf7f36b95 FIREFOX_3_0b5_RC1 338b03e47200cb9099f8d07587dbeab94f5062ed FIREFOX_3_0b5_RC2 ba95a4495e6a8f0dadcdcdea92363a09a9d6c011 JSS_4_0_BRANCHPOINT 01a90456b276c9eed41b38763823c5d9f95a31fa FIREFOX_3_0_4_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_17_BUILD1 ea3d15e255f5b388fe6d2baffbf884c4c1831a98 NSS_3_14_1_BETA3 c090553817020bebc7add9feda962a345f684bd1 FIREFOX_2_0_0_1_RELEASE 9fe276bab59d7de37147289da0d44cca59523a86 MOZILLA_1_1_BASE d9abb5a22a14aa7323aa9c0bc8e6906caf4dc5ea NSS_3_14_1_BETA1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_5_RC4 059b34b8ec1c7fb9677afea9b4a4a142f56bf78e NSS_3_4_1_RTM c81e447b98ba1870e61d43968668c28a88963e6d NSS_3_5_BETA1 97484fae41d7178c9b49c0061a54e08bea6ac1e2 NSS_3_5_BETA2 b00a8970848e13a4c67e59c7b61aabe19616bcf1 NSS_3_12_11_BETA3 a4f86ba5a977bada7ea56288ea5e453070c79f87 FIREFOX_1_5_0_3_RELEASE b00a8970848e13a4c67e59c7b61aabe19616bcf1 NSS_3_12_11_BETA1 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_5_RTM dd723df8492284680e8f08f6691c9addf356c259 CAMINO_1_6_11_RELEASE 1cb4c08d255bb89b26a21624404e30d5dd96cc67 NSS_3_11_20060331_TAG 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_19_RELEASE 31ec2dfc3fc4b71d0ddd02f69fd6bf9126f5b46c NSS_3_12_4_FIPS0 3eab354eb3e5891c57eabb1456120ec2a28eeeea NSS_3_12_0_BRANCHPOINT 4743208e8b17df941141129a2a52c29e0fd9f623 MOZILLA_1_8b3_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_0_RC1 1e6c0f58db4358aa75c5874376ac0e466170493d Accessible_042401_Base2 bcced5ecd355f440a4f94403bb40105eac7acb9c NSS_3_6_RTM dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_15_BUILD1 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R8 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d SUNBIRD_0_3rc1_RC1 369f0fdceee9efd93e2370fbc8bff1c64ac19951 THUNDERBIRD_0_3_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_9_RELEASE 6323c742414abe3c6e0e6ce02619812cde5b275f FIREFOX_1_0_1_RELEASE d1c9ca7c30373d09ba7d57dd1122e5dc179a02e5 NSS_3_12_4_FIPS1 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_1_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 NSS_CLIENT_TAG_20040323 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_8_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_5_RELEASE fe8a10ac1ec4a6acc6f4ef5cc6076ed61acf0fdf NSS_3_12_7_RTM 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 SEAMONKEY_1_0_6_RELEASE bf92503f7d275dff7ff19bfcf2c16668e6886b71 ROGC_20020830_FREEZE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a MOZILLA_1_8a5_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_11_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_7_BETA1 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_13_RELEASE fb7848f47bfe74548fad158e53d69e9e77f3cf19 CAMINO_2_0_B1_RELEASE 9d185bf8e80a494ca3b7e898cef19244eb87faae SYD_TEST_03052002_BASE 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e DOUGT_URI_PARSER_06122001_BASE c21a4071e11639c22bff2d31cdadda5c740e4338 NSS_3_4_20020114 98ceddf864d26fd047795331d9022d595383e272 FIREFOX_3_0_9_BUILD2 e620c5616cc9958413daa88a661be6bf3ff6640e FIREFOX_3_0_9_BUILD1 dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_5_RELEASE b67ddac6da6f7e2e25be95354361b57c1032be4d nsstip_20020225 97484fae41d7178c9b49c0061a54e08bea6ac1e2 MAIL_05302002_BASE 68858b478a72579ea4cfdfade9fc46cf00b18247 BSMEDBERG_SECURITY_PLAYGROUND_20050512_BASE 3480f05113e30e9b411d5e5d5e084ebabc3e4eb3 PSM20_M_1_5_TAG 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_7_RC4 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_7_RC6 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_10_RC1 63cbb20416c02105e4678fbbbd524b85c291789a FIREFOX_3_0rc3_RELEASE cc3fb143376b8e61b3d1de0bd217ea53fa27dbb1 FOLDER_OUTLINER_20010417_BASE 0aae6cf158a09e9cc97dbb1158198ca41dda7684 ROGC_20020430_FREEZE d4471b74a1fd8de5492089962803d3e67b57c970 NSS_3_12_6_WITH_CKBI_1_79_RTM 43ba84437ac8de1f249ce1d211e6fb16cf14ac80 NSS_3_13_2_RC0 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_11_RC1 3388306d8038576a614810634e71c10297890e06 NSS_3_4_4_BETA1 eca5c62b2770358093f108c07283496af66a3f65 BOB_3_12_ALPHA_TEST_1 88994717c152ef4c573f6582d53eb3aeffa1b359 SOFTWARE_UPDATE_20050428_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 MOZILLA_1_8_0_7_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R11_1 5597cb813098fa562c6fe05aaf165167f7b329c1 NSS_3_9_3_BETA3 84718cacc685fe689c9caa011b0f991c2b192c54 NSS_3_10_BETA3 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030321N5_WIN_FREEZE 6bcb0e09f6e4aa670536364935287b3495af7f65 NSS_3_10_BETA1 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_16_BUILD1 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_15_RELEASE b190c3bb376c9dc950c5d62d56cd0349a9861513 SSU_20030812_BASE cd197f30360fbaeb9c9412cb2ec41b3f48245a87 NSS_3_11_2_BETA1 14cfba7f33396d8499b407a8e2073e64c1b14e43 NSS_3_12_3_BETA4 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_20_BUILD1 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_6_RELEASE ed622de05e7b06196772d82434c08670720677d1 NSS_3_1_NT_RTM 9fe276bab59d7de37147289da0d44cca59523a86 UNINSTALL_WORK_BASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba NSS_3_11_10_WITH_CKBI_1_67_RTM 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_7_RC3 2acbe005a2e6ffa820c685f28d0b207bb64d2e81 MOZILLA_0_9_8_BASE 0c2aad25f496ead4d81cbd1ce1780443e59fc7a1 NSS_AUTOCONF_BASE 0683159fe173b0e8468e32973eec8346cef04732 FIREFOX_3_0rc1_BUILD1 ac87b948e10b3520103e348671e6108ffdb12ed2 NSS_3_13_RC0 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_13_RC1 fb9bfc356e233ae4e5c1cb16ce1715ac83bcae8a NSS_3_14_1_RC0 369f0fdceee9efd93e2370fbc8bff1c64ac19951 MOZILLA_1_5_1_RELEASE 49fcf2161e36169986479a2cb6a71ca06c44c0ac MOZILLA_0_8_1_20010326_RELEASE 30de0957a7d88841daceae3b7423ff500282fbc8 JSS_3_5_BETA1 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a4_RC2 673d325fcdbbe6b1eb393970ae8548da3a9aee2e JSS_4_3_1_BETA2 fab631d240c1f62f5f0c57606807d1a85b7965d8 MOZILLA_1_8_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_12_RELEASE ab65fa026c00716138bc36495bcf5d216af6af27 NSS_3_13_6_RTM 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030430N6_MAC_FREEZE 04cfdcce4b6d864adceea3e2c358882984fd73b4 NSS_3_12_8_BETA2 8ebc41d3cd0a07532a4923bdf241c7a88c9bf6ab NSS_3_2_RTM 0360fd0cfb6bd5087e8904b996efe36c51bbc1c2 JSS_TIP_20060224 dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_16_BUILD2 9789d4aa9367a124f482a4ebb98496dfaf0f6630 NSS_3_3_3_RC010903 279746f8384085c604dcc5b67acaf7be298422d2 THUNDERBIRD_0_7_2_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba CAMINO_1_6_5_RELEASE b2c26eb33789431f3a8a838c3352f4fa123187ac moz_win_20021026 92d38200df89c6abaa209592af349a54759d64de FIREFOX_3_0_12_BUILD1 7069a75b360766bf38f03b06f8c5d30a67ba84fb LIGHTNING_0_5_RC1 4d184c8989a53efc2643bb7be5d421ad8fc69fe3 JSS_4_3_RTM f3de32e624b36a13235c1df3950dc6e553511bf9 moz_win_20021122 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_2_RC4 dd723df8492284680e8f08f6691c9addf356c259 SEAMONKEY_1_1_18_RELEASE 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 DOM_AGNOSTIC3_BASE3 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 DOM_AGNOSTIC3_BASE2 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_5_4_RELEASE 9c045506ec36ea01b2564bfa84ab59bd937a899c DBM_1_6_RTM 4661fb3bf3a1f0f9d52cf5dd19ad56111e85fed8 ROGC_20021218_FREEZE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_3_RELEASE 279746f8384085c604dcc5b67acaf7be298422d2 THUNDERBIRD_0_8_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R13 8256dda1535f71be791a3d619587f438129a776b THUNDERBIRD_1_0_8_RC1 8256dda1535f71be791a3d619587f438129a776b THUNDERBIRD_1_0_8_RC2 8ba4b093528fa9b982fd98ad426116ac260c5360 NSS_3_4_2_RTM 11c2785b5c97402305aebcf53848a9129c2cc1be NSS_3_10_RTM 6ec67212b6f64d8bf5eaaa1940c9c1f2ebda4a4b NSS_3_13_4_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R14 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030722N9_MAC 9c045506ec36ea01b2564bfa84ab59bd937a899c MOZILLA_0_9_7_20011221 32d8140376f925949a48367fa0aa6088b8f3f5c4 FIREFOX_3_0b2_RC1 8734a494d46d951e4718ae2389663570cf90acdd NSS_3_7_BETA1 4743208e8b17df941141129a2a52c29e0fd9f623 MOZILLA_1_8b4_RELEASE c090553817020bebc7add9feda962a345f684bd1 MOZILLA_1_9a1_RC3 3ddbf2b0a2475cd9350c683cd7e3d96c3cafd328 PSM_1_3_RTM 4743208e8b17df941141129a2a52c29e0fd9f623 THUNDERBIRD_1_5b2_RELEASE d99f651ddbb0359c912444498323fe43a5dd5fa9 NSS_3_14_RC1 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e FASTLOAD_20010529_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_10_RC1 38fd461004424b2fc6bdedb2bb24536b2bbfdcf6 NSS_3_11_BRANCH_20060224 3d0d8cca663f741434cab42f311587cd8676af04 FIREFOX_3_0_11_RELEASE 6323c742414abe3c6e0e6ce02619812cde5b275f AVIARY_1_0_1_20050124_BASE b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_20021107_TAG dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_15_BUILD3 1d631b36a30253095b8a3055277fda3d23e82328 CHIMERA_0_4_RELEASE 84d3f9decd506c3461ca85070eb2dc3b18abecbe MailNews_Performance_20010208_BASE fab631d240c1f62f5f0c57606807d1a85b7965d8 CAMINO_1_0_BETA_1_RELEASE 0d07d48542dd4e1b8127eab176aab3a22163dcbb MOZILLA_1_3_1_RELEASE d9102467766b6324f76ffb579906c467eb07f6e9 PAVLOV_20020924_TAG dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_15_BUILD2 7069a75b360766bf38f03b06f8c5d30a67ba84fb LIGHTNING_0_3_1_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_15_BUILD1 8c8fa0bf2716618abab883b21238b5e75d3f96ba CAMINO_1_6_8_RELEASE dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_19_BUILD1 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 NSS_3_11_20060520_TAG fab631d240c1f62f5f0c57606807d1a85b7965d8 MOZILLA_1_8_0_BASE 3dbfce0e94b3e891149e9915173876e09779b0f1 NSS_3_12_3_2_RTM 03c47927924128713b3cd2c243d5237b00cdbcbc JSS_4_3_1_BETA bf976f62c706851d807f269a4ae271324a5ee5a2 ROGC_20020603_FREEZE 6ac7de92d106af912d0675179ba57dcdb5bcbb36 NSS_3_4_RTM 4743208e8b17df941141129a2a52c29e0fd9f623 FIREFOX_1_5b1_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb LIGHTNING_0_5_RELEASE 21396c58bb37bef010f424abe58b4fc4c6c8c933 ANGELON_MOZ12_BASE cee900570d942da894e26c3df81ae39e3dae90d9 FIREFOX_3_0_8_BUILD2 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_4_RELEASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df WEB_CONTENT_HANDLING_20070621_POSTMERGE_20070607 6fc78eefea4065b34a7d613510598a0ecb68a048 NSS_3_6_1_BETA3 f7bae5190d21ad6ea2ff3182a0292eaf642139d7 NSS_3_3_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_7_RC2 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_8_RELEASE 32fc3d2b031082c374a86c3202775ac45e28ba9b MOZILLA_1_4_2003052312_BASE 9fe276bab59d7de37147289da0d44cca59523a86 MAILIM_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_5_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_6_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_4_RC1 37b5d3664ba8f66e2db073542381e4e717af6e90 MOZILLA_1_0_RC1_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_18_BUILD1 fab631d240c1f62f5f0c57606807d1a85b7965d8 CAMINO_1_0_B2_RELEASE 236958fe155ce1c2eb8ff69bcdd1b0ce08458a17 JSS_4_2_5_RTM baf7a8b48ec080191241e76520b2d64828e5e4bb FIREFOX_3_0b3_RC2 cdf625e0a08d6172549f7c41a7fa1c08b271bbaa FIREFOX_3_0b3_RC3 17208c398305b4f401398eec43cd3bddf09ceafb FIREFOX_3_0b3_RC1 632a7d5f5979af88c35c83aab811167b48f28264 nss377_20030613 e10f13a02463e86ffcfc02619200dd61ac68cc73 FIREFOX_3_0_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_21_BUILD1 4743208e8b17df941141129a2a52c29e0fd9f623 DOM_AGNOSTIC_BASE 5f47025d8f10e324ffef5c6ce9ed881587ca83b0 NSS_3_13_RTM 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_7_RC1 32fc3d2b031082c374a86c3202775ac45e28ba9b ANGELON_MOZ_14_BASE 2dafef5e97750cbd124f0947d659c6ceacf573d2 ROGC_20020802_FREEZE fab631d240c1f62f5f0c57606807d1a85b7965d8 THUNDERBIRD_1_5_RELEASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_5_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SUNBIRD_0_5_RC1 f7362194625dc1dba1ea524ffa1b97a8bccbf183 NSS_3_3_4_8_RTM a5eaf0899fe90795ba65ea97465921e409ebbfc3 CAMINO_1_0rc1_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 FORMS_20040611_BASE 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030402N5_MAC_FREEZE b190c3bb376c9dc950c5d62d56cd0349a9861513 NSS_3_8_2_BETA1 566e2b1091e6355c323ce90fd74ba2a2dd56d788 NSS_3_12_BETA1 fda350d3001092523e119201eacc694f4566bdd2 JSS_4_1_BETA3 4651329e98c8d88012b7fda5a4ccae84ab4ea6dd NSS_3_12_BETA3 d0b0ae7f936529ca7dfd9171eb5ebc2274ee7dea NSS_CLIENT_TAG_20020305 29a68eeefd7f17021e0ba476ba5ea477ed7b8cd0 moz_ux_20021104 bc7d6346bb5d68dabad94ccee0c52a308a56dc92 NSS_3_14_2_RTM bac774abbf7ed64366d3436035b187277684fe67 FIREFOX_3_0_13_BUILD1 9efa376193ee3365a73882c2382638160f47055d NSS_CLIENT_TAG_20050315 d311aeff42df7ff97111757441a882df13c774f4 moz_ux_20021108 cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0rc1_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 NSS_3_9_1_BETA1 43fb21fdd37baa7651039fd6a7d7ac286cede513 FIREFOX_2_0b1_RC1 b659212bde350c23d0b7d82d883d033f61b1a9ae NSS_3_12_1_RC2 8159a367ccd983cec8aedd4c226285744eceb44a NSS_3_3_4_RTM 43fb21fdd37baa7651039fd6a7d7ac286cede513 FIREFOX_2_0b1_RC2 32fc3d2b031082c374a86c3202775ac45e28ba9b NSS_3_8_1_RTM daa235d20acad4eaf9ca1a01bce96a615deca53a NSS_CLIENT_TAG_20020515 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a4_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_4_RELEASE a4f86ba5a977bada7ea56288ea5e453070c79f87 FIREFOX_1_5_0_2_RC1 51424d5eb149a8df5315bf04e0009eb2b27d1df9 CAMINO_0_8_4_RELEASE 5cf47290b28a92014d862a1fba25f2aec6d728ee NSS_3_13_5_BETA1 b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_2_RELEASE 3dbfce0e94b3e891149e9915173876e09779b0f1 NSS_3_12_3_2_RC1 8c8fa0bf2716618abab883b21238b5e75d3f96ba CAMINO_1_6_2_RELEASE 04d19d340b00004f20d2bfc56fd0a4c12438c8a0 THUNDERBIRD_M3_BASE 05a9f3fb93bbc987b751b27b5e0515508038adec JSS_4_1_BETA4 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_8_BETA1 0f9b9e489ba6213b9faec3b7352d1039cf4fb5e1 NSS_3_4_2_20020528 b84a182ad514cd82bb54f1dac71709330210f616 NSS_3_10_2_BETA1 c9aba365b165f429955e9e894f9b31485dca4dbc CAMINO_2_0_B3_RELEASE 9dd15432807f2aa549c4310e6631376bae4051a1 NSS_3_14_RC0 691c29469688bd15b333087f9a8086042eea06b6 FIREFOX_2_0a1_RC1 6f74b9c115bba34ed3407d2261fea5edb7a15d17 moz_ux_20021203 c84b529267afd9aabd7610adec6840b8f6260de2 moz_ux_20021202 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_19_RELEASE 1016f27d7aa76a14883a6859e3dbf4b0b92fd7f3 NSS_CLIENT_TAG 224f31a896df86828f72d4d6868f141eeb329f38 NSS_3_12_ALPHA1 fab631d240c1f62f5f0c57606807d1a85b7965d8 SEAMONKEY_1_0b_RELEASE 3dbfce0e94b3e891149e9915173876e09779b0f1 NSS_3_12_3_2_WITH_CKBI_1_73_RC1 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030522N7_WIN_FREEZE 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_6_RTM 406cf91b7e7f8f287130eb90e5b0115e37ad15ce NSS_3_10_1_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_10_RELEASE 116eabe80c98f803bb6df803e124178f283a4052 NSS_3_9_BETA4 0959c2c3854119ff1545d9ab687cb12035e3aadd FIREFOX_3_0_6_BUILD1 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_8_RELEASE 5b1fa917edb41aeb7d1efa419ffde7449fbfa0b4 MOZILLA_0_7_2000122616_BASE dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_16_RELEASE c411bb97cd53e3136dcfbc901019c5866d07f71f FIREFOX_3_0_5_RELEASE cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_5_5_RELEASE 190159f9f8d90b7da7109f694ba6115aa451f4e0 SECURITY_3_9_2_BETA2 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_12_RC1 15e2f3cec78079a3ac9abd5cf1dcd003ed13abe3 NSS_3_11_RTM_SUN 4743208e8b17df941141129a2a52c29e0fd9f623 MOZILLA_1_8b5_RELEASE 37b5d3664ba8f66e2db073542381e4e717af6e90 NETSCAPE_7_0_PR1_RELEASE 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e MOZILLA_0_9_1_2001060715 426df769ba4c97feb509fb79d19957b440e12915 JSS_4_1_BETA2 b7f477645e89457d7cfd78d9b64bf1e5f132f772 JSS_4_1_BETA1 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_12_RELEASE 9789d4aa9367a124f482a4ebb98496dfaf0f6630 NSS_3_3_3_BETA121602 2f56a41b3cd9e2e0f8779920cb478a7144814346 SUN_SECURITY_3_3_12_RTM 0fef023f24f12051c363593ab15b32755998a73b JSS_3_X_BASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_16_RELEASE d6feb49b6f77dd97caa6e35cbd1e1e3f2ea63224 NSS_3_3_2_SUN_PKG-apps-server 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_7_RC5 597d9f501aa4a70676abda23b8d7e6baeb61639f MOZILLA_0_9_5_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_0_RELEASE 37b5d3664ba8f66e2db073542381e4e717af6e90 NETSCAPE_7_0_PR1_BASE eaa2c0ae5a4100aa909b66024050f69f4415e46f JSS_3_2_RTM dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_8_RELEASE a979390baf9077d17224a95610ac71d683bbc3fb MOZILLA_1_2_1_RELEASE cf362a9764680acde4e1f3e48954109eada0c381 RMCH_20021105_BASE 474365e481fc8ff4aa0669da721959f624f5ba60 FORMS_20040722_XTF_MERGE 4bc09782b2b398ad4c75afe844a386348a2ffdf6 NSS_3_13_2_BETA1 37b0a2132af4f2d438be100ae5141d4c63976c6d JSS_3_1_BASE 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_8_RTM 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_7_RC1 ccd9334922afb550d496a6628276835f9f34ad84 JSS_3_1_RC1 cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0rc3_RELEASE 32fc3d2b031082c374a86c3202775ac45e28ba9b FIREBIRD_0_6_RELEASE 2acbe005a2e6ffa820c685f28d0b207bb64d2e81 MOZILLA_0_9_8_RELEASE 2a059434a6f72f3690b2d2f5fb3f0699e9006fc5 NSS_3_11_1_BASE d0dd9cccc30bd2e40ff9e6e8cfb328c998461300 SECURITY_3_9_4_RC1 a4f86ba5a977bada7ea56288ea5e453070c79f87 THUNDERBIRD_1_5_0_2_RC1 597d9f501aa4a70676abda23b8d7e6baeb61639f NETSCAPE_6_2_2_RELEASE eb8f6f1e5ecf930c45ffc826882eaeaa1fc46921 NSS_3_4_4_RTM a0bd47a08991e8081151d22f2364cb798195e884 FIREFOX_3_0b2_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_7_RC2 b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa CHIMERA_M1_0_1_BASE 5e4351a2f8cf333b0fa9781656366e9b84f87e85 NSS_3_4_1_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_3_RC1 e9ee7d23d81d6bdb5996aa3344236166efa16ee9 NSS_3_4_1_RC3 50bc305cefdaa6637888292d546352d80e95a941 NSS_3_12_10_BETA1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_7_RC5 4e18c9dbe9e4c321d2d77e5875d9c5acc7a165ae PREFERENCES_20050201_BASE 29c58ffefae09880f62862ed476c78e71b54460d FIREFOX_1_5_0_1_RELEASE ac8553e5d9eeedbddc51b7c3bef178fbe7a45401 FIREFOX_3_0b1_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_13_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_9_RC1 dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_9_RELEASE 1110e9973082d197e9aae24f37b15113b3f2ad2e NSS_3_12_5_RTM d07b83687a84e9e990953708ebde9c56a02dfc0b NSS_3_13_5_RTM 43fb21fdd37baa7651039fd6a7d7ac286cede513 THUNDERBIRD_2_0a1_RELEASE 1e6c0f58db4358aa75c5874376ac0e466170493d Style_20010509_Base eb28248ebd471c46ba608965cc13b113cddeb811 NSS_CLIENT_TAG_20010815 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a5_RC2 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 MINOTAUR_20030218_BASE dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_RELEASE 3ddbf2b0a2475cd9350c683cd7e3d96c3cafd328 PSM_1_4_N6 27acae0b6d14ab6567fa4f2ad88e542422282245 moz_win_20021014 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_13_RELEASE 85027b198527b8f49114f73b155ade3475783b50 NSS_3_12_BETA2 ac3d5aac789274c941cb664d3ed9abb978bcfa13 NSS_3_12_6_BETA1 d9102467766b6324f76ffb579906c467eb07f6e9 PHOENIX_0_1_RELEASE 8159a367ccd983cec8aedd4c226285744eceb44a NSS_334_20030307 8256dda1535f71be791a3d619587f438129a776b THUNDERBIRD_1_0_6_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_4_RC3 a4f86ba5a977bada7ea56288ea5e453070c79f87 THUNDERBIRD_1_5_0_2_RC2 b2c22a3f3321c8564238f3ea0f62f78132742172 NSS_3_8_BASE 632a7d5f5979af88c35c83aab811167b48f28264 ANGELON_MOZ12_N6_BASE dd723df8492284680e8f08f6691c9addf356c259 THUNDERBIRD_2_0_0_23_RELEASE ccbcee88733d7304f61d1229da7c4a7b7b31aaf2 NSS_3_0_1_RTM b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa BEONEX_0_8_2_0_RELEASE 3d43ef53f922a54037618406b24f6a83c5d5a788 JSS_3_1_2_3_RTM 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_17_BUILD1 2bb4b383571161fbea3bf6b54256992d979a6d0f JSS_3_1_2_2_RC011503 597d9f501aa4a70676abda23b8d7e6baeb61639f PSM_2_2_DEV_20011002_BASE 9c045506ec36ea01b2564bfa84ab59bd937a899c CW7_20011204_TAG 51e995b5cc63a419bfb8920b12af72b948efe89d NSS_3_12_1_WITH_CKBI_1_72_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_12_RELEASE a4f86ba5a977bada7ea56288ea5e453070c79f87 THUNDERBIRD_1_5_0_2_RELEASE 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_3_RTM 52558347e7daca2448ebeb7b261c442b292a4cec NSS_3_12_ALPHA_2B f379a9a8f9d3e74980ff5df7cafe65e6e7498662 QT_LAST_RITES 32fc3d2b031082c374a86c3202775ac45e28ba9b CFM_LAST_RITES 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 SEAMONKEY_1_0_3_RELEASE 1c49fc8bc37fe95e4b54877428da6bd7db3c18e1 FIREFOX_3_0_4_BUILD1 37b5d3664ba8f66e2db073542381e4e717af6e90 MOZILLA_1_0_RC3_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_0_8_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_13_RC1 474365e481fc8ff4aa0669da721959f624f5ba60 MOZILLA_1_8a2_RELEASE f5c66687bc418ed61d2cf3ec7960d4b5eab2fddb JSS_3_6_RTM b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_20020927_TAG b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_20020805 737048adb0e92456eb6e2914b26f054446d59f94 MOZILLA_1_6a_RELEASE d1394efcb4f5c0714f06c827fc97bcaa138e4e5a JSS_PRE_NSS_3_12_API d6feb49b6f77dd97caa6e35cbd1e1e3f2ea63224 NSS_3_3_2_SUN_PKG-0918 2dbc83cb11fb3f11046092af9adf1fc5ec78e5d6 nss_20020222 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_7_RC3 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_7_RC2 8256dda1535f71be791a3d619587f438129a776b THUNDERBIRD_1_0_8_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_7_RC4 7d99989db574b2150f52e09d5947322802ca76fc nss_20020225 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_7_RC6 349358666682b056226b265ec22b663d1643ab94 FIREFOX_3_0_10_BUILD1 2eb6f5df0e065dd6596ac81b3521f9f238242117 FIREFOX_3_0_2_BUILD5 97e94618f3771f05d52d8ae0d9fe20c8529cf746 NSS_3_10_2_RTM_HPUX_IPF b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_20021120_TAG 279746f8384085c604dcc5b67acaf7be298422d2 CAMINO_0_8_RELEASE 632a7d5f5979af88c35c83aab811167b48f28264 NSS_CLIENT_TAG_20030319 ef4989cd2d2d56446fb85deb50e230c1d6de3eaa XPCDOM_20010329_BASE_PLUS_FLATTENING_BASE 40c4b8cc5e481d35d3591b26e8e9874e65a293fc LIGHTNING_0_1_RELEASE cc014b41cf51e27104db1aaf9cd79675e2ce3b6e LIGHTNING_0_3_RELEASE 68b4294b4e8b2e51ca2a5d66d2b296be8a3ab5da NSS_3_2_1_RTM_SOLARIS_X86 474365e481fc8ff4aa0669da721959f624f5ba60 FORMS_20040621_BASE f379a9a8f9d3e74980ff5df7cafe65e6e7498662 PROFILE_SHARING_1_TAG b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_20021114_TAG 4fdc33a4ef5475ed54f4b71d4ce81a4a9362c09a FIREFOX_3_0b4_RELEASE 1e6c0f58db4358aa75c5874376ac0e466170493d MOZILLA_0_9_2001042510_BASE 279746f8384085c604dcc5b67acaf7be298422d2 MOZILLA_1_7_RELEASE 279746f8384085c604dcc5b67acaf7be298422d2 MOZILLA_1_7_1_RELEASE 06b3b37ddc26f46147e7c286281e39033cc4e8d5 NSS_3_3_BASE 26a162d0e254457d2debe63d17095600b510591d FIREFOX_3_0_2_BUILD2 43fb21fdd37baa7651039fd6a7d7ac286cede513 SEAMONKEY_1_1a_RELEASE f804d0d03a7397a84255e74c9707b3dee71ac04f JSS_4_2_6_RTM 418ff8ae73433dd4f7b8c76a01ae84e202bc9a3f FIREFOX_3_0_12_RELEASE 6323c742414abe3c6e0e6ce02619812cde5b275f THUNDERBIRD_1_0_RC_RELEASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RC2 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RC3 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RC4 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_10_RELEASE 6323c742414abe3c6e0e6ce02619812cde5b275f FIREFOX_1_0_2_RELEASE 1e9e38ea60eb857193ecbd2716a4bddae7d8c21e NSS_3_10_BETA2 e4b85ba92b45eccb1cd002bdfa65561dc21d98df NSS_3_11_7_WITH_CKBI_1_64_RTM 924cd8d1cd268033c446f06e0e7058de602ef917 FIREFOX_1_1a1_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_6_1_RELEASE 0d07d48542dd4e1b8127eab176aab3a22163dcbb MINOTAUR_0_1_BASE cd339e7f88b7bca784f45dde5508cc4e6bd2f941 ROGC_20020930_FREEZE 369f0fdceee9efd93e2370fbc8bff1c64ac19951 MOZILLA_1_5_RC2 138e9e21a6b172c8367cf2f01063b312123e34d1 JSS_3_4_2_BETA1 d3feba1d8b430b83adaaed173367939e0f064cd7 NSS_TRUNK_20060424 2a059434a6f72f3690b2d2f5fb3f0699e9006fc5 NSS_3_11_1_RTM dc6f61b6727bf3590d7129ff8fb643190e1edbe0 NSS_3_14_2_BETA2 b0a64357a9f1b821c6cbdb3b10aa8b7d1fec7833 NSS_3_14_2_BETA3 37b5d3664ba8f66e2db073542381e4e717af6e90 MOZILLA_1_0_0_2002052821 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 MOZILLA_1_8_0_5_RC5 4743208e8b17df941141129a2a52c29e0fd9f623 SPLITWINDOW_20050714_BASE ed622de05e7b06196772d82434c08670720677d1 NSS_3_1_RTM 890fb2ac287f224f7b76d38dfec83afbd8441ef4 MOZILLA_1_8a4_RELEASE 33f2bfefed818a60f8c7082c7e816a4fb7942055 JSS_3_0_RTM 43fb21fdd37baa7651039fd6a7d7ac286cede513 FIREFOX_2_0b1_RC3 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 MINOTAUR_20030217_BASE dbdd33c031175e39da154b17ad857e2b152631c3 MOZILLA_1_2_2002110512_BASE a7fe654cbee1b2528d82593abb3caedf92843349 STATIC_BUILD_20010628_BASE 369f0fdceee9efd93e2370fbc8bff1c64ac19951 FIREBIRD_0_7_1_RELEASE 597d9f501aa4a70676abda23b8d7e6baeb61639f NETSCAPE_6_2_3_RELEASE 9fe276bab59d7de37147289da0d44cca59523a86 WINCE_20020710_BASE 3a0db653f667bbf7a6e4d3cf7f51f8b3217e653a moz_20020906 737048adb0e92456eb6e2914b26f054446d59f94 NSS_3_8_3_BETA2 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_9_RC1 db9c3b4fb02c937ed1d6e82bab737121379104b6 moz_20020902 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_16_BUILD1 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_0_4_RELEASE 691c29469688bd15b333087f9a8086042eea06b6 FIREFOX_2_0a1_RELEASE 0c979022232016b996614c211a70a1ca81486791 MOZILLA_0_8_2001020916_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_4_RC2 b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_1RC1_TAG 9f101cbdc766936fdb97484bb31ff69b9bf5e555 FIREFOX_3_0_8_BUILD1 5e4adc1160dac2fce3199304c10bbb479d7a41ee JSS_3_1_2_3_BETA 279746f8384085c604dcc5b67acaf7be298422d2 MOZILLA_1_7_RC2 474365e481fc8ff4aa0669da721959f624f5ba60 MOZILLA_1_7_RC1 c090553817020bebc7add9feda962a345f684bd1 THUNDERBIRD_2_0b1_RC2 e2d522f6c1d2ca62c98ec12ab9c46dc84f6cd874 NSS_3_4_2_BETA1 176c11c887d4a5e221d8147cf964bb3cbe1a4b8d NSS_3_4_2_BETA2 597d9f501aa4a70676abda23b8d7e6baeb61639f MOZILLA_0_9_4_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_2_RC2 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_2_RC3 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_19_BUILD1 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_2_RC1 cb5fe38fced50c3a34f1e6966a82233691ff7356 FIREFOX_3_0_2_BUILD1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_7_RELEASE b0b63baae3c6a39579a5023c62267546dac1fefd FIREFOX_3_0b3_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_8_RELEASE 33ec44ea70252453a4b418aa7f625a00de0647ac JSS_3_2_0_1 88463716c534eec58e06f9c08b7764315ee5bc85 JSS_3_1_2_3_BETA0211 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_4_RC3 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R12 279746f8384085c604dcc5b67acaf7be298422d2 CAMINO_0_8_BETA 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_5_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_5_RC2 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a3_RC1 50bc305cefdaa6637888292d546352d80e95a941 NSS_3_12_10_RTM 93fcf435d951103822c95d3626640668de9114ba NSS_LIBPKIX_START a702a3dfbab2f20c986e8e6e2507cefdcdac5dc4 NSS_3_14_1_RTM a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a LDAPCSDK_5_1_6_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_6_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_9_RELEASE 61a8140c6e01b3447af7111960335b16404e447b NSS_3_11_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_5_2_RELEASE 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d NSS_3_11_3_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_5_BETA2 6194d5fb8171a5dc52171045c46e5525f56a6f48 JSS_3_7_RTM_HPUX_IPF 258e897d94ecfbfd1de7315dead545e6698844c4 FIREFOX_3_0_2_BUILD4 a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a PREFERENCES_20050101_BASE c090553817020bebc7add9feda962a345f684bd1 MOZILLA_1_9a1_RC1 a19e489063b60e60ffffa6796be90c0dfe7ffa90 FIREFOX_3_0_2_BUILD3 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_4_RELEASE c090553817020bebc7add9feda962a345f684bd1 MOZILLA_1_9a1_RC2 f7362194625dc1dba1ea524ffa1b97a8bccbf183 NSS_3_3_4_6_RTM 279746f8384085c604dcc5b67acaf7be298422d2 THUNDERBIRD_0_7_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba CAMINO_1_6_7_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a5_RC1 0aef85cd31f7727bce5623b821416a7217b62051 NSS_3_11_TPATCH_20051221_V3_20060203 dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_17_RELEASE 30f863f411ea1c36548fc63f7908c5ab5b6dd72c XPC_IDISP_20020417_BRANCH 4743208e8b17df941141129a2a52c29e0fd9f623 THUNDERBIRD_1_1a2_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_4_RC1 cc014b41cf51e27104db1aaf9cd79675e2ce3b6e CAMINO_1_1_A1_RELEASE 279746f8384085c604dcc5b67acaf7be298422d2 FIREFOX_0_10_RELEASE b84a182ad514cd82bb54f1dac71709330210f616 NSS_3_10_2_RTM 52e35657298805506f03af26acdcd54f823c39c5 SUN_SECURITY_3_3_5_RC 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a2_RC1 a3258feccb4655f5c31acc6f784ba6bb5b8be180 THUNDERBIRD_M4_BASE 41bcd91ac419206e73a31c7fd8566a9fd0e783d1 NSS_3_4_RC2 420fed7ce07dd4bfbc9e6a439bdb58aa0d579a16 NSS_3_12_6_RTM b08f960ef6987252caa9ece05b738a77d10367e8 SECURITY_3_10_RTM 0b9248fe55f49188b88364a19f291d9eaef15056 NSS_3_4_RC1 3418ab75e1ee3f5bc23fe8aa03eff7fec8e3726e NSS_3_12_RTM 8945b2df6d54298c6761be749c5b54eb412455ef NSS_3_11_8_RTM b35763dc0d370232b40eb7632d53c3d4a08178fd FIREFOX_3_0_11_BUILD2 c8a76e969382c2d40f037ae3f3d3d15b4867dec8 NSS_3_14_2_BETA1 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_3_BETA1 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_21_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_6_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_5_RC1 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_6_RELEASE 03ed4fcb7e791b7575cd61595a4f76f7da57e9e5 FIREFOX_3_0b1_RC2 a51984035f7f1e5dbf81d828dd2c7d6f63cc9946 NSS_3_12_6_RC1 8ee34dd43079d6062bcf7fdd30b8bf5b09f48122 JSS_3_2_BETA3 ceb5bad518b9e3cabb7c8e905d53f2a7a820897f JSS_3_2_BETA2 12eb8c0834e374b1ca9142953def2f3e8c83a7ad JSS_3_2_BETA1 dd723df8492284680e8f08f6691c9addf356c259 THUNDERBIRD_2_0_0_23_BUILD1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 MOZILLA_1_8_0_4_RELEASE 7111215536aec8e5955bdff853d3f09b490a642f JSS_TIP_20060404 a1377f883a930eff6a6acda84d145479692fa599 NSS_3_10_BASE 6323c742414abe3c6e0e6ce02619812cde5b275f FIREFOX_1_0_1_AUP_RELEASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df NSS_3_11_7_RTM 597d9f501aa4a70676abda23b8d7e6baeb61639f OTIS_TEST_BASE 4260c7f2fbb315445bcf57dae2a341fa98d47796 NSS_3_4_3_BETA2 737048adb0e92456eb6e2914b26f054446d59f94 NSS_3_8_3_BETA1 d1394efcb4f5c0714f06c827fc97bcaa138e4e5a JSS_4_2_BRANCHPOINT 737048adb0e92456eb6e2914b26f054446d59f94 THUNDERBIRD_M2_BASE 545f4fd93b0af9e0d68575f52fd2aa0e183e539d CHIMERA_0_5_RELEASE a791fa7bd190925d04d38a994c9f572048855781 NSS_3_12_2_RC1 24be4544231a17fce166a992f5f208dbcf41a8dc NSS_3_13_1_RTM 81edf37bc9894aa336d361f036f01065a520a3a9 JSS_3_2_BETA3_NS 7a8b4cc3e6003f729d85a30e5d80ba8548880b25 NSS_3_11_2_RTM dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_7_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_17_BUILD2 8ef22796fc24745bc1bc5faae18bb08fca528330 JSS_3_2_RC 2bbea26f99241bca49575ac321746302d8d3aeb1 nss34_20020321 1fb07d3bb04a955242cb1a421ba29a51ad5eb87d JSS_3_1_2_1_BETA 5b1fa917edb41aeb7d1efa419ffde7449fbfa0b4 MOZILLA_0_7_20010109_RELEASE 0b1816bb906cf30d0210215932fb0f3076eced00 NSS_3_4_5_RTM f379a9a8f9d3e74980ff5df7cafe65e6e7498662 ROGC_20030129_FREEZE b00a8970848e13a4c67e59c7b61aabe19616bcf1 NSS_3_12_11_RTM 93368d9b1d3d813590a338ee994772499a5af566 NSS_TIP_20020305 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_9_RC1 369f0fdceee9efd93e2370fbc8bff1c64ac19951 THUNDERBIRD_0_3_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_14_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_12_RC1 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 NSS_3_7_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_0_9_RELEASE 369f0fdceee9efd93e2370fbc8bff1c64ac19951 MOZILLA_1_5_20030910_BASE 0cbbbae377f7cb79c082b7733d11a80a1b8b4f7d NSS_3_4_20020403_2 32fc3d2b031082c374a86c3202775ac45e28ba9b MOZILLA_1_5a_BASE b84a182ad514cd82bb54f1dac71709330210f616 DOM_AGNOSTIC2_BASE f77226d1e0a583335d60010b8402c73f0c24e0dd NSS_3_4_SunBeta0401 474365e481fc8ff4aa0669da721959f624f5ba60 MOZILLA_1_8a_RELEASE 3b5d5321a86e2db9cba81a589a18861a849bf7bf NSS_3_12_BRANCHPOINT 3df2eab7b5b8149c729f7a4e1e54fcb38be7d51a JSS_3_1_2_2_RTM 4743208e8b17df941141129a2a52c29e0fd9f623 SEAMONKEY_1_0a_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 SEAMONKEY_1_0_2_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_2_RC5 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_15_BUILD2 ec350903cd2c4e9bf2041db13a8f0d95a7f98113 FIREFOX_3_0_5_BUILD1 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_13_RC4 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_4_RTM dd723df8492284680e8f08f6691c9addf356c259 CAMINO_1_6_10_RELEASE a7fe654cbee1b2528d82593abb3caedf92843349 MOZILLA_0_9_2_1_SRC_RELEASE cd197f30360fbaeb9c9412cb2ec41b3f48245a87 NSS_3_11_20060515_TAG 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_13_RC3 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_13_RC2 a462f09c5cb32c63b0a85ff4fb2871df497719d4 JSS_FIPS_20060524 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030605N7_MAC b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_2002082208_TAG 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_6_RC1 5a2064d779f605c5d49c8309c39e5bffec146907 FASTLOAD_20010703_BASE 700f4475fe8eceb58202ce6367bc162af568164c DDRINAN_TEST_NSS_TAG 737048adb0e92456eb6e2914b26f054446d59f94 NSS_3_8_2_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_7_RELEASE 450cd43aab6dc5870629da499d699f67693328e7 LayeredDOM_20020307_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_11_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_5_3_RELEASE c090553817020bebc7add9feda962a345f684bd1 FIREFOX_2_0_0_1_RC1 c090553817020bebc7add9feda962a345f684bd1 FIREFOX_2_0_0_1_RC2 cdc52f796c163ffd8d5a711ecb172c8da9ca8309 JSS_DSAME_OCSP_RTM 5476620f22194a49c549b9ec23085b6586b14779 JSS_3_4_1_BETA1 f20e861175735a0fb046460c0a6edffb0e3ad5ee NSS_3_13_2_RC1 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e MOZILLA_0_9_1_RELEASE cd197f30360fbaeb9c9412cb2ec41b3f48245a87 NSS_3_11_20060512_TAG ad10e8d6cd423f82becfa9e592753e9c95d99aa2 JSS_3_3_RC1 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_17_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_6_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_6_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_10_RELEASE 6b36f0bd9e98fc238399e135ae424a430e9a319a MOZILLA_200303241605_TAG c64d652f8fafaa80a162fc8dff27454974c453da ROGC_20020430_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 MOZILLA_1_8_0_5_RELEASE f379a9a8f9d3e74980ff5df7cafe65e6e7498662 PHOTON_MOZ_PR1_BASE b190c3bb376c9dc950c5d62d56cd0349a9861513 THUNDERBIRD_0_2_BASE 37b5d3664ba8f66e2db073542381e4e717af6e90 MOZILLA_1_0_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 THUNDERBIRD_0_6_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_4_RC2 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e STATIC_BUILD_20010523_BASE 632a7d5f5979af88c35c83aab811167b48f28264 BOOKMARKS_20030310_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_4_RC1 211cd199dd6bd1eb812383b43766ae21dbe9b3df NSS_3_11_RTM bac774abbf7ed64366d3436035b187277684fe67 FIREFOX_3_0_13_RELEASE b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa NETSCAPE_7_0_RTM 4665ed3797f9405f36c9474f07243acfdb6460b3 NSS_TIP_20020426 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_12_RELEASE 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e MOZILLA_0_9_1_2001053110_BASE f7362194625dc1dba1ea524ffa1b97a8bccbf183 NSS_3_3_4_5_RTM b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa NETSCAPE_7_02_RELEASE 10843802aea81ed748d7ed71db4995d96a514ece moz_ux_20021009 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_9_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_10_RELEASE 8f32a794dcaff756e5f4f5e4529f6b2cf97a410d NSS_CLIENT_TAG_20040303 8f32a794dcaff756e5f4f5e4529f6b2cf97a410d NSS_CLIENT_TAG_20040304 c090553817020bebc7add9feda962a345f684bd1 SVRCORE_20070312_404_RTM 4d925615c01db355640ed6877b2e18c3d8f7d7aa NSS_3_12_4_FIPS2 37b5d3664ba8f66e2db073542381e4e717af6e90 MOZILLA_1_0_RC2_RELEASE 9c045506ec36ea01b2564bfa84ab59bd937a899c MOZILLA_0_9_7_BASE b7a5ec76418aa0677c4053c7918d287a7ff7837d NSS_HEAD_BEFORE_RFC4507BIS 34f654d87496c3aa11b97d2b5fb488848103c900 NSS_3_3_BETA2 11d99358876d1504f60542b4d44d343fc70ebc07 NSS_3_3_BETA3 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_20_RELEASE 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_9_RC0 474365e481fc8ff4aa0669da721959f624f5ba60 NSS_3_9_1_RTM 279746f8384085c604dcc5b67acaf7be298422d2 FIREFOX_0_10_1_RELEASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df WEB_CONTENT_HANDLING_20070621_POST_HANDLER_SERVICE_20070720 4743208e8b17df941141129a2a52c29e0fd9f623 MOZILLA_1_8_SVG_BASE f38b164dfdafd725817ced1344df26b4bb874d5b NSS_3_12_4_FIPS4 dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_3_RELEASE c182c7bbb2ee0174026c483b2547f6d7c34ae137 MOZILLA_1_7_5_RELEASE ed622de05e7b06196772d82434c08670720677d1 NSS_3_1_BASE 43aed4a4608d9f70ceb9ec1ec9460cb3b0972afb CAMINO_2_0_B2_RELEASE 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e Netscape61_PR1_RELEASE dd723df8492284680e8f08f6691c9addf356c259 SEAMONKEY_1_1_19_RELEASE 6323c742414abe3c6e0e6ce02619812cde5b275f THUNDERBIRD_1_0_2_RELEASE 279746f8384085c604dcc5b67acaf7be298422d2 MOZILLA_1_7_3_RELEASE 3e7543dcd80e7b3f128a265920c7c2b8a6ab9fc0 NSS_OTIS_RELEASE_1 6323c742414abe3c6e0e6ce02619812cde5b275f FIREFOX_1_0_RELEASE 7160133ff580af6421496975bc3f03adc96e0f6c SUNBIRD_0_5_RC3 c090553817020bebc7add9feda962a345f684bd1 SEAMONKEY_1_1_RELEASE dd723df8492284680e8f08f6691c9addf356c259 CAMINO_1_6_9_RELEASE 632a7d5f5979af88c35c83aab811167b48f28264 pmoz_20030415 a947fa225a8199543d6d62aad9f37fd71c346ff0 JSS_3_5_1_RTM 84d3f9decd506c3461ca85070eb2dc3b18abecbe DOUGT_CHANNEL_CHANGES_01222001_BASE 692a4ffbd0dd86c7dfa994fab631e0996c9ed8b2 NSS_3_2_BETA2_20010119 b1d671c9ebc5eb692976a47c4b6adb9bfc8db3f6 JSS_3_4_RTM 6323c742414abe3c6e0e6ce02619812cde5b275f FIREFOX_1_0_RC2_RELEASE 2acbe005a2e6ffa820c685f28d0b207bb64d2e81 NSS_CLIENT_TAG_20020204 5324f86e89b1e6a4df94017a36f5b2137a83bf90 NSS_3_2_2_RTM 425419421cabc1b0d5e2621a49f79a26377bacf0 THUNDERBIRD_3_0a2_RELEASE 93db6ac782a7674f778e13e6fd76e476e976d6dd AB_OUTLINER_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_6_B4_RELEASE 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_5_RTM 4540824dd47da359bd0f58b705c9473c5a57fc6b MOZILLA_1_4a_RELEASE 279746f8384085c604dcc5b67acaf7be298422d2 MOZILLA_1_7_2_RELEASE 0fef023f24f12051c363593ab15b32755998a73b JSS_3_5_RTM cc72e8f9e825698e6ce12296b463a3a89280cc0e NSS_3_12_6_RC0 b23eca2c5b38cae96ffb3d1712bb0936f690865b NSS32RtmAll 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_7_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_5_WITH_CKBI_1_64_RTM 24140235f55358c8674f5ccc6c3b08ebe45dc802 CAMINO_2_0_A1_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 SEAMONKEY_1_0_4_RELEASE fab631d240c1f62f5f0c57606807d1a85b7965d8 THUNDERBIRD_1_5rc1_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_12_RC1 dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_4_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_10_RC1 07d4912e2489f0578a55fe07af716722a6a72a44 NSS_3_12_3_BETA1 0541ed2ad53ea86554f0eed132da9d086a9083b3 STRING_20040119_BASE 43fb21fdd37baa7651039fd6a7d7ac286cede513 FIREFOX_2_0b2_RELEASE 97484fae41d7178c9b49c0061a54e08bea6ac1e2 MOZILLA_1_1a_RELEASE 9fe276bab59d7de37147289da0d44cca59523a86 MOZILLA_1_1_RELEASE f49978e198be19c6ffd1e135f9632d22d7ee00ce NSS_3_12_3_BETA3 29c58ffefae09880f62862ed476c78e71b54460d XULRUNNER_1_8_0_1_RELEASE 32fc3d2b031082c374a86c3202775ac45e28ba9b MOZILLA_1_4b_RELEASE 7bd3f0b52fdb88d3f8b0e5e8039709328590e658 SVRCORE_4_0_1_RTM 6323c742414abe3c6e0e6ce02619812cde5b275f THUNDERBIRD_1_0_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 FORMS_20040722_BASE 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_9_BETA1 98b0bec99adf8c14492682dd22bb2ef82094de51 NSS_3_6_BRANCH_20021026 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_5_RELEASE 6eeb9971de5f52b4d7c287c5f29af1b243de7c83 moz_win_20021009 97484fae41d7178c9b49c0061a54e08bea6ac1e2 NSS_3_5_RTM 805beda221c7c22ccb510f4b9ec12c1c5435b234 NSS_3_12_4_FIPS1_WITH_CKBI_1_75 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_9_BETA1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 CAMINO_1_0_2_RELEASE 279746f8384085c604dcc5b67acaf7be298422d2 AVIARY_1_0_20040515_BASE b41d0e16cabd39396255cb9be0f992687a65e360 ALERT_SERVICE_BASE 9eadf23f4373a97f0865d2c2213cd8b40e2eaa8f NSS_3_14_RTM d94d951adb8e9f773cb7b24d46d8a41bba148c33 DBM_1_61_RTM ea308aed26c3351cb0153510ffb3f98d4a65b49f SUN_SECURITY_3_3_6_BETA 9e9814779c68c9e32bd0d5f395b4cf3bb46714dc MOZILLA_1_6_20031218_BASE 6c499d50485a9eda0590d2affb8c0bd4a9f658db FIREFOX_3_0_10_RELEASE 8256dda1535f71be791a3d619587f438129a776b THUNDERBIRD_1_0_7_RELEASE 3989c41a499bcccf7330fe9b4bb3948b463c7236 FIREFOX_3_0_9_RELEASE 4e75a33716520ff0c5014b670ad72f904ba02dc4 NSS_3_12_3_BETA2 632a7d5f5979af88c35c83aab811167b48f28264 ANGELON_MOZ12_N5_BASE 6e5d2811a1fd06b384305de025b9bcc83c8800ce MOZILLA_1_4_3_RELEASE 32fc3d2b031082c374a86c3202775ac45e28ba9b MOZILLA_1_4_1_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 XULRUNNER_1_8_0_5_RELEASE 074f9419b6fe5e4c6a929f1f7b36e5e35f62b3f9 NSS_3_13_BETA1 8c8fa0bf2716618abab883b21238b5e75d3f96ba CAMINO_1_6_6_RELEASE 6fb51a1bc3819c53121b16ead8f513d1616fdddf NSS_3_4_PRE_BETA 279746f8384085c604dcc5b67acaf7be298422d2 AVIARY_20040809_MERGEPOINT 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030619N8x_WIN_MAC df46d7a41b911d0ecb17b601d170b7c0adc6c629 NSS_3_13_BETA2 dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_19_RELEASE 0ca28daaec24543437e3d6cd0b54d8ef29bfda98 NSS_CLIENT_TAG_20040128 b56c7b93d3038af3e3a0a4ec55cbbea453492b81 DBM16_RTM_20011206 b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_20020920_TAG 7d850f372fb58e06c5c5f52318e470825977f898 NSS_3_13_2_BETA3 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_11_RC1 e7312e6ec1b0ee2196aa768f534f87794595a894 FastLoadXUL_20020410_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_6_A1_RELEASE d6aa913cee352d699ecd923f4b79e651501ab4df REFLOW_20020412_BASE 54abc4d34bb0e28388f4b9b7ccecedd47f741748 NSS_CLIENT_TAG_20040123 3acaa20d534cdd0d6cb8f1aafd428a40982207ad NSS_CLIENT_TAG_20040124 39d79d08821830a2cf4b1a6b4aa13d7545a06702 NSS_3_13_4_BETA2 a69eea5f8cb9690a5d277919904b03debe2b78b3 NSS_3_13_4_BETA1 5b8594a3873dff04cdf42e2889e6fab5875eb741 NSS_3_4_20020329_2 c090553817020bebc7add9feda962a345f684bd1 CAMINO_1_1_A2_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_6_B3_RELEASE 94950d706ac98b47ec7c96b2138142c97599565c THUNDERBIRD_0_4_BASE a7fe654cbee1b2528d82593abb3caedf92843349 MOZILLA_0_9_2_BASE c090553817020bebc7add9feda962a345f684bd1 NSS_3_11_4_RTM 6d06b68af3216bcf5cd0d04141a7f52bf40e91d4 NSS_3_14_3_BETA1 9714b7b809961e6daa5ebaa546f4a485072d1c4c JSS_4_2_3_RTM 369f0fdceee9efd93e2370fbc8bff1c64ac19951 MOZILLA_1_5_RC1 8c8fa0bf2716618abab883b21238b5e75d3f96ba SUNBIRD_0_9_RC2 1e6c0f58db4358aa75c5874376ac0e466170493d XPCDOM_20010420_BASE 372120233af508d1c83f9f4d8006ea6eb57867df JSS_4_3_2_RTM fbbb2e19dccaf65f6e375f724d71006afdf501f0 NSS_3_13_2_BETA2 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_9_WITH_CKBI_1_82_RTM 2acbe005a2e6ffa820c685f28d0b207bb64d2e81 IFRAME_20020207_BASE 597d9f501aa4a70676abda23b8d7e6baeb61639f FORMREWRITE_20011008_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb NSS_3_11_6_RTM 48fb041f246789bf6933900cf98ecf7a6311505f FIREFOX_3_0_2_BUILD6 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_7_RELEASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_7_RELEASE 597d9f501aa4a70676abda23b8d7e6baeb61639f MOZILLA_0_9_4_BASE 2a059434a6f72f3690b2d2f5fb3f0699e9006fc5 NSS_3_11_1_RTM_STUDIO11 7069a75b360766bf38f03b06f8c5d30a67ba84fb SONGBIRD_20070117_01_TAG f7362194625dc1dba1ea524ffa1b97a8bccbf183 NSS_3_3_4_7_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R11 d17b5aa44b5c5b74942f302ea244ee8daf66740c NSS_3_13_3_RC0 632a7d5f5979af88c35c83aab811167b48f28264 ANGELON_MOZ_14_20030709_TAG d988cd572f0030750cccf93f8e709a19dff98212 MOZILLA_1_2b_RELEASE eed59567829b21d757bff4c7e9c80a226a448426 REFLOW_20020502_BASE 313fbffc5f5e4c402dbcee8e62a6070279bd8abf JSS_3_1_1_RTM 6323c742414abe3c6e0e6ce02619812cde5b275f FIREFOX_1_0_RC1 e4b85ba92b45eccb1cd002bdfa65561dc21d98df WEB_CONTENT_HANDLING_20070621_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a4_RC1 c090553817020bebc7add9feda962a345f684bd1 THUNDERBIRD_2_0b1_RELEASE 545f4fd93b0af9e0d68575f52fd2aa0e183e539d CAMINO_0_7_RELEASE 6caa9e47910e79c8a22cdbfee85ac014716319f6 FIREFOX_3_0_11_BUILD1 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_8_RC0 632a7d5f5979af88c35c83aab811167b48f28264 ANGELON_MOZ12_N8_BASE c2f420b104fde72684d07aba1b26f6df35e0e492 SUNBIRD_0_3a2_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_14_RC1 95719a6f91693ce9399fd28faf134bfbddfdf24b FIREFOX_3_0rc2_BUILD1 0f560c8eef8dc9cdbd82922191b8be688b5d5ec6 NSS_RFC4507BIS_BASE 32fc3d2b031082c374a86c3202775ac45e28ba9b ANGELON_MOZ_14_BR_BASE 0833841c5d927ebff9e1dc7dbf6e82458a6da25b FIREFOX_3_0rc2_BUILD2 63c3417867946a6f989f2105c725be786d4811b9 NSS_3_12_7_BETA 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a2_RELEASE 7036dc1d9c2e80fcf5fd1cd612a704b1cc5ba3ad DBM_1_61_RC1 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d NSS_3_11_20060926_TAG dd723df8492284680e8f08f6691c9addf356c259 NSS_3_12_3_1_RTM f7362194625dc1dba1ea524ffa1b97a8bccbf183 NSS_3_3_4_4_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_10_RC2 59d4871fd5b4a28cf0af38c760f5d00f829b2603 FOLDER_OUTLINER_20010531_BASE 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_9_BETA2 1f810299d2021a885a1bf654175c95b6f21d260b MOZILLA_1_9a7_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R2 0871f91c2d8f2bdec69a3a6fd8894943a4da9f4b JSS_3_3_RTM dd723df8492284680e8f08f6691c9addf356c259 THUNDERBIRD_2_0_0_24_BUILD1 dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_6_RELEASE 32fc3d2b031082c374a86c3202775ac45e28ba9b MOZILLA_1_4_RELEASE 2b4420491f5c62b1b58e0e728f8ef2dd999d1322 NSS_C ec5b5dbd3a43c2768daa0b0a034a7bcc00e2048d NSS_3_12_1_RTM bd65904c8f8e003bcd595c3cfa45a32d45145f12 THUNDERBIRD_3_0a2_BUILD1 927501c14c959444f93b92e9c47c6f906078cfb1 moz_20020919 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_11_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_8_RC1 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_2_BETA2 cd197f30360fbaeb9c9412cb2ec41b3f48245a87 NSS_3_11_2_BETA_20060428_TAG 19e741ab3f40a6e068e70d5359fa8c558ca8f814 DOM_AGNOSTIC3_BASE d68ef2666223417419f346c4f6d2bdf0f2e2067d SUN_COMPONENT_PACK_V_1_1 dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_14_BUILD2 c090553817020bebc7add9feda962a345f684bd1 SVRCORE_4_0_4_RTM a4f86ba5a977bada7ea56288ea5e453070c79f87 MOZILLA_1_8_0_3_RELEASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_8_RELEASE 9c045506ec36ea01b2564bfa84ab59bd937a899c WTC_20011211_TAG b50af1d68ad3eaad98e8cc75c826e6f64a27e87c NSS_3_6_BASE 597d9f501aa4a70676abda23b8d7e6baeb61639f NSS_3_3_1_BETA1 597d9f501aa4a70676abda23b8d7e6baeb61639f NSS_3_3_1_BETA2 597d9f501aa4a70676abda23b8d7e6baeb61639f NSS_3_3_1_BETA3 59b6c03ac0717e31e4abb2b06b80d14eee82b8c1 NSS_3_4_BETA1 3dbfce0e94b3e891149e9915173876e09779b0f1 NSS_3_12_3_2_WITH_CKBI_1_73_RTM fe4de946d07b8eea67cd1257607152b9bf4b52ce NSS_3_4_BETA2 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_22_BUILD1 29c58ffefae09880f62862ed476c78e71b54460d FIREFOX_1_5_0_1rc1_RELEASE be59725a29fbcd3cc338e9529294ed5b757b3c5b NSS_3_2_1_RTM 587988aeaa947448e0efee4b003b4601dfca8316 NSS_TIP_20020510 545f4fd93b0af9e0d68575f52fd2aa0e183e539d CHIMERA_0_6_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_18_BUILD1 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_5_1_RELEASE 532de21d1891c479f17fd2ce1a0e9053eae585e5 NSS_3_12_5_BETA 93db6ac782a7674f778e13e6fd76e476e976d6dd NSS_CLIENT_TAG_20011201 5531c7e9c930edce6ac17f0fd1be428606f53314 nss_3_12_5_BETA2 29c58ffefae09880f62862ed476c78e71b54460d MOZILLA_1_8_0_1_RELEASE 0ccec2d7da2030428961effe97ad3dc5e3e03f7d JSS_3_1_2_2_BETA1217 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_7_RELEASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a NSS_3_9_4_RTM 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_9_RELEASE bbe38ee3a26f5c6da18ea4aa25bbc82eb519bc2a JSS_4_1_RTM 3c61984c489daa6b2233a94f4a2b145748847979 NSS_MULTIACCESS_DB_TAG 597d9f501aa4a70676abda23b8d7e6baeb61639f PSM_2_2_DEV_20010918_BASE 389321fc597ddd31f1720fcbc7658289b617346c NSS_CLIENT_TAG_20060112 9789d4aa9367a124f482a4ebb98496dfaf0f6630 NSS_3_3_3_RTM 279746f8384085c604dcc5b67acaf7be298422d2 THUNDERBIRD_0_7_1_RELEASE 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_12_RELEASE 8fe5a36fb8eb7bcb7132153c2181b24305e39a38 FIREFOX_3_0_1_RELEASE 1d4e9ef3636d9f817dd0e508b335b5371aa7a7fd MOZILLA_1_3a_RELEASE eb28248ebd471c46ba608965cc13b113cddeb811 MOZILLA_0_9_3_2001_07_31_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_0_5_RELEASE 597d9f501aa4a70676abda23b8d7e6baeb61639f NSS_3_3_1_RTM 1e6c0f58db4358aa75c5874376ac0e466170493d MOZILLA_0_9_RELEASE 32b6cf63d6ab6d976938cb8e40e5f51d70128a27 FIREFOX_3_0_8_RELEASE 82c9c9925361804d3c7590e741b585c4fbf595d8 MOZILLA_1_2_RELEASE fab631d240c1f62f5f0c57606807d1a85b7965d8 FIREFOX_1_5rc1_RELEASE 2a059434a6f72f3690b2d2f5fb3f0699e9006fc5 NSS_3_11_20060424 5c64c776f49d5db07c0d6025dc9c54f65319d5ae NSS_WINCE_ALPHA_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 XULRUNNER_1_8_0_5_RC5 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 XULRUNNER_1_8_0_5_RC2 1b72daaba67bed6166b64cc40bb65f4cc8d25dd0 NSS_3_12_3_RC0 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_1_B_RELEASE a13d179963ec09a5468e12f64adb0cd8efba8775 NSS_3_12_2_WITH_CKBI_1_75_RTM d9102467766b6324f76ffb579906c467eb07f6e9 NSS_CLIENT_TAG_20020925 691c29469688bd15b333087f9a8086042eea06b6 REDFIVE_MEMBUF_20060320_BASE 9c045506ec36ea01b2564bfa84ab59bd937a899c NSS_3_3_2_BETA1 279746f8384085c604dcc5b67acaf7be298422d2 MOZILLA_1_7_2_BASE b190c3bb376c9dc950c5d62d56cd0349a9861513 MINIMO_6_AUG_2003_TAG 7069a75b360766bf38f03b06f8c5d30a67ba84fb UPDATE_PACKAGING_R10 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e STATIC_BUILD_20010612_BASE 632a7d5f5979af88c35c83aab811167b48f28264 phtmoz_20030411 396fdceb8cd36d6cbfa7fd8d23d1f52926fbcd48 NSS_3_5_BASE ead43caece3bd796bddc6ffc4401204f29d9edb9 JSS_4_1_BASE dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_16_BUILD1 70a2461bbd06b9fa77895426ecaa8e8c2b94af04 moz_win_20021108 dd723df8492284680e8f08f6691c9addf356c259 FIREFOX_3_0_16_BUILD3 b190c3bb376c9dc950c5d62d56cd0349a9861513 MOZILLA_1_5b_RELEASE 787b56d6239861bffe5cb714063d8e7a8f8dd774 JSS_4_2_BETA1 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_13_RC1 3ddbf2b0a2475cd9350c683cd7e3d96c3cafd328 smimetk_branch_point 8c8fa0bf2716618abab883b21238b5e75d3f96ba NSS_3_11_10_RC1 fd0b2d616a179c75da08145d16802a2a3a914809 FIREFOX_3_0rc3_BUILD1 252a2fefdd7ede8a9a55082317605a3c3dc3f234 FIREFOX_3_0b4_RC1 d9102467766b6324f76ffb579906c467eb07f6e9 MOZILLA_1_2a_RELEASE 897c8274a5316e847baf56878c2385aa3b21f8ec moz_win_20021104 4690f84c7554905a063e9adf848f5626adba4608 FIREFOX_3_0b4_RC2 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_4_RC2 85d51b67fed8a8753b7d9e2200f2aaa350397291 NSS_3_11_BASE 29c58ffefae09880f62862ed476c78e71b54460d MOZILLA_1_8_0_1rc1_RELEASE 2caea2fbc2d3e4153427c958de69a06a3e05ad00 PHOENIX_0_3_RELEASE 04cfdcce4b6d864adceea3e2c358882984fd73b4 NSS_3_12_8_BETA1 a994e47a0c2517eb3a31b88bbcf743b39d2b510b SECURITY_3_3_9_RTM 643c1209ddd73062f6d984e071fdd12d67730416 JSS_4_2_5_RC0 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e CW7_20010609_TAG faa44b5d84ea8993198b3897dc5c347da3440c87 MOZILLA_1_6_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb MOZILLA_1_9a5_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_10_RELEASE 1375d92b626c1a7bcb84c38b1b5ef0c716bec5e5 SUN_SECURITY_3_3_11_RTM 1e6c0f58db4358aa75c5874376ac0e466170493d Accessible_042501_Base3 61fd3e8ecc0853c406523b8be88e91a574961cb1 PHOENIX_0_5_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_5_RC3 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_5_RC2 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 THUNDERBIRD_1_5_0_5_RC1 ed601e106bb33d5b4ec3ba49614cc8c5628b4701 WINCE_20020218_BASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df MOZILLA_1_9a6_RELEASE 2a059434a6f72f3690b2d2f5fb3f0699e9006fc5 NSS_3_11_1_RTM_FORTE6 bcbac16a0d68ecf0ab8d121a5735d18c14653964 PSM1_NSS_CLIENT_TAG_20010410 279746f8384085c604dcc5b67acaf7be298422d2 FIREFOX_0_9_3_RELEASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a WEBFORMS_20050202_BASE 061ad84e2b775ef3e1fb0d40350c83872ee8da6d NSS_3_9_BASE bd83bbfc0c359eb7479e39bfd57fda59c3ab4034 JSS_3_3_1_RTM 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_13_RELEASE 369f0fdceee9efd93e2370fbc8bff1c64ac19951 FIREBIRD_0_7_RELEASE 836b0ee5e11436068953d602f980a9316f030ebb NSS_3_12_2_RTM 597d9f501aa4a70676abda23b8d7e6baeb61639f MOZILLA_0_9_5_2001100514_BASE 1e6c0f58db4358aa75c5874376ac0e466170493d XPCDOM_20010329_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_7_RC1 b9c80a14b4520400f3f99b26c1de9074d240e827 JSS_4_0_RTM 8c8fa0bf2716618abab883b21238b5e75d3f96ba NSS_3_11_10_RTM 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_5_BETA1 eaaf09571a28f504056af7eed9963683d6c9bc74 NSS_3_4_3_RTM a742ae75557ab9842f7d54b32db7ed22f26cf43d JSS_3_6_BETA1 279746f8384085c604dcc5b67acaf7be298422d2 MOZILLA_1_7_RC3 c977b694dfd54680ec9d0cf63ff9bdec8a767d31 NSS_3_13_3_RTM a7fe654cbee1b2528d82593abb3caedf92843349 Netscape61_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_1_5_0_12_RC2 023213c890c7d71fcc30aa781dbfad417a13d947 NSS_3_6_BETA3 adeeaeec3aac6fafa01e59817dadfde043654177 NSS_3_6_BETA2 ca0abcedcd669d55da30a41a71bfbc6732ab543b NSS_3_6_BETA1 fab631d240c1f62f5f0c57606807d1a85b7965d8 FIREFOX_1_5_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_9_RELEASE df7c386366a6fcaf0c61c718220816509b1a81f6 FIREFOX_3_0_3_BUILD1 fab631d240c1f62f5f0c57606807d1a85b7965d8 MOZILLA_1_8rc1_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_8_RC2 474365e481fc8ff4aa0669da721959f624f5ba60 NSS_CLIENT_TAG_20040409 597d9f501aa4a70676abda23b8d7e6baeb61639f MOTIF_LAST_RITES db7b9e6b0464fe4c6b11d813a5c453085f39a687 NSS_3_9_BETA1 69749bc0129a2a56351b6e58b6538c941cd847f5 NSS_3_9_BETA2 d011ed9b536d776da9733508a042e115aafc9249 NSS_3_9_BETA3 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_10_RTM 4804a6944abb6ab13ac114cb089c9b97d1827dcc NSS_3_9_BETA5 9c045506ec36ea01b2564bfa84ab59bd937a899c CW7_20011205_TAG 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_8_RC1 b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa NETSCAPE_7_01_RTM_RELEASE 7e078c05b972bb641cc38da2103ff913c449c013 MOZILLA_1_6b_RELEASE a963c6a23b3616e0aa1ac2fea58074d1aa93ac6a NSS_3_9_3_RTM 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d SUNBIRD_0_3_RELEASE 37b5d3664ba8f66e2db073542381e4e717af6e90 CHIMERA_M1_0_BASE 0e8ae6df014f9a3ef73536c2f3ab6eba09fdf3bf JSS_3_1_RTM b4f764d3db45e8bbddc67bae33185a957f0cbfcb NSS_3_7_BASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 SEAMONKEY_1_0_5_RELEASE 737048adb0e92456eb6e2914b26f054446d59f94 NSS_CLIENT_TAG_20031117 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_9_RTM 4ca586635181674da455f93213f5789833a59700 THUNDERBIRD_3_0a1_BUILD1 7613494079ab676424b58a18a18c81c8a61c2bda NSS_3_4_SunBeta0314 d46949c9c150f6d6386dfd15a113cb11fbc85750 JSS_4_3_1_RTM 279746f8384085c604dcc5b67acaf7be298422d2 FIREFOX_0_9_1_RELEASE b312a8b30261250380cafaa19354b5267beba2a9 NSS_CLIENT_TAG_20041015 632a7d5f5979af88c35c83aab811167b48f28264 PHT_20030715N1X_EMP_WIN ce48473da3ecf3e06e0abedebfc95fbcba97c05c NSS_3_13_4_RTM dd723df8492284680e8f08f6691c9addf356c259 CAMINO_2_0_2_RELEASE c880d824c95661178e622babad57770ed0fae67a NSS_3_12_1_RC1 36cd4d003e092c70e81bb2e78f2903a878f2fdaf NSS_3_12_4_RTM bb05189e43aee15c765558e39f6ee925d40c7244 NSS_3_4_SunBeta0318 e5b35f9d0659023339e1c681e46c9cbb09ad6c84 THUNDERBIRD_1_1a1_RELEASE c23bacddb3c649171e7209136a731db5c6c74698 MOZILLA_1_9a8_RELEASE b4190e856e27193b7068d35c97e02a1237364fa4 FIREFOX_3_0b1_RC1 279746f8384085c604dcc5b67acaf7be298422d2 NETSCAPE_7_2_RELEASE 6de86ec4dac58a2a4da1ec6b0b62ec91dbe43d32 FIREFOX_3_0b1_RC3 4743208e8b17df941141129a2a52c29e0fd9f623 THUNDERBIRD_1_5b1_RELEASE b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa NETSCAPE_7_0_RTM_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_6_RC2 1e6c0f58db4358aa75c5874376ac0e466170493d PSM2_NSS_CLIENT_TAG_20010410 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_6_RC1 279746f8384085c604dcc5b67acaf7be298422d2 THUNDERBIRD_0_7_3_RELEASE 0d07d48542dd4e1b8127eab176aab3a22163dcbb MOZILLA_1_3_RELEASE f5a4b374b0a6b84cb31b9fe33890050e059cc0bc FIREFOX_3_0_7_BUILD1 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_4_RELEASE 04c273d1fd5375411545b0ed0560ffe2402caa80 FIREFOX_3_0_7_BUILD2 2acbe005a2e6ffa820c685f28d0b207bb64d2e81 NSS_3_3_2_RTM a4f86ba5a977bada7ea56288ea5e453070c79f87 SEAMONKEY_1_0_1_RELEASE d761191b390fc6fdea41f994c58254e1df702199 MOZILLA_0_9_9_RELEASE 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_8_BETA3 4743208e8b17df941141129a2a52c29e0fd9f623 FIREFOX_1_5b2_RELEASE cc014b41cf51e27104db1aaf9cd79675e2ce3b6e LIGHTNING_0_3_1_RC1 aeb16ad4e8147f04435c042c06c38807e2da3a24 FIREFOX_3_0rc1_RELEASE d9d7b407669ebcae94cf84e0218df8b3f6a7c792 NSS_3_12_6_RC2 6ad5e6961ac3af3e24c95e1e7f3187e2e3f22ad8 NSS_3_9_2_RTM 51424d5eb149a8df5315bf04e0009eb2b27d1df9 CAMINO_0_8_3_RELEASE b42e263ddb861e5e52d05c5662286249351ac973 NSS_3_14_3_RC0 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d SUNBIRD_0_3_1_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_1_5_0_12_RC2 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_7_RTM c739ccbc0d53f5fa243b664ae4a68306ff9dfeb8 Style_20010518_Base 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RC1 4a20d3139943f1152b1bd992ab062f8ef8ae397c SUN_SECURITY_3_3_5_BETA4 b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_2002082106_TAG 597d9f501aa4a70676abda23b8d7e6baeb61639f NETSCAPE_6_2_RELEASE b793b610625c4fc5f60594111bb35a396dce1e31 nss_20021126 d25943fa7e9356faf6f34d54b3366286b52aab0f SUN_SECURITY_3_3_5_BETA2 a5bf97abe220f3af14719439412261ca8cf45a15 SUN_SECURITY_3_3_5_BETA3 22292af8d39435fd6057d07fb080b3f42d3b4e8b NETSCAPE_7_0_OEM_RELEASE 039eb9b472a82e93c6b46b9aa0db55220c3cbc94 moz_ux_20021014 efe1988d0e624426910b0c0430f7284a73140ec6 NSS_3_8_BETA2 597d9f501aa4a70676abda23b8d7e6baeb61639f MOZILLA_0_9_4_1_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba FIREFOX_2_0_0_18_RELEASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_12_RELEASE 637528ca6fd036271b8a9edd3b6bcee53ac3837b NSS_3_14_1_BETA2 7069a75b360766bf38f03b06f8c5d30a67ba84fb SEAMONKEY_1_1_2_RELEASE 9f77a3dd3cfb012d950f4a347e7d957089ca89dd NSS_3_11_TPATCH_20051221_BASE b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa MOZILLA_1_0_1_RELEASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RC5 e3f74fb6fed5a82dcb758a28bf8282fdacba947d FIREFOX_3_0_6_RELEASE 2acbe005a2e6ffa820c685f28d0b207bb64d2e81 NSS_3_3_3_BETA_Sun120602 8f32a794dcaff756e5f4f5e4529f6b2cf97a410d MOZILLA_1_7b_RELEASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RC6 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_5_RELEASE bfd3d87b7e5942ba5a9e41004543b072d4bafa62 NSS_3_13_5_BETA2 4557c07c6a12512629688576ca5796362ebeeedf NSS_3_12_3_BASE 8256dda1535f71be791a3d619587f438129a776b FIREFOX_1_0_8_RC7 cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0rc1_RC1 f379a9a8f9d3e74980ff5df7cafe65e6e7498662 MINIMO_01302003_TAG 632a7d5f5979af88c35c83aab811167b48f28264 BOOKMARKS_20030320_BASE f9157ad065bc0379f8c71e91c0dc9b5afd38978a JSS_3_1_2_SUN_PKG_1120_BETA 9fe276bab59d7de37147289da0d44cca59523a86 NMAKE_LAST_RITES b8c6aeb1b89f4f5819ae885c9fd632d214a6c8aa ANYTHING_FOR_PUTTERMAN_08082002_BASE 279746f8384085c604dcc5b67acaf7be298422d2 FIREFOX_0_9_RC1 43fb21fdd37baa7651039fd6a7d7ac286cede513 FIREFOX_2_0b2_RC1 eb28248ebd471c46ba608965cc13b113cddeb811 MACHO_20010807_BASE eb3c7d9cdac219d584a5beceaf18254473952c6c NSS_3_3_11_RTM 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_7_BETA1 8ec8594b32e54a151a5bcb4e219289e84394cb27 NSS_3_4_BASE e1c4b02f1ea8a946b179b45b26647f831329af5d JS_1_7_ALPHA_MERGE b8469ef308bbd1cbf5b7a2559e020ba4b15d661c NSS_3_8_RTM 6e5d2811a1fd06b384305de025b9bcc83c8800ce MOZILLA_1_4_4_RELEASE a4f86ba5a977bada7ea56288ea5e453070c79f87 FIREFOX_1_5_0_2_RC2 1aa27e5fc26037a07daa6828a24f8834b76b7e57 NSS_NSCP_20020228_1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 FIREFOX_1_5_0_9_RELEASE 29c58ffefae09880f62862ed476c78e71b54460d SEAMONKEY_1_0_RELEASE 28be9bc537706df7715ee4dde4efcd8dd4292d7e NSS_3_13_2_RTM 32fc3d2b031082c374a86c3202775ac45e28ba9b FIREBIRD_0_6_1_RELEASE 773657cdf8e3ea0be3fc90b616ae6d658e7f64e7 moz_ux_20021122 e4b85ba92b45eccb1cd002bdfa65561dc21d98df WEB_CONTENT_HANDLING_20070621_PRE_LAUNCHWITHURI e146f07a0a04e088a627fffe46e91f583adbb5cd NSS_CLIENT_TAG_20020217 eb28248ebd471c46ba608965cc13b113cddeb811 NOIMG_20010801_TAG 658f0fc6175fdea8b28505678f80576135446cfd NSS_3_12_9_1_RTM 7d7ee48db4871325f6b1545d4b4dbc1686df8908 NSS_CLIENT_TAG_20020213 e4b85ba92b45eccb1cd002bdfa65561dc21d98df MOZILLA_1_9a6_RC2 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_16_RELEASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df MOZILLA_1_9a6_RC1 632a7d5f5979af88c35c83aab811167b48f28264 NSS_3_7_11_RTM cc014b41cf51e27104db1aaf9cd79675e2ce3b6e FIREFOX_2_0rc3_RC1 7069a75b360766bf38f03b06f8c5d30a67ba84fb CAMINO_1_6_B2_RELEASE 474365e481fc8ff4aa0669da721959f624f5ba60 XULRUNNER_20040804_BASE 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0b2_RELEASE 602b79f6278b8086cbe40a4b263b42e7a2ab9a0d NSS_3_11_20060929_TAG 0c979022232016b996614c211a70a1ca81486791 MOZILLA_0_8_20010215_RELEASE 32fc3d2b031082c374a86c3202775ac45e28ba9b NETSCAPE_7_1_RELEASE cc014b41cf51e27104db1aaf9cd79675e2ce3b6e SEAMONKEY_1_1b_RELEASE 43fb21fdd37baa7651039fd6a7d7ac286cede513 FIREFOX_2_0b1_RELEASE 51424d5eb149a8df5315bf04e0009eb2b27d1df9 MOZILLA_1_7_11_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_18_RELEASE 73cd7806c035af2e988163b67c05d6ad2221ae80 NSS_TNH_1_BASE e4b85ba92b45eccb1cd002bdfa65561dc21d98df NSS_3_11_7_RC1 e4b85ba92b45eccb1cd002bdfa65561dc21d98df NSS_3_11_7_RC0 4743208e8b17df941141129a2a52c29e0fd9f623 CAMINO_1_0a1_RELEASE b6c5f6090e3c7014e981d66babf046cbefc9aa47 JSS_3_3_BETA1 fab631d240c1f62f5f0c57606807d1a85b7965d8 FIREFOX_1_5rc2_RELEASE 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 CAMINO_1_0_3_RELEASE e404505cc0701ed5080e5366ec8e298ba27053b4 SUN_SECURITY_3_9_3_O3B7 8c8fa0bf2716618abab883b21238b5e75d3f96ba SEAMONKEY_1_1_17_RELEASE 883e14b022a902faf381e9889d95fe7b8c82ac70 NSS_3_8_BETA1 31f3f83cdf6aeaed60efc9e7b9895bc2b4957c6e BookmarksOutliner_20010601_BASE 597d9f501aa4a70676abda23b8d7e6baeb61639f PSM_2_2_DEV_20011016_1736 eb28248ebd471c46ba608965cc13b113cddeb811 MOZILLA_0_9_3_RELEASE 9fe276bab59d7de37147289da0d44cca59523a86 MOZILLA_1_1b_RELEASE 5b1fa917edb41aeb7d1efa419ffde7449fbfa0b4 NSS_3_1_1_RTM 7069a75b360766bf38f03b06f8c5d30a67ba84fb THUNDERBIRD_2_0_0_13_RC1 fab631d240c1f62f5f0c57606807d1a85b7965d8 THUNDERBIRD_1_5rc2_RELEASE 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_19_BUILD1 d6feb49b6f77dd97caa6e35cbd1e1e3f2ea63224 NSS_3_3_2_SUN_PKG_RTM 372120233af508d1c83f9f4d8006ea6eb57867df JSS_4_3_2_RC0 7069a75b360766bf38f03b06f8c5d30a67ba84fb FIREFOX_2_0_0_9_RC1 0c4fbe0b62eaf56f9b33ad4e9164541bcd606278 XULRUNNER_1_8_0_5_RC4 8c8fa0bf2716618abab883b21238b5e75d3f96ba THUNDERBIRD_2_0_0_22_RELEASE ba7f7a07f9446dbc0a6a654afe9cc95535319e14 NSS_PERFORMANCE_HACKS_BASE 055aa3ce8a61adae592e6450d6505f7fbb4dbc77 JSS_4_4_20170313 b3e864205ff027dac3ef52847f74695e429a7f45 JSS_4_4_20170328 4ee5af07d6d8fd7efe60d130d3e7593f6e12e642 JSS_4_4_20170501 jss-4.4.3/jss/.project000066400000000000000000000005521326145000000145600ustar00rootroot00000000000000 jss org.eclipse.jdt.core.javabuilder org.eclipse.jdt.core.javanature jss-4.4.3/jss/.settings/000077500000000000000000000000001326145000000150255ustar00rootroot00000000000000jss-4.4.3/jss/.settings/org.eclipse.jdt.core.prefs000066400000000000000000000561231326145000000220160ustar00rootroot00000000000000eclipse.preferences.version=1 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16 org.eclipse.jdt.core.formatter.alignment_for_assignment=0 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1 org.eclipse.jdt.core.formatter.blank_lines_after_package=1 org.eclipse.jdt.core.formatter.blank_lines_before_field=0 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1 org.eclipse.jdt.core.formatter.blank_lines_before_method=1 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1 org.eclipse.jdt.core.formatter.blank_lines_before_package=0 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false org.eclipse.jdt.core.formatter.comment.format_block_comments=false org.eclipse.jdt.core.formatter.comment.format_header=false org.eclipse.jdt.core.formatter.comment.format_html=true org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true org.eclipse.jdt.core.formatter.comment.format_line_comments=false org.eclipse.jdt.core.formatter.comment.format_source_code=true org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true org.eclipse.jdt.core.formatter.comment.indent_root_tags=true org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert org.eclipse.jdt.core.formatter.comment.line_length=120 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false org.eclipse.jdt.core.formatter.compact_else_if=true org.eclipse.jdt.core.formatter.continuation_indentation=2 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_empty_lines=false org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false org.eclipse.jdt.core.formatter.indentation.size=8 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert org.eclipse.jdt.core.formatter.join_lines_in_comments=false org.eclipse.jdt.core.formatter.join_wrapped_lines=false org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false org.eclipse.jdt.core.formatter.lineSplit=120 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true org.eclipse.jdt.core.formatter.tabulation.char=space org.eclipse.jdt.core.formatter.tabulation.size=4 org.eclipse.jdt.core.formatter.use_on_off_tags=false org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true jss-4.4.3/jss/.settings/org.eclipse.jdt.ui.prefs000066400000000000000000000052561326145000000215040ustar00rootroot00000000000000eclipse.preferences.version=1 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true formatter_profile=_PKI Project Profile formatter_settings_version=12 sp_cleanup.add_default_serial_version_id=true sp_cleanup.add_generated_serial_version_id=false sp_cleanup.add_missing_annotations=false sp_cleanup.add_missing_deprecated_annotations=true sp_cleanup.add_missing_methods=false sp_cleanup.add_missing_nls_tags=false sp_cleanup.add_missing_override_annotations=true sp_cleanup.add_missing_override_annotations_interface_methods=true sp_cleanup.add_serial_version_id=false sp_cleanup.always_use_blocks=true sp_cleanup.always_use_parentheses_in_expressions=false sp_cleanup.always_use_this_for_non_static_field_access=false sp_cleanup.always_use_this_for_non_static_method_access=false sp_cleanup.convert_to_enhanced_for_loop=false sp_cleanup.correct_indentation=false sp_cleanup.format_source_code=false sp_cleanup.format_source_code_changes_only=false sp_cleanup.make_local_variable_final=false sp_cleanup.make_parameters_final=false sp_cleanup.make_private_fields_final=true sp_cleanup.make_type_abstract_if_missing_method=false sp_cleanup.make_variable_declarations_final=false sp_cleanup.never_use_blocks=false sp_cleanup.never_use_parentheses_in_expressions=true sp_cleanup.on_save_use_additional_actions=true sp_cleanup.organize_imports=true sp_cleanup.qualify_static_field_accesses_with_declaring_class=false sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true sp_cleanup.qualify_static_member_accesses_with_declaring_class=false sp_cleanup.qualify_static_method_accesses_with_declaring_class=false sp_cleanup.remove_private_constructors=true sp_cleanup.remove_trailing_whitespaces=true sp_cleanup.remove_trailing_whitespaces_all=true sp_cleanup.remove_trailing_whitespaces_ignore_empty=false sp_cleanup.remove_unnecessary_casts=true sp_cleanup.remove_unnecessary_nls_tags=false sp_cleanup.remove_unused_imports=true sp_cleanup.remove_unused_local_variables=false sp_cleanup.remove_unused_private_fields=true sp_cleanup.remove_unused_private_members=false sp_cleanup.remove_unused_private_methods=true sp_cleanup.remove_unused_private_types=true sp_cleanup.sort_members=false sp_cleanup.sort_members_all=false sp_cleanup.use_blocks=false sp_cleanup.use_blocks_only_for_return_and_throw=false sp_cleanup.use_parentheses_in_expressions=false sp_cleanup.use_this_for_non_static_field_access=false sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true sp_cleanup.use_this_for_non_static_method_access=false sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true jss-4.4.3/jss/Makefile000066400000000000000000000037321326145000000145540ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### # have to put this here, instead of in rules.mk, so that Java gets # built first all:: buildJava test_jss: testJava include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### include rules.mk package: $(MAKE) -C pkg publish jss-4.4.3/jss/README000066400000000000000000000166741326145000000140050ustar00rootroot00000000000000============================================ || Upstream JSS Build/Test Instructions || ============================================ (1) Prepare a work area (a) For upstream builds which checkout and utilize the current NSPR and NSS source repositories: # mkdir sandbox # cd sandbox # hg clone https://hg.mozilla.org/projects/nspr # hg clone https://hg.mozilla.org/projects/nss # hg clone https://hg.mozilla.org/projects/jss # cd .. (There is no need to clone every time. For additional builds, simply use: cd nspr; hg pull -u -v; cd ..; cd nss; hg pull -u -v; cd ..; cd jss; hg pull -u -v; cd .. ) (b) Alternatively, for upstream builds which use the NSPR and NSS installed on the system: # mkdir sandbox # cd sandbox # export USE_INSTALLED_NSPR=1 # export USE_INSTALLED_NSS=1 # export PKG_CONFIG_ALLOW_SYSTEM_LIBS=1 # export PKG_CONFIG_ALLOW_SYSTEM_CFLAGS=1 # export NSPR_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nspr | sed 's/-I//'` # export NSPR_LIB_DIR=`/usr/bin/pkg-config --libs-only-L nspr | sed 's/-L//'` # export NSS_INCLUDE_DIR=`/usr/bin/pkg-config --cflags-only-I nss | sed 's/-I//'` # export NSS_LIB_DIR=`/usr/bin/pkg-config --libs-only-L nss | sed 's/-L//'` # export XCFLAGS="-g" # hg clone https://hg.mozilla.org/projects/jss # cd .. (There is no need to clone every time. For additional builds, simply use: cd jss; hg pull -u -v; cd .. ) (2) Prepare an interactive shell for building: # export JAVA_HOME=/etc/alternatives/java_sdk_1.8.0_openjdk # export USE_64=1 NOTE: JSS will now attempt to verify whether or not these two environment variables have been set (JAVA_HOME is mandatory; USE_64 is mandatory on 64-bit platforms when building 64-bit). The following steps are optional, and left to the discretion of the user: Debug vs. Optimized jar files: By default, JSS will be built as a debuggable jar (xpclass_dbg.jar - generally recommended for test builds); to create an optimized jar (xpclass.jar), set the following environment variable: # export BUILD_OPT=1 Beta vs. Non-Beta builds: Finally, by default, JSS is not built as a "beta" release (as specified in 'org/mozilla/jss/util/jssver.h'): #define JSS_BETA PR_FALSE If a "beta" version of JSS is desired, reset this #define (as specified in 'org/mozilla/jss/util/jssver.h') to: #define JSS_BETA PR_TRUE (3) Build JSS # cd sandbox/jss # make clean all # cd ../.. (or you can run "# script -c 'make clean all' typescript.build") NOTE: When build method (1)(a) is being utilized, if nss has not been built, it will now automatically be built before jss; if nss has already been built, only jss will be built/re-built. (4) Install JSS on the System (Optional) If JSS already exists on the system, run something similar to the following command(s): # sudo mv /usr/lib/java/jss4.jar /usr/lib/java/jss4.jar.orig If the platform is 32-bit Linux: # sudo mv /usr/lib/jss/libjss4.so /usr/lib/jss/libjss4.so.orig else if the platform is 64-bit Linux: # sudo mv /usr/lib64/jss/libjss4.so /usr/lib64/jss/libjss4.so.orig If BUILD_OPT is undefined (default Debuggable Jar): # sudo cp sandbox/dist/xpclass_dbg.jar /usr/lib/java/jss4.jar else if BUILD_OPT is defined (Optimized Jar): # sudo cp sandbox/dist/xpclass.jar /usr/lib/java/jss4.jar # sudo chown root:root /usr/lib/java/jss4.jar # sudo chmod 644 /usr/lib/java/jss4.jar # sudo cp sandbox/jss/lib/Linux*.OBJ/libjss4.so /usr/lib64/jss/libjss4.so # sudo chown root:root /usr/lib64/jss/libjss4.so # sudo chmod 755 /usr/lib64/jss/libjss4.so (5) Run JSS Tests (Optional, but only if build method (1)(a) was utilized) If build method (1)(a) is being utilized, it is possible to run the built-in JSS tests: # cd sandbox/jss # make test_jss # cd ../.. (or you can run "# script -c 'make test_jss' typescript.tests") NOTE: This command is currently only available on Linux and Macintosh platforms when method (1)(a) has been utilized to build JSS since the tests are dependent upon the work area as setup in this method; currenty JSS must be built via 'make clean all' before execution of this command (e.g. - build is separate from test). (6) Restoration of non-Test-Only Systems (Optional) If step (4) above was run, and the system is being used for purposes other than test, the user may wish to restore the original system JSS by running the following commands: # sudo mv /usr/lib/java/jss4.jar.orig /usr/lib/java/jss4.jar If the platform is 32-bit Linux: # sudo mv /usr/lib/jss/libjss4.so.orig /usr/lib/jss/libjss4.so else if the platform is 64-bit Linux: # sudo mv /usr/lib64/jss/libjss4.so.orig /usr/lib64/jss/libjss4.so NOTE: For this procedure, no ownership or permission changes should be necessary. (7) Tagging the Source Code for a Release During development, several releases may be made. Consequently, it is good practice to create a "regular tag" to the source code at these various points in time using the following format: # hg tag -m "message" JSS___YYYYMMDD where: = JSS Major Version Number = JSS Minor Version Number YYYY = 4-digit year (e. g. - 2017) MM = 2-digit month (e. g. - 01, ..., 12) DD = 2-digit day of the month (e. g. - 01, ..., 31) For example: # hg id b3e864205ff0+ tip # hg tag -m "Added tag JSS_4_4_20170328 for changeset b3e864205ff0" JSS_4_4_20170328 At the appropriate time, a new major.minor version may be created. At this time, it is important to create a maintenance branch for any future changes to the previous major.minor version: For example: # hg id f00f00f00f00+ tip # hg branch -m "Created branch JSS_4_4_BRANCH for changeset f00f00f00f00" JSS_4_4_BRANCH (8) Known Issues * Mozilla Bug #1346410 - Load JSS libraries appropriately NOTE: This issue should not occur unless step (4) above was skipped. Testing failures were found while working on Bug 1346410 when loading the JSS libraries to meet requirements of certain operating systems. Our investigation revealed that due to the nature of the changes made via this patch and its interaction with the HMAC Tests (both non-FIPS and FIPS), that a failure may be encountered on one or more of the HMAC algorithms causing these two tests to fail. On 64-bit Linux, for example, the workaround for this issue is to perform the following steps before re-running the tests: (a) Install the new JSS builds by executing step (4) above (b) Execute the following commands: # cd sandbox/jss; make test_jss NOTE: If the system is being used for purposes other than test, the user may wish to restore the original JSS by executing step (6) above. jss-4.4.3/jss/build_java.pl000066400000000000000000000345721326145000000155570ustar00rootroot00000000000000#use strict; use File::Find; use File::Compare; use File::Basename; use File::stat; use File::Copy; @excluded_sources = qw( provider\.new/ org/mozilla/jss/provider/java/security/KeyFactorySpi1_4\.java org/mozilla/jss/pkix/cert/X509Certificate\.java samples/ ); @javah_classes = qw( org.mozilla.jss.DatabaseCloser org.mozilla.jss.CryptoManager org.mozilla.jss.crypto.Algorithm org.mozilla.jss.crypto.EncryptionAlgorithm org.mozilla.jss.crypto.PQGParams org.mozilla.jss.crypto.SecretDecoderRing org.mozilla.jss.asn1.ASN1Util org.mozilla.jss.pkcs11.CertProxy org.mozilla.jss.pkcs11.CipherContextProxy org.mozilla.jss.pkcs11.PK11Module org.mozilla.jss.pkcs11.ModuleProxy org.mozilla.jss.pkcs11.PK11Cert org.mozilla.jss.pkcs11.PK11Cipher org.mozilla.jss.pkcs11.PK11KeyWrapper org.mozilla.jss.pkcs11.PK11MessageDigest org.mozilla.jss.pkcs11.PK11PrivKey org.mozilla.jss.pkcs11.PK11PubKey org.mozilla.jss.pkcs11.PK11SymKey org.mozilla.jss.pkcs11.PK11KeyPairGenerator org.mozilla.jss.pkcs11.PK11SymmetricKeyDeriver org.mozilla.jss.pkcs11.PK11KeyGenerator org.mozilla.jss.pkcs11.PK11Token org.mozilla.jss.pkcs11.PrivateKeyProxy org.mozilla.jss.pkcs11.PublicKeyProxy org.mozilla.jss.pkcs11.SymKeyProxy org.mozilla.jss.pkcs11.KeyProxy org.mozilla.jss.pkcs11.PK11Token org.mozilla.jss.pkcs11.TokenProxy org.mozilla.jss.pkcs11.PK11Signature org.mozilla.jss.pkcs11.PK11Store org.mozilla.jss.pkcs11.PK11KeyPairGenerator org.mozilla.jss.pkcs11.SigContextProxy org.mozilla.jss.pkcs11.PK11RSAPublicKey org.mozilla.jss.pkcs11.PK11DSAPublicKey org.mozilla.jss.pkcs11.PK11ECPublicKey org.mozilla.jss.pkcs11.PK11SecureRandom org.mozilla.jss.provider.java.security.JSSKeyStoreSpi org.mozilla.jss.SecretDecoderRing.KeyManager org.mozilla.jss.ssl.SSLSocket org.mozilla.jss.ssl.SSLServerSocket org.mozilla.jss.ssl.SocketBase org.mozilla.jss.util.Debug org.mozilla.jss.util.Password ); @packages = qw( org.mozilla.jss org.mozilla.jss.asn1 org.mozilla.jss.crypto org.mozilla.jss.pkcs7 org.mozilla.jss.pkcs10 org.mozilla.jss.pkcs11 org.mozilla.jss.pkcs12 org.mozilla.jss.pkix.primitive org.mozilla.jss.pkix.cert org.mozilla.jss.pkix.cmc org.mozilla.jss.pkix.cmmf org.mozilla.jss.pkix.cms org.mozilla.jss.pkix.crmf org.mozilla.jss.provider.java.security org.mozilla.jss.provider.javax.crypto org.mozilla.jss.SecretDecoderRing org.mozilla.jss.ssl org.mozilla.jss.tests org.mozilla.jss.util ); # setup environment setup_env(); # setup variables setup_vars(\@ARGV); # run the command with its arguments my $cmd = (shift || "build"); # first argument is command grep { s/(.*)/"$1"/ } @ARGV; # enclose remaining arguments in quotes my $args = join(",",@ARGV); # and comma-separate them eval "$cmd($args)"; # now run the command if( $@ ) { die $@; # errors in eval will be put in $@ } # END sub grab_cmdline_vars { my $argv = shift; while( $$argv[0] =~ /(.+)=(.*)/ ) { $cmdline_vars{$1} = $2; shift @$argv; } } sub dump_cmdline_vars { print "Command variables:\n"; for(keys %cmdline_vars) { print "$_=" . $cmdline_vars{$_} . "\n"; } } sub setup_env { # check that JAVA_HOME environment variable has been set externally $ENV{JAVA_HOME} or die "\nMust specify JAVA_HOME environment variable!\n" . "(e. g. - export JAVA_HOME=/etc/alternatives/java_sdk_1.8.0_openjdk)" . "\n\n"; print "JAVA_HOME=$ENV{'JAVA_HOME'}\n"; # check that USE_64 environment variable has been set externally # for 64-bit architectures (when applicable) $bitsize = `getconf LONG_BIT`; if( $bitsize == 64 ) { $ENV{USE_64} or die "\nMust specify USE_64 environment variable!\n" . "(e. g. - export USE_64=1)\n\n"; print "USE_64=$ENV{'USE_64'}\n"; } } sub setup_vars { my $argv = shift; grab_cmdline_vars($argv); dump_cmdline_vars(); $jar = "$ENV{JAVA_HOME}/bin/jar"; $javac = "$ENV{JAVA_HOME}/bin/javac"; $javah = "$ENV{JAVA_HOME}/bin/javah"; $javadoc = "$ENV{JAVA_HOME}/bin/javadoc"; $dist_dir = $cmdline_vars{SOURCE_PREFIX}; $jce_jar = $ENV{JCE_JAR}; $class_release_dir = $cmdline_vars{SOURCE_RELEASE_PREFIX}; if( $ENV{BUILD_OPT} ) { $class_dir = "$dist_dir/classes"; $class_jar = "$dist_dir/$cmdline_vars{XPCLASS_JAR}"; $class_release_dir .= "/$cmdline_vars{SOURCE_RELEASE_CLASSES_DIR}"; $javac_opt_flag = "-O"; $debug_source_file = "org/mozilla/jss/util/Debug_ship.jnot"; } else { $class_dir = "$dist_dir/classes_DBG"; $class_jar = "$dist_dir/$cmdline_vars{XPCLASS_DBG_JAR}"; $class_release_dir .= "/$cmdline_vars{SOURCE_RELEASE_CLASSES_DBG_DIR}"; $javac_opt_flag = "-g"; $debug_source_file = "org/mozilla/jss/util/Debug_debug.jnot"; } $jni_header_dir = "$dist_dir/private/jss/_jni"; if( $jce_jar ) { $classpath = "-classpath $jce_jar"; } # retrieve present working directory $pwd = `pwd`; $pwd =~ chomp $pwd; # retrieve architecture $arch = `uname -m`; $arch =~ chomp $arch; # retrieve operating system $os = `uname`; $os =~ chomp $os; if( ( $ENV{USE_INSTALLED_NSPR} ) && ( $ENV{USE_INSTALLED_NSS} ) ) { print "Using the NSPR and NSS installed on the system to build JSS.\n"; } else { # Verify existence of work area if(( ! -d "$pwd/../nspr" ) || ( ! -d "$pwd/../nss" ) || ( ! -d "$pwd/../jss" )) { my $workarea = "\nA work area must first be prepared; for example:\n\n" . " mkdir sandbox\n" . " cd sandbox\n" . " hg clone https://hg.mozilla.org/projects/nspr\n" . " hg clone https://hg.mozilla.org/projects/nss\n" . " hg clone https://hg.mozilla.org/projects/jss\n" . " cd ..\n\n"; die "$workarea"; } # Build NSS if not already built if( ! -d $dist_dir ) { print("########################\n" . "# BEGIN: Building NSS #\n" . "########################\n"); print_do("cd ../nss;make clean nss_build_all;cd ../jss"); print("######################\n" . "# END: Building NSS #\n" . "######################\n"); } if( $os eq 'Linux' || $os eq 'Darwin' ) { # set major and minor release numbers $majorrel = `uname -r | cut -f1 -d.`; $majorrel =~ chomp $majorrel; $minorrel = `uname -r | cut -f2 -d.`; $minorrel =~ chomp $minorrel; # read the contents of the $dist_dir into an array opendir DIR, $dist_dir or die "Cannot open directory: $!"; my @files = readdir DIR; closedir DIR; # process the array to obtain the NSS OBJDIR_NAME my $prefix = "$os$majorrel.$minorrel"; foreach my $file (@files) { if ((index($file, $prefix) != -1) && (index($file, "_cc") != -1)) { $nss_objdir_name = $file; print "NSS OBJDIR_NAME=$nss_objdir_name\n"; # craft JSS OBJDIR_NAME based upon value of NSS OBJDIR_NAME $jss_objdir_name = $nss_objdir_name; $jss_objdir_name =~ s/_cc//; print "JSS OBJDIR_NAME=$jss_objdir_name\n"; break; } } # create a JSS OBJDIR_NAME symlink to NSS OBJDIR_NAME in $dist_dir $jss_symlink = "$pwd/../dist/$jss_objdir_name"; if( ! -l $jss_symlink ) { my $cmd = "cd ../dist;" . "ln -s $nss_objdir_name $jss_objdir_name;" . "cd ../jss"; print_do($cmd); } print "jss_symlink=$jss_symlink\n" } } } sub clean { print_do("rm -rf $class_dir"); print_do("rm -f $class_jar"); print_do("rm -rf $jni_header_dir"); } sub build { # # copy the appropriate debug file # my $debug_target_file = "org/mozilla/jss/util/Debug.java"; if( compare($debug_source_file, $debug_target_file) ) { copy($debug_source_file, $debug_target_file) or die "Copying file: $!"; } # # generate manifest.mf file in lib dir # my $manifest_file = "MANIFEST.MF"; my $jss_revision = `grep JSS_VERSION org/mozilla/jss/util/jssver.h`; chop($jss_revision); $jss_revision = substr($jss_revision, 22, 3); my $build_revision = $jss_revision; $append = 0; if ($append) { open(MYOUTFILE, ">MANIFEST.MF"); #open for write, overwrite } else { open(MYOUTFILE, ">>MANIFEST.MF"); #open for write, append } #*** Print freeform text, semicolon required *** print MYOUTFILE <<"MyLabel"; Manifest-Version: 1.0 Name: org/mozilla/jss/ Specification-Title: Network Security Services for Java (JSS) Specification-Version: $jss_revision Specification-Vendor: Mozilla Foundation Implementation-Title: org.mozilla.jss Implementation-Version: $build_revision Implementation-Vendor: Mozilla Foundation MyLabel #*** Close the file *** close(MYOUTFILE); # # recursively find *.java # my %source_list; find sub { my $name = $File::Find::name; if( $name =~ /\.java$/) { $source_list{$File::Find::name} = 1; } }, "."; # # weed out files that are excluded or don't need to be updated # my $file; foreach $file (keys %source_list) { my $pattern; foreach $pattern (@excluded_sources) { if( $file =~ /$pattern/ ) { delete $source_list{$file}; } } unless( java_source_needs_update( $file, $class_dir ) ){ delete $source_list{$file}; } } my @source_list = keys(%source_list); # # build the java sources # if( scalar(@source_list) > 0 ) { ensure_dir_exists($class_dir); print_do("$javac $javac_opt_flag -sourcepath . -d $class_dir " . "$classpath " . join(" ",@source_list)); print_do("sh -c 'pwd && cd $class_dir && pwd && rm -f $class_jar && pwd && ls -al && ls -al ../../dist && $jar -cvmf ../../jss/$manifest_file ../$class_jar *'"); print_do("rm -f $manifest_file"); print "Exit status was " . ($?>>8) . "\n"; } # # create the JNI header files # ensure_dir_exists($jni_header_dir); print_do("$javah -classpath $class_dir -d $jni_header_dir " . (join " ", @javah_classes) ); } sub print_do { my $cmd = shift; print "$cmd\n"; system($cmd); my $exit_status = $?>>8; $exit_status and die "Command failed ($exit_status)\n"; } sub needs_update { my $target = shift; my @dependencies = @_; my $target_mtime = (stat($target))[9]; my $dep; foreach $dep( @dependencies ) { my $dep_mtime = (stat($dep))[9]; if( $dep_mtime > $target_mtime ) { return 1; } } return 0; } # A quick-and-dirty way to guess whether a .java file needs to be rebuilt. # We merely look for a .class file of the same name. This won't work if # the source file's directory is different from its package, and it # doesn't know about nested or inner classes. # source_file: the relative path to the source file ("org/mozilla/jss/...") # dest_dir: the directory where classes are output ("../../dist/classes_DBG") # Returns 1 if the source file is newer than the class file, or the class file # doesn't exist. Returns 0 if the class file is newer than the source file. sub java_source_needs_update { my $source_file = shift; my $dest_dir = shift; my $class_dir = "$dest_dir/" . dirname($source_file); my $class_file = basename($source_file); $class_file =~ s/\.java/.class/; $class_file = $class_dir . "/" . $class_file; if( -f $class_file ) { my $class_stat = stat($class_file); my $source_stat = stat($source_file); if( $source_stat->mtime > $class_stat->mtime) { # class file exists and is out of date return 1; } else { #class file exists and is up to date return 0; } } else { # class file hasn't been generated yet. return 1; } } # Recursively makes the given directory. Dies at the first sign of trouble sub ensure_dir_exists { my $dir = shift; my $parent = dirname($dir); if( $parent ne $dir ) { ensure_dir_exists($parent); } if( ! -d $dir ) { mkdir($dir, 0777) or die "Failed to mkdir $dir: $!"; } } sub release { # copy all class files into release directory ensure_dir_exists("$class_release_dir"); print_do("cp -r $class_dir/* $class_release_dir"); } sub javadoc { my $html_header_opt; if( $ENV{HTML_HEADER} ) { $html_header_opt = "-header '$ENV{HTML_HEADER}'"; } ensure_dir_exists("$dist_dir/jssdoc"); my $targets = join(" ", @packages); print "$targets\n"; print_do("$javadoc -breakiterator -sourcepath . -d $dist_dir/jssdoc $html_header_opt $targets"); print_do("cp $dist_dir/jssdoc/index.html $dist_dir/jssdoc/index.html.bak"); print_do("cp $dist_dir/jssdoc/overview-summary.html $dist_dir/jssdoc/index.html"); } sub test { if( ( $ENV{USE_INSTALLED_NSPR} ) && ( $ENV{USE_INSTALLED_NSS} ) ) { die "make test_jss is only available on upstream builds of Linux and MacOS platforms."; } elsif( $os eq 'Linux' || $os eq 'Darwin' ) { # Test JSS presuming that it has already been built if(( -d $dist_dir ) && ( -l $jss_symlink )) { my $cmd = "cd $pwd/org/mozilla/jss/tests;" . "perl all.pl dist $jss_symlink;" . "cd $pwd"; print("#######################\n" . "# BEGIN: Testing JSS #\n" . "#######################\n"); print_do($cmd); print("#####################\n" . "# END: Testing JSS #\n" . "#####################\n"); } else { die "JSS builds are not available at $jss_symlink."; } } else { die "make test_jss is only available on Linux and MacOS platforms."; } } jss-4.4.3/jss/config/000077500000000000000000000000001326145000000143545ustar00rootroot00000000000000jss-4.4.3/jss/config/config.mk000066400000000000000000000026531326145000000161600ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Configuration information unique to the "sectools" component # ####################################################################### # Local "sectools" component library link options # ####################################################################### include $(CORE_DEPTH)//config/linkage.mk ####################################################################### # Local "sectools" component STATIC system library names # ####################################################################### include $(CORE_DEPTH)/config/static.mk ####################################################################### # Local "sectools" component DYNAMIC system library names # ####################################################################### include $(CORE_DEPTH)/config/dynamic.mk # Stricter semantic checking for SunOS compiler. This catches calling # undeclared functions, a major headache during debugging. ifeq ($(OS_ARCH), SunOS) OS_CFLAGS += -v endif ifeq ($(OS_ARCH), WINNT) LINK_DLL += -LIBPATH:$(SOURCE_LIB_DIR) LINK_DLL += -LIBPATH:$(JAVA_HOME)/$(JAVA_LIBDIR) LINK_DLL += $(foreach file,$(LD_LIBS),-DEFAULTLIB:"$(notdir $(file))") endif CFLAGS += -I$(JAVA_HOME)/include jss-4.4.3/jss/config/dynamic.mk000066400000000000000000000035531326145000000163370ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Initialize DYNAMIC system library names on some platforms # ####################################################################### # # AIX platforms # ifeq ($(OS_ARCH),AIX) ifeq ($(OS_RELEASE),4.1) DLLSYSTEM += -lsvld -lC_r -lC -lpthreads -lc_r -lm /usr/lib/libc.a else DLLSYSTEM += -ldl -lC_r -lC -lpthreads -lc_r -lm /usr/lib/libc.a endif endif # # HP/UX platforms # ifeq ($(OS_ARCH),HP-UX) ifeq ($(USE_PTHREADS), 1) DLLSYSTEM += -lpthread endif ifeq ($(PTHREADS_USER), 1) DLLSYSTEM += -lpthread endif ifeq ($(OS_RELEASE),A.09.03) DLLSYSTEM += -ldld -L/lib/pa1.1 -lm else DLLSYSTEM += -ldld -lm -lc endif endif # # IRIX platforms # ifeq ($(OS_ARCH), IRIX) ifeq ($(USE_PTHREADS), 1) DLLSYSTEM += -lpthread endif endif # # Linux platforms # ifeq ($(OS_ARCH), Linux) DLLSYSTEM += -ldl -lpthread -lm endif # # NCR platforms # ifeq ($(OS_ARCH), NCR) DLLSYSTEM += -lsocket -ldl -lnsl -lc endif # # OSF 1 platforms # ifeq ($(OS_ARCH),OSF1) ifneq ($(OS_RELEASE),V2.0) DLLSYSTEM += -lc_r endif ifeq ($(USE_PTHREADS), 1) DLLSYSTEM += -lpthread -lrt endif ifeq ($(USE_IPV6), 1) DLLSYSTEM += -lip6 endif endif # # SCO platforms # ifeq ($(OS_ARCH), SCO_SV) DLLSYSTEM += -lsocket -ldl -lnsl -lc endif # # Solaris platforms # ifeq ($(OS_ARCH), SunOS) ifneq ($(OS_RELEASE), 4.1.3_U1) DLLSYSTEM += -lthread -lposix4 -lsocket -lnsl -lintl -ldl endif endif # # UNIXWARE platforms # ifeq ($(OS_ARCH), UNIXWARE) DLLSYSTEM += -lsocket endif # # Windows platforms # ifeq ($(OS_ARCH),WINNT) ifneq ($(OS_TARGET),WIN16) DLLSYSTEM += wsock32.lib winmm.lib endif endif jss-4.4.3/jss/config/linkage.mk000066400000000000000000000024061326145000000163210ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Adjust variables for component library linkage on some platforms # ####################################################################### # # AIX platforms # ifeq ($(OS_ARCH),AIX) LDOPTS += -blibpath:.:$(PWD)/$(SOURCE_LIB_DIR):/usr/lib/threads:/usr/lpp/xlC/lib:/usr/lib:/lib endif # # HP/UX platforms # ifeq ($(OS_ARCH), HP-UX) LDOPTS += -Wl,+s,+b,$(PWD)/$(SOURCE_LIB_DIR) endif # # IRIX platforms # ifeq ($(OS_ARCH), IRIX) LDOPTS += -rpath $(PWD)/$(SOURCE_LIB_DIR) endif # # OSF 1 platforms # ifeq ($(OS_ARCH), OSF1) LDOPTS += -rpath $(PWD)/$(SOURCE_LIB_DIR) -lpthread endif # # Solaris platforms # NOTE: Disable optimization on SunOS4.1.3 # ifeq ($(OS_ARCH), SunOS) ifneq ($(OS_RELEASE), 4.1.3_U1) ifdef NS_USE_GCC LDOPTS += -Xlinker -R -Xlinker $(PWD)/$(SOURCE_LIB_DIR) else LDOPTS += -R $(PWD)/$(SOURCE_LIB_DIR) endif else OPTIMIZER = endif endif # # Windows platforms # ifeq ($(OS_ARCH), WINNT) LDOPTS += -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO endif jss-4.4.3/jss/config/rules.mk000066400000000000000000000010641326145000000160400ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### ### ### ### R U L E S O F E N G A G E M E N T ### ### ### ####################################################################### jss-4.4.3/jss/config/static.mk000066400000000000000000000037231326145000000162010ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Initialize STATIC system library names on some platforms # ####################################################################### # # AIX platforms # ifeq ($(OS_ARCH),AIX) ifeq ($(OS_RELEASE),4.1) LIBSYSTEM += /lib/libsvld.a /lib/libC_r.a /lib/libC.a /lib/libpthreads.a /lib/libc_r.a /lib/libm.a /lib/libc.a else LIBSYSTEM += -ldl /lib/libC_r.a /lib/libC.a /lib/libpthreads.a /lib/libc_r.a /lib/libm.a /lib/libc.a endif endif # # HP/UX platforms # ifeq ($(OS_ARCH),HP-UX) ifeq ($(USE_PTHREADS), 1) LIBSYSTEM += -lpthread endif ifeq ($(PTHREADS_USER), 1) LIBSYSTEM += -lpthread endif ifeq ($(OS_RELEASE),A.09.03) LIBSYSTEM += -ldld -L/lib/pa1.1 -lm else LIBSYSTEM += -ldld -lm -lc endif endif # # Linux platforms # ifeq ($(OS_ARCH), Linux) LIBSYSTEM += -ldl endif # # IRIX platforms # ifeq ($(OS_ARCH), IRIX) ifeq ($(USE_PTHREADS), 1) LIBSYSTEM += -lpthread endif endif # # OSF 1 platforms # ifeq ($(OS_ARCH),OSF1) ifneq ($(OS_RELEASE),V2.0) LIBSYSTEM += -lc_r endif ifeq ($(USE_PTHREADS), 1) LIBSYSTEM += -lpthread -lrt endif ifeq ($(USE_IPV6), 1) LIBSYSTEM += -lip6 endif endif # # Solaris platforms # ifeq ($(OS_ARCH), SunOS) ifneq ($(OS_RELEASE), 4.1.3_U1) ifeq ($(OS_RELEASE), 5.5.1_i86pc) LIBSYSTEM += -lsocket -lnsl -lintl -ldl else ifeq ($(OS_RELEASE), 5.6_i86pc) LIBSYSTEM += -lsocket -lnsl -lintl -ldl else LIBSYSTEM += -lthread -lposix4 /lib/libsocket.a /lib/libnsl.a /lib/libintl.a -ldl endif endif endif endif # # UNIXWARE platforms # ifeq ($(OS_ARCH), UNIXWARE) LIBSYSTEM += -lsocket endif # # Windows platforms # ifeq ($(OS_ARCH),WINNT) ifneq ($(OS_TARGET),WIN16) LIBSYSTEM += wsock32.lib winmm.lib endif endif jss-4.4.3/jss/coreconf/000077500000000000000000000000001326145000000147055ustar00rootroot00000000000000jss-4.4.3/jss/coreconf/AIX.mk000066400000000000000000000030661326145000000156640ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Config stuff for AIX. include $(CORE_DEPTH)/coreconf/UNIX.mk # # There are two implementation strategies available on AIX: # pthreads, and pthreads-user. The default is pthreads. # In both strategies, we need to use pthread_user.c, instead of # aix.c. The fact that aix.c is never used is somewhat strange. # # So we need to do the following: # - Default (PTHREADS_USER not defined in the environment or on # the command line): # Set PTHREADS_USER=1, USE_PTHREADS=1 # - PTHREADS_USER=1 set in the environment or on the command line: # Do nothing. # ifeq ($(PTHREADS_USER),1) USE_PTHREADS = # just to be safe IMPL_STRATEGY = _PTH_USER else USE_PTHREADS = 1 PTHREADS_USER = 1 endif DEFAULT_COMPILER = xlc_r CC = xlc_r CCC = xlC_r CPU_ARCH = rs6000 RANLIB = ranlib OS_CFLAGS = -DAIX -DSYSV OS_LIBS += -blibpath:/usr/lib:/lib -lc -lm DSO_LDOPTS = -brtl -bnortllib -bM:SRE -bnoentry MKSHLIB = $(LD) $(DSO_LDOPTS) -blibpath:/usr/lib:/lib -lc -lm AIX_WRAP = $(DIST)/lib/aixwrap.o AIX_TMP = $(OBJDIR)/_aix_tmp.o ifdef MAPFILE DSO_LDOPTS += -bexport:$(MAPFILE) else DSO_LDOPTS += -bexpall endif PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \ sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' > $@ ifdef BUILD_OPT OPTIMIZER += -qmaxmem=-1 endif ifeq ($(USE_64), 1) OS_CFLAGS += -DAIX_64BIT OBJECT_MODE=64 export OBJECT_MODE endif jss-4.4.3/jss/coreconf/Android.mk000066400000000000000000000003621326145000000166170ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/Linux.mk jss-4.4.3/jss/coreconf/BSD_OS.mk000066400000000000000000000024341326145000000162520ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = gcc CC = gcc CCC = g++ RANLIB = ranlib ifeq ($(OS_TEST),i386) OS_REL_CFLAGS = -D__i386__ CPU_ARCH = x86 else ifeq ($(OS_TEST),ppc) OS_REL_CFLAGS = -D__ppc__ CPU_ARCH = ppc else ifeq ($(OS_TEST),sparc) OS_REL_CFLAGS = -D__sparc__ CPU_ARCH = sparc else # treat the ultrasparc like a regular sparc, at least for now! ifeq ($(OS_TEST),sparc_v9) OS_REL_CFLAGS = -D__sparc__ CPU_ARCH = sparc endif endif endif endif DLL_SUFFIX = so OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -DBSD_OS -DBSDI -Dunix -DHAVE_STRERROR -DHAVE_BSD_FLOCK ARCH = bsdos DSO_CFLAGS = -fPIC -DPIC DSO_LDOPTS = -shared -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) ifdef LIBRUNPATH DSO_LDOPTS += -Wl,-R$(LIBRUNPATH) endif MKSHLIB = $(CC) $(DSO_LDOPTS) ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ G++INCLUDES = -I/usr/include/g++ INCLUDES += -I/usr/X11R6/include jss-4.4.3/jss/coreconf/BeOS.mk000066400000000000000000000015261326145000000160320ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk XP_DEFINE := $(XP_DEFINE:-DXP_UNIX=-DXP_BEOS) USE_PTHREADS = ifeq ($(USE_PTHREADS),1) IMPL_STRATEGY = _PTH endif CC = gcc CCC = g++ RANLIB = ranlib DEFAULT_COMPILER = gcc ifeq ($(OS_TEST),ppc) OS_REL_CFLAGS = -Dppc CPU_ARCH = ppc else OS_REL_CFLAGS = -Di386 CPU_ARCH = x86 endif MKSHLIB = $(CC) -nostart -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) ifdef BUILD_OPT OPTIMIZER = -O2 endif OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -Wno-switch -pipe OS_LIBS = -lbe DEFINES += -DBEOS ifdef USE_PTHREADS DEFINES += -D_REENTRANT endif ARCH = beos DSO_CFLAGS = -fPIC DSO_LDOPTS = jss-4.4.3/jss/coreconf/Darwin.mk000066400000000000000000000100251326145000000164600ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = gcc CC = gcc CCC = g++ RANLIB = ranlib ifndef CPU_ARCH # When cross-compiling, CPU_ARCH should already be defined as the target # architecture, set to powerpc or i386. CPU_ARCH := $(shell uname -p) endif ifeq (,$(filter-out i%86,$(CPU_ARCH))) ifdef USE_64 CC += -arch x86_64 override CPU_ARCH = x86_64 else OS_REL_CFLAGS = -Di386 CC += -arch i386 override CPU_ARCH = x86 endif else ifeq (arm,$(CPU_ARCH)) # Nothing set for arm currently. else OS_REL_CFLAGS = -Dppc CC += -arch ppc endif endif ifneq (,$(MACOS_SDK_DIR)) GCC_VERSION_FULL := $(shell $(CC) -dumpversion) GCC_VERSION_MAJOR := $(shell echo $(GCC_VERSION_FULL) | awk -F. '{ print $$1 }') GCC_VERSION_MINOR := $(shell echo $(GCC_VERSION_FULL) | awk -F. '{ print $$2 }') GCC_VERSION = $(GCC_VERSION_MAJOR).$(GCC_VERSION_MINOR) ifeq (,$(filter-out 2 3,$(GCC_VERSION_MAJOR))) # GCC <= 3 DARWIN_SDK_FRAMEWORKS = -F$(MACOS_SDK_DIR)/System/Library/Frameworks ifneq (,$(shell find $(MACOS_SDK_DIR)/Library/Frameworks -maxdepth 0)) DARWIN_SDK_FRAMEWORKS += -F$(MACOS_SDK_DIR)/Library/Frameworks endif DARWIN_SDK_CFLAGS = -nostdinc -isystem $(MACOS_SDK_DIR)/usr/include/gcc/darwin/$(GCC_VERSION) -isystem $(MACOS_SDK_DIR)/usr/include $(DARWIN_SDK_FRAMEWORKS) DARWIN_SDK_LDFLAGS = -L$(MACOS_SDK_DIR)/usr/lib/gcc/darwin -L$(MACOS_SDK_DIR)/usr/lib/gcc/darwin/$(GCC_VERSION_FULL) -L$(MACOS_SDK_DIR)/usr/lib DARWIN_SDK_SHLIBFLAGS = $(DARWIN_SDK_LDFLAGS) $(DARWIN_SDK_FRAMEWORKS) NEXT_ROOT = $(MACOS_SDK_DIR) export NEXT_ROOT else # GCC >= 4 DARWIN_SDK_CFLAGS = -isysroot $(MACOS_SDK_DIR) ifneq (4.0.0,$(GCC_VERSION_FULL)) # gcc > 4.0.0 passes -syslibroot to ld based on -isysroot. # Don't add -isysroot to DARWIN_SDK_LDFLAGS, because the programs # that are linked with those flags also get DARWIN_SDK_CFLAGS. DARWIN_SDK_SHLIBFLAGS = -isysroot $(MACOS_SDK_DIR) else # gcc 4.0.0 doesn't pass -syslibroot to ld, it needs to be # explicit. DARWIN_SDK_LDFLAGS = -Wl,-syslibroot,$(MACOS_SDK_DIR) DARWIN_SDK_SHLIBFLAGS = $(DARWIN_SDK_LDFLAGS) endif endif LDFLAGS += $(DARWIN_SDK_LDFLAGS) endif # "Commons" are tentative definitions in a global scope, like this: # int x; # The meaning of a common is ambiguous. It may be a true definition: # int x = 0; # or it may be a declaration of a symbol defined in another file: # extern int x; # Use the -fno-common option to force all commons to become true # definitions so that the linker can catch multiply-defined symbols. # Also, common symbols are not allowed with Darwin dynamic libraries. OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Wall -fno-common -pipe -DDARWIN -DHAVE_STRERROR -DHAVE_BSD_FLOCK $(DARWIN_SDK_CFLAGS) ifdef BUILD_OPT ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE)) OPTIMIZER = -Oz else OPTIMIZER = -O2 endif ifdef MOZ_DEBUG_SYMBOLS ifdef MOZ_DEBUG_FLAGS OPTIMIZER += $(MOZ_DEBUG_FLAGS) else OPTIMIZER += -gdwarf-2 -gfull endif endif endif ARCH = darwin DSO_CFLAGS = -fPIC # May override this with different compatibility and current version numbers. DARWIN_DYLIB_VERSIONS = -compatibility_version 1 -current_version 1 # May override this with -bundle to create a loadable module. DSO_LDOPTS = -dynamiclib $(DARWIN_DYLIB_VERSIONS) -install_name @executable_path/$(notdir $@) -headerpad_max_install_names MKSHLIB = $(CC) $(DSO_LDOPTS) $(DARWIN_SDK_SHLIBFLAGS) DLL_SUFFIX = dylib ifdef MAPFILE MKSHLIB += -exported_symbols_list $(MAPFILE) endif PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \ sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,_,' > $@ USE_SYSTEM_ZLIB = 1 ZLIB_LIBS = -lz jss-4.4.3/jss/coreconf/FreeBSD.mk000066400000000000000000000024241326145000000164520ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = gcc CC = gcc CCC = g++ RANLIB = ranlib CPU_ARCH = $(OS_TEST) ifeq ($(CPU_ARCH),i386) CPU_ARCH = x86 endif ifeq ($(CPU_ARCH),pc98) CPU_ARCH = x86 endif ifeq ($(CPU_ARCH),amd64) CPU_ARCH = x86_64 endif OS_CFLAGS = $(DSO_CFLAGS) -ansi -Wall -Wno-switch -DFREEBSD -DHAVE_STRERROR -DHAVE_BSD_FLOCK DSO_CFLAGS = -fPIC DSO_LDOPTS = -shared -Wl,-soname -Wl,$(notdir $@) # # The default implementation strategy for FreeBSD is pthreads. # ifndef CLASSIC_NSPR USE_PTHREADS = 1 DEFINES += -D_THREAD_SAFE -D_REENTRANT OS_LIBS += -pthread DSO_LDOPTS += -pthread endif ARCH = freebsd MOZ_OBJFORMAT := $(shell test -x /usr/bin/objformat && /usr/bin/objformat || echo elf) ifeq ($(MOZ_OBJFORMAT),elf) DLL_SUFFIX = so else DLL_SUFFIX = so.1.0 endif MKSHLIB = $(CC) $(DSO_LDOPTS) ifdef MAPFILE MKSHLIB += -Wl,--version-script,$(MAPFILE) endif PROCESS_MAP_FILE = grep -v ';-' $< | \ sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ G++INCLUDES = -I/usr/include/g++ INCLUDES += -I/usr/X11R6/include jss-4.4.3/jss/coreconf/HP-UX.mk000066400000000000000000000031371326145000000161030ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Config stuff for HP-UX # include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = cc ifeq ($(OS_TEST),ia64) CPU_ARCH = ia64 CPU_TAG = _$(CPU_ARCH) ifneq ($(USE_64),1) 64BIT_TAG = _32 endif DLL_SUFFIX = so else CPU_ARCH = hppa DLL_SUFFIX = sl endif CC = cc CCC = CC ifndef NS_USE_GCC OS_CFLAGS += -Ae endif OS_CFLAGS += $(DSO_CFLAGS) -DHPUX -D$(CPU_ARCH) -D_HPUX_SOURCE -D_USE_BIG_FDS ifeq ($(DEFAULT_IMPL_STRATEGY),_PTH) USE_PTHREADS = 1 ifeq ($(CLASSIC_NSPR),1) USE_PTHREADS = IMPL_STRATEGY = _CLASSIC endif ifeq ($(PTHREADS_USER),1) USE_PTHREADS = IMPL_STRATEGY = _PTH_USER endif endif ifdef PTHREADS_USER OS_CFLAGS += -D_POSIX_C_SOURCE=199506L endif LDFLAGS = -z -Wl,+s ifdef NS_USE_GCC LD = $(CC) endif MKSHLIB = $(LD) $(DSO_LDOPTS) $(RPATH) ifdef MAPFILE ifndef NS_USE_GCC MKSHLIB += -c $(MAPFILE) else MKSHLIB += -Wl,-c,$(MAPFILE) endif endif PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \ sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,+e ,' > $@ ifndef NS_USE_GCC DSO_LDOPTS = -b +h $(notdir $@) RPATH = +b '$$ORIGIN' else DSO_LDOPTS = -shared -Wl,+h,$(notdir $@) RPATH = -Wl,+b,'$$ORIGIN' endif ifneq ($(OS_TEST),ia64) # pa-risc ifndef USE_64 RPATH = endif endif # +Z generates position independent code for use in shared libraries. ifndef NS_USE_GCC DSO_CFLAGS = +Z else DSO_CFLAGS = -fPIC ASFLAGS += -x assembler-with-cpp endif jss-4.4.3/jss/coreconf/HP-UXA.09.03.mk000066400000000000000000000006651326145000000166570ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # On HP-UX 9, the default (and only) implementation strategy is # classic nspr. # ifeq ($(OS_RELEASE),A.09.03) DEFAULT_IMPL_STRATEGY = _CLASSIC endif # # Config stuff for HP-UXA.09.03 # include $(CORE_DEPTH)/coreconf/HP-UXA.09.mk jss-4.4.3/jss/coreconf/HP-UXA.09.07.mk000066400000000000000000000006621326145000000166600ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 9, the default (and only) implementation strategy is # classic nspr. ifeq ($(OS_RELEASE),A.09.07) DEFAULT_IMPL_STRATEGY = _CLASSIC endif # # Config stuff for HP-UXA.09.07 # include $(CORE_DEPTH)/coreconf/HP-UXA.09.mk jss-4.4.3/jss/coreconf/HP-UXA.09.mk000066400000000000000000000004511326145000000164270ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Config stuff for HP-UXA.09 # include $(CORE_DEPTH)/coreconf/HP-UX.mk OS_CFLAGS += -DHPUX9 jss-4.4.3/jss/coreconf/HP-UXB.10.01.mk000066400000000000000000000005401326145000000166360ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ifeq ($(OS_RELEASE),B.10.01) DEFAULT_IMPL_STRATEGY = _CLASSIC endif # # Config stuff for HP-UXB.10.01 # include $(CORE_DEPTH)/coreconf/HP-UXB.10.mk jss-4.4.3/jss/coreconf/HP-UXB.10.10.mk000066400000000000000000000010731326145000000166400ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.10 and 10.20, the default implementation strategy is # pthreads (actually DCE threads). Classic nspr is also available. ifeq ($(OS_RELEASE),B.10.10) DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.10.10 # include $(CORE_DEPTH)/coreconf/HP-UXB.10.mk OS_CFLAGS += -DHPUX10_10 ifeq ($(USE_PTHREADS),1) OS_CFLAGS += -D_REENTRANT endif jss-4.4.3/jss/coreconf/HP-UXB.10.20.mk000066400000000000000000000010721326145000000166400ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.10 and 10.20, the default implementation strategy is # pthreads (actually DCE threads). Classic nspr is also available. ifeq ($(OS_RELEASE),B.10.20) DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.10.20 # include $(CORE_DEPTH)/coreconf/HP-UXB.10.mk OS_CFLAGS += -DHPUX10_20 ifeq ($(USE_PTHREADS),1) OS_CFLAGS += -D_REENTRANT endif jss-4.4.3/jss/coreconf/HP-UXB.10.30.mk000066400000000000000000000013421326145000000166410ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.30 and 11.00, the default implementation strategy is # pthreads. Classic nspr and pthreads-user are also available. ifeq ($(OS_RELEASE),B.10.30) DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.10.30. # include $(CORE_DEPTH)/coreconf/HP-UXB.10.mk OS_CFLAGS += -DHPUX10_30 # # To use the true pthread (kernel thread) library on 10.30 and # 11.00, we should define _POSIX_C_SOURCE to be 199506L. # The _REENTRANT macro is deprecated. # ifdef USE_PTHREADS OS_CFLAGS += -D_POSIX_C_SOURCE=199506L endif jss-4.4.3/jss/coreconf/HP-UXB.10.mk000066400000000000000000000004431326145000000164210ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/HP-UX.mk OS_CFLAGS += -DHPUX10 OS_LIBS += -lpthread -lm jss-4.4.3/jss/coreconf/HP-UXB.11.00.mk000066400000000000000000000007671326145000000166510ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.30 and 11.00, the default implementation strategy is # pthreads. Classic nspr and pthreads-user are also available. ifeq ($(OS_RELEASE),B.11.00) OS_CFLAGS += -DHPUX10 DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.11.00. # include $(CORE_DEPTH)/coreconf/HP-UXB.11.mk jss-4.4.3/jss/coreconf/HP-UXB.11.11.mk000066400000000000000000000007661326145000000166520ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.30 and 11.x, the default implementation strategy is # pthreads. Classic nspr and pthreads-user are also available. ifeq ($(OS_RELEASE),B.11.11) OS_CFLAGS += -DHPUX10 DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.11.11. # include $(CORE_DEPTH)/coreconf/HP-UXB.11.mk jss-4.4.3/jss/coreconf/HP-UXB.11.20.mk000066400000000000000000000007651326145000000166510ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.30 and 11.x, the default implementation strategy is # pthreads. Classic nspr and pthreads-user are also available. ifeq ($(OS_RELEASE),B.11.20) OS_CFLAGS += -DHPUX10 DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.11.x. # include $(CORE_DEPTH)/coreconf/HP-UXB.11.mk jss-4.4.3/jss/coreconf/HP-UXB.11.22.mk000066400000000000000000000007651326145000000166530ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.30 and 11.x, the default implementation strategy is # pthreads. Classic nspr and pthreads-user are also available. ifeq ($(OS_RELEASE),B.11.22) OS_CFLAGS += -DHPUX10 DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.11.x. # include $(CORE_DEPTH)/coreconf/HP-UXB.11.mk jss-4.4.3/jss/coreconf/HP-UXB.11.23.mk000066400000000000000000000007651326145000000166540ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On HP-UX 10.30 and 11.x, the default implementation strategy is # pthreads. Classic nspr and pthreads-user are also available. ifeq ($(OS_RELEASE),B.11.23) OS_CFLAGS += -DHPUX10 DEFAULT_IMPL_STRATEGY = _PTH endif # # Config stuff for HP-UXB.11.x. # include $(CORE_DEPTH)/coreconf/HP-UXB.11.mk jss-4.4.3/jss/coreconf/HP-UXB.11.mk000066400000000000000000000026361326145000000164300ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/HP-UX.mk ifndef NS_USE_GCC CCC = /opt/aCC/bin/aCC -ext ifeq ($(USE_64), 1) ifeq ($(OS_TEST), ia64) ARCHFLAG = -Aa +e +p +DD64 else # Our HP-UX build machine has a strange problem. If # a 64-bit PA-RISC executable calls getcwd() in a # network-mounted directory, it fails with ENOENT. # We don't know why. Since nsinstall calls getcwd(), # this breaks our 64-bit HP-UX nightly builds. None # of our other HP-UX machines have this problem. # # We worked around this problem by building nsinstall # as a 32-bit PA-RISC executable for 64-bit PA-RISC # builds. -- wtc 2003-06-03 ifdef INTERNAL_TOOLS ARCHFLAG = +DAportable +DS2.0 else ARCHFLAG = -Aa +e +DA2.0W +DS2.0 +DChpux endif endif else ifeq ($(OS_TEST), ia64) ARCHFLAG = -Aa +e +p +DD32 else ARCHFLAG = +DAportable +DS2.0 endif endif else CCC = aCC endif # # To use the true pthread (kernel thread) library on HP-UX # 11.x, we should define _POSIX_C_SOURCE to be 199506L. # The _REENTRANT macro is deprecated. # OS_CFLAGS += $(ARCHFLAG) -DHPUX11 -D_POSIX_C_SOURCE=199506L OS_LIBS += -lpthread -lm -lrt HPUX11 = 1 jss-4.4.3/jss/coreconf/IRIX.mk000066400000000000000000000040651326145000000160160ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk # # The default implementation strategy for Irix is classic nspr. # ifeq ($(USE_PTHREADS),1) ifeq ($(USE_N32),1) IMPL_STRATEGY = _n32_PTH else IMPL_STRATEGY = _PTH endif endif DEFAULT_COMPILER = cc ifdef NS_USE_GCC CC = gcc AS = $(CC) -x assembler-with-cpp ODD_CFLAGS = -Wall -Wno-format -Wno-switch ifdef BUILD_OPT OPTIMIZER = -O6 endif else CC = cc CCC = CC ODD_CFLAGS = -fullwarn -xansi -woff 1209 ifdef BUILD_OPT ifeq ($(USE_N32),1) OPTIMIZER = -O -OPT:Olimit=4000 else OPTIMIZER = -O -Olimit 4000 endif endif # For 6.x machines, include this flag ifeq (6., $(findstring 6., $(OS_RELEASE))) ifeq ($(USE_N32),1) ODD_CFLAGS += -n32 -mips3 -exceptions else ODD_CFLAGS += -32 -multigot endif else ODD_CFLAGS += -xgot endif ifeq ($(USE_N32),1) OS_CFLAGS += -dollar endif endif ODD_CFLAGS += -DSVR4 -DIRIX CPU_ARCH = mips RANLIB = /bin/true # For purify # NOTE: should always define _SGI_MP_SOURCE NOMD_OS_CFLAGS += $(ODD_CFLAGS) -D_SGI_MP_SOURCE OS_CFLAGS += $(NOMD_OS_CFLAGS) ifdef USE_MDUPDATE OS_CFLAGS += -MDupdate $(DEPENDENCIES) endif ifeq ($(USE_N32),1) SHLIB_LD_OPTS += -n32 -mips3 endif MKSHLIB += $(LD) $(SHLIB_LD_OPTS) -shared -soname $(@:$(OBJDIR)/%.so=%.so) ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ DSO_LDOPTS = -elf -shared -all ifdef DSO_BACKEND DSO_LDOPTS += -soname $(DSO_NAME) endif # # Revision notes: # # In the IRIX compilers prior to version 7.2, -n32 implied -mips3. # Beginning in the 7.2 compilers, -n32 implies -mips4 when the compiler # is running on a system with a mips4 CPU (e.g. R8K, R10K). # We want our code to explicitly be mips3 code, so we now explicitly # set -mips3 whenever we set -n32. # jss-4.4.3/jss/coreconf/IRIX5.2.mk000066400000000000000000000003611326145000000162360ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/IRIX5.mk jss-4.4.3/jss/coreconf/IRIX5.3.mk000066400000000000000000000004111326145000000162330ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/IRIX5.mk OS_CFLAGS += -DIRIX5_3 jss-4.4.3/jss/coreconf/IRIX5.mk000066400000000000000000000004371326145000000161020ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/IRIX.mk ifndef NS_USE_GCC ODD_CFLAGS += -xgot endif jss-4.4.3/jss/coreconf/IRIX6.2.mk000066400000000000000000000005101326145000000162330ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # catch unresolved symbols SHLIB_LD_OPTS += -no_unresolved include $(CORE_DEPTH)/coreconf/IRIX6.mk OS_CFLAGS += -DIRIX6_2 jss-4.4.3/jss/coreconf/IRIX6.3.mk000066400000000000000000000005071326145000000162420ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # catch unresolved symbols SHLIB_LD_OPTS += -no_unresolved include $(CORE_DEPTH)/coreconf/IRIX6.mk OS_CFLAGS += -DIRIX6_3 jss-4.4.3/jss/coreconf/IRIX6.5.mk000066400000000000000000000005631326145000000162460ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # catch unresolved symbols SHLIB_LD_OPTS += -no_unresolved include $(CORE_DEPTH)/coreconf/IRIX6.mk OS_CFLAGS += -DIRIX6_5 ifndef NS_USE_GCC OS_CFLAGS += -mips3 endif jss-4.4.3/jss/coreconf/IRIX6.mk000066400000000000000000000006101326145000000160740ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/IRIX.mk ifndef NS_USE_GCC ifneq ($(USE_N32),1) OS_CFLAGS += -32 endif ODD_CFLAGS += -multigot endif ifeq ($(USE_PTHREADS),1) OS_LIBS += -lpthread endif jss-4.4.3/jss/coreconf/Linux.mk000066400000000000000000000116731326145000000163450ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk # # The default implementation strategy for Linux is now pthreads # ifneq ($(OS_TARGET),Android) USE_PTHREADS = 1 endif ifeq ($(USE_PTHREADS),1) IMPL_STRATEGY = _PTH endif CC = gcc CCC = g++ RANLIB = ranlib DEFAULT_COMPILER = gcc ifeq ($(OS_TARGET),Android) ifndef ANDROID_NDK $(error Must set ANDROID_NDK to the path to the android NDK first) endif ANDROID_PREFIX=$(OS_TEST)-linux-androideabi ANDROID_TARGET=$(ANDROID_PREFIX)-4.4.3 # should autodetect which linux we are on, currently android only # supports linux-x86 prebuilts ANDROID_TOOLCHAIN=$(ANDROID_NDK)/toolchains/$(ANDROID_TARGET)/prebuilt/linux-x86 ANDROID_SYSROOT=$(ANDROID_NDK)/platforms/android-$(OS_TARGET_RELEASE)/arch-$(OS_TEST) ANDROID_CC=$(ANDROID_TOOLCHAIN)/bin/$(ANDROID_PREFIX)-gcc # internal tools need to be built with the native compiler ifndef INTERNAL_TOOLS CC = $(ANDROID_CC) --sysroot=$(ANDROID_SYSROOT) DEFAULT_COMPILER=$(ANDROID_PREFIX)-gcc ARCHFLAG = --sysroot=$(ANDROID_SYSROOT) DEFINES += -DNO_SYSINFO -DNO_FORK_CHECK -DANDROID CROSS_COMPILE = 1 endif endif ifeq ($(OS_TEST),ppc64) CPU_ARCH = ppc ifeq ($(USE_64),1) ARCHFLAG = -m64 endif else ifeq ($(OS_TEST),alpha) OS_REL_CFLAGS = -D_ALPHA_ CPU_ARCH = alpha else ifeq ($(OS_TEST),x86_64) ifeq ($(USE_64),1) CPU_ARCH = x86_64 else OS_REL_CFLAGS = -Di386 CPU_ARCH = x86 ARCHFLAG = -m32 endif else ifeq ($(OS_TEST),sparc64) CPU_ARCH = sparc else ifeq (,$(filter-out arm% sa110,$(OS_TEST))) CPU_ARCH = arm else ifeq (,$(filter-out parisc%,$(OS_TEST))) CPU_ARCH = hppa else ifeq (,$(filter-out i%86,$(OS_TEST))) OS_REL_CFLAGS = -Di386 CPU_ARCH = x86 else ifeq ($(OS_TEST),sh4a) CPU_ARCH = sh4 else # $(OS_TEST) == m68k, ppc, ia64, sparc, s390, s390x, mips, sh3, sh4 CPU_ARCH = $(OS_TEST) endif endif endif endif endif endif endif endif ifneq ($(OS_TARGET),Android) LIBC_TAG = _glibc endif ifeq ($(OS_RELEASE),2.0) OS_REL_CFLAGS += -DLINUX2_0 MKSHLIB = $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) $(RPATH) ifdef MAPFILE MKSHLIB += -Wl,--version-script,$(MAPFILE) endif PROCESS_MAP_FILE = grep -v ';-' $< | \ sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ endif ifdef BUILD_OPT ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE)) OPTIMIZER = -Os else OPTIMIZER = -O2 endif ifdef MOZ_DEBUG_SYMBOLS ifdef MOZ_DEBUG_FLAGS OPTIMIZER += $(MOZ_DEBUG_FLAGS) else OPTIMIZER += -gdwarf-2 endif endif endif ifeq ($(USE_PTHREADS),1) OS_PTHREAD = -lpthread endif # See bug 537829, in particular comment 23. # Place -ansi and *_SOURCE before $(DSO_CFLAGS) so DSO_CFLAGS can override # -ansi on platforms like Android where the system headers are C99 and do # not build with -ansi. STANDARDS_CFLAGS = -D_POSIX_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE OS_CFLAGS = $(STANDARDS_CFLAGS) $(DSO_CFLAGS) $(OS_REL_CFLAGS) $(ARCHFLAG) -Wall -Werror-implicit-function-declaration -Wno-switch -pipe -DLINUX -Dlinux -DHAVE_STRERROR OS_LIBS = $(OS_PTHREAD) -ldl -lc ifdef USE_PTHREADS DEFINES += -D_REENTRANT endif ARCH = linux DSO_CFLAGS = -fPIC DSO_LDOPTS = $(LDFLAGS) -shared $(ARCHFLAG) # The linker on Red Hat Linux 7.2 and RHEL 2.1 (GNU ld version 2.11.90.0.8) # incorrectly reports undefined references in the libraries we link with, so # we don't use -z defs there. ZDEFS_FLAG = -Wl,-z,defs DSO_LDOPTS += $(if $(findstring 2.11.90.0.8,$(shell ld -v)),,$(ZDEFS_FLAG)) LDFLAGS += $(ARCHFLAG) # On Maemo, we need to use the -rpath-link flag for even the standard system # library directories. ifdef _SBOX_DIR LDFLAGS += -Wl,-rpath-link,/usr/lib:/lib endif # INCLUDES += -I/usr/include -Y/usr/include/linux G++INCLUDES = -I/usr/include/g++ # # Always set CPU_TAG on Linux. # CPU_TAG = _$(CPU_ARCH) # # On Linux 2.6 or later, build libfreebl3.so with no NSPR and libnssutil3.so # dependencies by default. Set FREEBL_NO_DEPEND to 0 in the environment to # override this. # ifneq ($(OS_TARGET),Android) ifeq (2.6,$(firstword $(sort 2.6 $(OS_RELEASE)))) ifndef FREEBL_NO_DEPEND FREEBL_NO_DEPEND = 1 FREEBL_LOWHASH = 1 endif endif endif USE_SYSTEM_ZLIB = 1 ZLIB_LIBS = -lz # The -rpath '$$ORIGIN' linker option instructs this library to search for its # dependencies in the same directory where it resides. ifeq ($(BUILD_SUN_PKG), 1) ifeq ($(USE_64), 1) RPATH = -Wl,-rpath,'$$ORIGIN:/opt/sun/private/lib64:/opt/sun/private/lib' else RPATH = -Wl,-rpath,'$$ORIGIN:/opt/sun/private/lib' endif endif OS_REL_CFLAGS += -DLINUX2_1 MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) $(RPATH) ifdef MAPFILE MKSHLIB += -Wl,--version-script,$(MAPFILE) endif PROCESS_MAP_FILE = grep -v ';-' $< | \ sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ ifeq ($(OS_RELEASE),2.4) DEFINES += -DNO_FORK_CHECK endif jss-4.4.3/jss/coreconf/Makefile000066400000000000000000000005431326145000000163470ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DEPTH = .. CORE_DEPTH = .. MODULE = coreconf DIRS = nsinstall include $(DEPTH)/coreconf/config.mk include $(DEPTH)/coreconf/rules.mk export:: libs jss-4.4.3/jss/coreconf/NCR3.0.mk000066400000000000000000000027201326145000000161020ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = cc ### NS_USE_NATIVE = 1 # NS_USE_GCC = 1 export PATH:=$(PATH):/opt/ncc/bin ### RANLIB = true GCC_FLAGS_EXTRA += -pipe DEFINES += -DSVR4 -DSYSV -DHAVE_STRERROR -DNCR OS_CFLAGS += -Hnocopyr -DSVR4 -DSYSV -DHAVE_STRERROR -DNCR -DPRFSTREAMS_BROKEN ifdef NS_USE_NATIVE CC = cc CCC = ncc CXX = ncc # OS_LIBS += -L/opt/ncc/lib else # OS_LIBS += endif #OS_LIBS += -lsocket -lnsl -ldl -lc MKSHLIB += $(LD) $(DSO_LDOPTS) #DSO_LDOPTS += -G -z defs DSO_LDOPTS += -G ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ CPU_ARCH = x86 ARCH = ncr NOSUCHFILE = /solaris-rm-f-sucks # now take care of default GCC (rus@5/5/97) ifdef NS_USE_GCC # if gcc-settings are redefined already - don't touch it # ifeq (,$(findstring gcc, $(CC))) CC = gcc CCC = g++ CXX = g++ # always use -fPIC - some makefiles are still broken and don't distinguish # situation when they build shared and static libraries CFLAGS += -fPIC -Wall -Wno-switch $(GCC_FLAGS_EXTRA) # OS_LIBS += -L/usr/local/lib -lstdc++ -lg++ -lgcc endif endif ### jss-4.4.3/jss/coreconf/NEC4.2.mk000066400000000000000000000016001326145000000160640ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = $(CORE_DEPTH)/build/hcc CPU_ARCH = mips ifdef NS_USE_GCC CC = gcc CCC = g++ else CC = $(CORE_DEPTH)/build/hcc OS_CFLAGS = -Xa -KGnum=0 -KOlimit=4000 CCC = g++ endif MKSHLIB = $(LD) $(DSO_LDOPTS) ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ RANLIB = /bin/true OS_CFLAGS += $(ODD_CFLAGS) -DSVR4 -D__SVR4 -DNEC -Dnec_ews -DHAVE_STRERROR OS_LIBS = -lsocket -lnsl -ldl $(LDOPTIONS) LDOPTIONS = -lc -L/usr/ucblib -lucb NOSUCHFILE = /nec-rm-f-sucks DSO_LDOPTS = -G jss-4.4.3/jss/coreconf/NetBSD.mk000066400000000000000000000024261326145000000163210ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = gcc CC = gcc CCC = g++ RANLIB = ranlib CPU_ARCH := $(shell uname -p) ifeq ($(CPU_ARCH),i386) OS_REL_CFLAGS = -Di386 CPU_ARCH = x86 endif ifndef OBJECT_FMT OBJECT_FMT := $(shell if echo __ELF__ | $${CC:-cc} -E - | grep -q __ELF__ ; then echo a.out ; else echo ELF ; fi) endif ifeq ($(OBJECT_FMT),ELF) DLL_SUFFIX = so else DLL_SUFFIX = so.1.0 endif OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -Wno-switch -pipe -DNETBSD -Dunix -DHAVE_STRERROR -DHAVE_BSD_FLOCK OS_LIBS = -lcompat ARCH = netbsd DSO_CFLAGS = -fPIC -DPIC DSO_LDOPTS = -shared ifeq ($(OBJECT_FMT),ELF) DSO_LDOPTS += -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) endif ifdef LIBRUNPATH DSO_LDOPTS += -Wl,-R$(LIBRUNPATH) endif MKSHLIB = $(CC) $(DSO_LDOPTS) ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ G++INCLUDES = -I/usr/include/g++ INCLUDES += -I/usr/X11R6/include jss-4.4.3/jss/coreconf/OS2.mk000066400000000000000000000111601326145000000156400ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. MOZ_WIDGET_TOOLKIT = os2 # XP_PC is for Window and OS2 on Intel X86 # XP_OS2 is strictly for OS2 only XP_DEFINE += -DXP_PC=1 -DXP_OS2=1 # Override prefix LIB_PREFIX = $(NULL) # Override suffix in suffix.mk LIB_SUFFIX = lib # the DLL_SUFFIX must be uppercase for FIPS mode to work. bugzilla 240784 DLL_SUFFIX = DLL PROG_SUFFIX = .exe CCC = gcc LINK = gcc AR = emxomfar r $@ # Keep AR_FLAGS blank so that we do not have to change rules.mk AR_FLAGS = RANLIB = @echo OS2 RANLIB BSDECHO = @echo OS2 BSDECHO IMPLIB = emximp -o FILTER = emxexp -o # GCC for OS/2 currently predefines these, but we don't want them DEFINES += -Uunix -U__unix -U__unix__ DEFINES += -DTCPV40HDRS ifeq ($(MOZ_OS2_HIGH_MEMORY),1) HIGHMEM_LDFLAG = -Zhigh-mem endif ifndef NO_SHARED_LIB WRAP_MALLOC_LIB = WRAP_MALLOC_CFLAGS = DSO_CFLAGS = DSO_PIC_CFLAGS = MKSHLIB = $(CXX) $(CXXFLAGS) $(DSO_LDOPTS) -o $@ MKCSHLIB = $(CC) $(CFLAGS) $(DSO_LDOPTS) -o $@ MKSHLIB_FORCE_ALL = MKSHLIB_UNFORCE_ALL = DSO_LDOPTS = -Zomf -Zdll -Zmap $(HIGHMEM_LDFLAG) SHLIB_LDSTARTFILE = SHLIB_LDENDFILE = ifdef MAPFILE MKSHLIB += $(MAPFILE) endif PROCESS_MAP_FILE = \ echo LIBRARY $(LIBRARY_NAME)$(LIBRARY_VERSION) INITINSTANCE TERMINSTANCE > $@; \ echo PROTMODE >> $@; \ echo CODE LOADONCALL MOVEABLE DISCARDABLE >> $@; \ echo DATA PRELOAD MOVEABLE MULTIPLE NONSHARED >> $@; \ echo EXPORTS >> $@; \ grep -v ';+' $< | grep -v ';-' | \ sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,\([\t ]*\),\1_,' | \ awk 'BEGIN {ord=1;} { print($$0 " @" ord " RESIDENTNAME"); ord++;}' >> $@ endif #NO_SHARED_LIB OS_CFLAGS = -Wall -Wno-unused -Wpointer-arith -Wcast-align -Wno-switch -Zomf -DDEBUG -DTRACING -g ifdef BUILD_OPT ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE)) OPTIMIZER += -Os -s else OPTIMIZER += -O2 -s endif DEFINES += -UDEBUG -U_DEBUG -DNDEBUG DLLFLAGS = -DLL -OUT:$@ -MAP:$(@:.dll=.map) $(HIGHMEM_LDFLAG) EXEFLAGS = -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE $(HIGHMEM_LDFLAG) OBJDIR_TAG = _OPT else #OPTIMIZER = -O+ -Oi DEFINES += -DDEBUG -D_DEBUG -DDEBUGPRINTS #HCT Need += to avoid overidding manifest.mn DLLFLAGS = -DEBUG -DLL -OUT:$@ -MAP:$(@:.dll=.map) $(HIGHMEM_LDFLAG) EXEFLAGS = -DEBUG -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE $(HIGHMEM_LDFLAG) OBJDIR_TAG = _DBG LDFLAGS = -DEBUG $(HIGHMEM_LDFLAG) endif # BUILD_OPT # OS/2 use nsinstall that is included in the toolkit. # since we do not wish to support and maintain 3 version of nsinstall in mozilla, nspr and nss ifdef BUILD_TREE NSINSTALL_DIR = $(BUILD_TREE)/nss else NSINSTALL_DIR = $(CORE_DEPTH)/coreconf/nsinstall endif # NSINSTALL = $(NSINSTALL_DIR)/$(OBJDIR_NAME)/nsinstall NSINSTALL = nsinstall # HCT4OS2 INSTALL = $(NSINSTALL) MKDEPEND_DIR = $(CORE_DEPTH)/coreconf/mkdepend MKDEPEND = $(MKDEPEND_DIR)/$(OBJDIR_NAME)/mkdepend MKDEPENDENCIES = $(OBJDIR_NAME)/depend.mk #################################################################### # # One can define the makefile variable NSDISTMODE to control # how files are published to the 'dist' directory. If not # defined, the default is "install using relative symbolic # links". The two possible values are "copy", which copies files # but preserves source mtime, and "absolute_symlink", which # installs using absolute symbolic links. # - THIS IS NOT PART OF THE NEW BINARY RELEASE PLAN for 9/30/97 # - WE'RE KEEPING IT ONLY FOR BACKWARDS COMPATIBILITY #################################################################### ifeq ($(NSDISTMODE),copy) # copy files, but preserve source mtime INSTALL = $(NSINSTALL) INSTALL += -t else ifeq ($(NSDISTMODE),absolute_symlink) # install using absolute symbolic links INSTALL = $(NSINSTALL) INSTALL += -L `pwd` else # install using relative symbolic links INSTALL = $(NSINSTALL) INSTALL += -R endif endif define MAKE_OBJDIR if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi endef # # override the definition of DLL_PREFIX in prefix.mk # ifndef DLL_PREFIX DLL_PREFIX = $(NULL) endif # # override the TARGETS defined in ruleset.mk, adding IMPORT_LIBRARY # ifndef TARGETS TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(PROGRAM) endif ifdef LIBRARY_NAME IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)$(JDK_DEBUG_SUFFIX).lib endif jss-4.4.3/jss/coreconf/OSF1.mk000066400000000000000000000022741326145000000157530ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # The Bourne shell (sh) on OSF1 doesn't handle "set -e" correctly, # which we use to stop LOOP_OVER_DIRS submakes as soon as any # submake fails. So we use the Korn shell instead. # SHELL = /usr/bin/ksh include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = cc CC = cc OS_CFLAGS += $(NON_LD_FLAGS) -std1 CCC = cxx RANLIB = /bin/true CPU_ARCH = alpha ifdef BUILD_OPT OPTIMIZER += -Olimit 4000 endif NON_LD_FLAGS += -ieee_with_inexact OS_CFLAGS += -DOSF1 -D_REENTRANT ifeq ($(USE_PTHREADS),1) OS_CFLAGS += -pthread endif # The command to build a shared library on OSF1. MKSHLIB += ld -shared -expect_unresolved "*" -soname $(notdir $@) ifdef MAPFILE MKSHLIB += -hidden -input $(MAPFILE) endif PROCESS_MAP_FILE = grep -v ';+' $< | grep -v ';-' | \ sed -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,,' -e 's,^,-exported_symbol ,' > $@ DSO_LDOPTS += -shared # required for freebl USE_64=1 # this platform name does not use a bit tag due to only having a 64-bit ABI 64BIT_TAG= jss-4.4.3/jss/coreconf/OSF1V2.0.mk000066400000000000000000000003601326145000000163130ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/OSF1.mk jss-4.4.3/jss/coreconf/OSF1V3.0.mk000066400000000000000000000003601326145000000163140ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/OSF1.mk jss-4.4.3/jss/coreconf/OSF1V3.2.mk000066400000000000000000000006421326145000000163210ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On OSF1 V3.2, classic nspr is the default (and only) implementation # strategy. # # Config stuff for DEC OSF/1 V3.2 # include $(CORE_DEPTH)/coreconf/OSF1.mk ifeq ($(OS_RELEASE),V3.2) OS_CFLAGS += -DOSF1V3 endif jss-4.4.3/jss/coreconf/OSF1V4.0.mk000066400000000000000000000010661326145000000163210ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On OSF1 V4.0, pthreads is the default implementation strategy. # Classic nspr is also available. ifneq ($(OS_RELEASE),V3.2) USE_PTHREADS = 1 ifeq ($(CLASSIC_NSPR), 1) USE_PTHREADS = IMPL_STRATEGY := _CLASSIC endif endif # # Config stuff for DEC OSF/1 V4.0 # include $(CORE_DEPTH)/coreconf/OSF1.mk ifeq ($(OS_RELEASE),V4.0) OS_CFLAGS += -DOSF1V4 endif jss-4.4.3/jss/coreconf/OSF1V4.0B.mk000066400000000000000000000003641326145000000164230ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/OSF1V4.0.mk jss-4.4.3/jss/coreconf/OSF1V4.0D.mk000066400000000000000000000004451326145000000164250ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/OSF1V4.0.mk DEFINES += -DOSF1V4D OS_LIBS += -lpthread -lrt jss-4.4.3/jss/coreconf/OSF1V5.0.mk000066400000000000000000000007761326145000000163310ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On OSF1 V5.0, pthreads is the default implementation strategy. # Classic nspr is also available. ifneq ($(OS_RELEASE),V3.2) USE_PTHREADS = 1 ifeq ($(CLASSIC_NSPR), 1) USE_PTHREADS = IMPL_STRATEGY := _CLASSIC endif endif # # Config stuff for DEC OSF/1 V5.0 # include $(CORE_DEPTH)/coreconf/OSF1.mk jss-4.4.3/jss/coreconf/OSF1V5.1.mk000066400000000000000000000007761326145000000163320ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # On OSF1 V5.0, pthreads is the default implementation strategy. # Classic nspr is also available. ifneq ($(OS_RELEASE),V3.2) USE_PTHREADS = 1 ifeq ($(CLASSIC_NSPR), 1) USE_PTHREADS = IMPL_STRATEGY := _CLASSIC endif endif # # Config stuff for DEC OSF/1 V5.1 # include $(CORE_DEPTH)/coreconf/OSF1.mk jss-4.4.3/jss/coreconf/OpenBSD.mk000066400000000000000000000015441326145000000164740ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk CC ?= gcc CXX ?= g++ DEFAULT_COMPILER = ${CC} CCC = ${CXX} RANLIB = ranlib CPU_ARCH := $(shell arch -s) ifeq ($(CPU_ARCH),i386) OS_REL_CFLAGS = -Di386 CPU_ARCH = x86 endif ifndef CLASSIC_NSPR USE_PTHREADS = 1 DEFINES += -pthread OS_LIBS += -pthread DSO_LDOPTS += -pthread endif DLL_SUFFIX = so.1.0 OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -ansi -Wall -Wno-switch -pipe -DOPENBSD OS_LIBS = ARCH = openbsd DSO_CFLAGS = -fPIC -DPIC DSO_LDOPTS = -shared -fPIC -Wl,-soname,lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX) MKSHLIB = $(CC) $(DSO_LDOPTS) USE_SYSTEM_ZLIB = 1 ZLIB_LIBS = -lz jss-4.4.3/jss/coreconf/OpenUNIX.mk000066400000000000000000000032031326145000000166410ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = gcc CC = gcc OS_CFLAGS += -fPIC CCC = g++ CCC += -DPRFSTREAMS_BROKEN -I/usr/gnu/lib/g++-include # CCC = $(CORE_DEPTH)/build/hcpp # CCC += +.cpp +w RANLIB = /bin/true # # -DSCO_PM - Policy Manager AKA: SCO Licensing # -DSCO - Changes to Netscape source (consistent with AIX, LINUX, etc..) # -Dsco - Needed for /usr/include/X11/* # OS_CFLAGS += -DSCO_SV -DSYSV -D_SVID3 -DHAVE_STRERROR -DSW_THREADS -DSCO_PM -DSCO -Dsco #OS_LIBS += -lpmapi -lsocket -lc MKSHLIB = $(LD) MKSHLIB += $(DSO_LDOPTS) XINC = /usr/include/X11 MOTIFLIB += -lXm INCLUDES += -I$(XINC) CPU_ARCH = x86 GFX_ARCH = x ARCH = sco LOCALE_MAP = $(CORE_DEPTH)/cmd/xfe/intl/sco.lm EN_LOCALE = C DE_LOCALE = de_DE.ISO8859-1 FR_LOCALE = fr_FR.ISO8859-1 JP_LOCALE = ja SJIS_LOCALE = ja_JP.SJIS KR_LOCALE = ko_KR.EUC CN_LOCALE = zh TW_LOCALE = zh I2_LOCALE = i2 LOC_LIB_DIR = /usr/lib/X11 NOSUCHFILE = /solaris-rm-f-sucks BSDECHO = /bin/echo ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ # # These defines are for building unix plugins # BUILD_UNIX_PLUGINS = 1 #DSO_LDOPTS += -b elf -G -z defs DSO_LDOPTS += -G # Used for Java compiler EXPORT_FLAGS += -W l,-Bexport jss-4.4.3/jss/coreconf/QNX.mk000066400000000000000000000014601326145000000157050ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk USE_PTHREADS = 1 ifeq ($(USE_PTHREADS),1) IMPL_STRATEGY = _PTH endif CC = qcc CCC = qcc RANLIB = ranlib DEFAULT_COMPILER = qcc ifeq ($(OS_TEST),mips) CPU_ARCH = mips else CPU_ARCH = x86 endif MKSHLIB = $(CC) -shared -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) ifdef BUILD_OPT OPTIMIZER = -O2 endif OS_CFLAGS = $(DSO_CFLAGS) $(OS_REL_CFLAGS) -Vgcc_ntox86 -Wall -pipe -DNTO -DHAVE_STRERROR -D_QNX_SOURCE -D_POSIX_C_SOURCE=199506 -D_XOPEN_SOURCE=500 ifdef USE_PTHREADS DEFINES += -D_REENTRANT endif ARCH = QNX DSO_CFLAGS = -Wc,-fPIC DSO_LDOPTS = -shared jss-4.4.3/jss/coreconf/README000066400000000000000000000617001326145000000155710ustar00rootroot00000000000000OVERVIEW of "ns/coreconf": This README file is an attempt to provide the reader with a simple synopsis of the "ns/coreconf" build system which was originally fundamentally designed and built to accomodate Netscape's binary release model. Wherever possible, an attempt has been made to comply with the NSPR 2.0 build system, including mimicing the compiler/linker flags, and directory naming structure. The reader should keep in mind that the system builds binary releases of header files, class files, libraries, and executables on numerous flavors of UNIX and Windows operating systems. Unfortunately, no serious attempt has ever been made to incorporate an ability to generate cross-platform binaries on an Apple MacIntosh platform. Note that this file will not attempt to redefine or document the architecture of this system. However, documents on this subject are available at the following URL: http://warp/hardcore/prj-ttools/specs/release/index.html DEPENDENCIES of "ns/coreconf": The "ns/coreconf" build system requires the specified versions of the following platform-dependent tools: UNIX Platforms: -------------- gmake (version 3.74 or later) perl 4.0 (NOTE: perl 5.003 or later recommended) uname Windows Platforms: ----------------- gmake 3.74 (must use hacked Netscape version) shmsdos.exe (contained in Netscape gmake.exe) nsinstall.exe (contained in Netscape gmake.exe) perl.exe (version 4.0 for everything except testing; NOTE: MKS toolkit perl 5.002 is broken) perl5.exe (for testing; NOTE: perl 5.003 or later recommended; MKS toolkit perl 5.002 is broken) uname.exe (use nstools version) ENHANCEMENTS to "ns/coreconf": With the advent of Certificate Server 4.0 using the ns/coreconf build system, several changes had to be made to enhance ns/coreconf support for building Java/JNI classes/programs, as well as libraries slated to be released as binaries. While the following may not represent an exhaustive list of these changes, it does attempt to be at least somewhat comprehensive: (1) During the course of these enhancements, a total of four files have been modified, and four new files have been added. The following files have been modified: - command.mk: removed old definition of JAR - config.mk: added include statement of new "jdk.mk" file - ruleset.mk: allowed the $(MKPROG) variable to be overridden by supplying it with a default value of $(CC); augmented numerous definitions to enhance ability of ns/coreconf to produce a more robust set of libraries; added some JNI definitions; PACKAGE definition may be overridden by new "jdk.mk" file - rules.mk: separated the compile phase of a program from the link phase of a program such that a developer can now strictly override program linkage by simply supplying a $(MKPROG) variable; augmented NETLIBDEPTH to use CORE_DEPTH but retain backward compatibility; added JNI section; modified .PRECIOUS rule; The following files have been added: - README: this file; an ASCII-based text document used to summarize the ns/coreconf build system and suitable (paginated) for printing - jdk.mk: a file comprising most (if not all) of the default Java related build information; the definitions in this file are only included if NS_USE_JDK has been defined - jniregen.pl: a perl script used to create a dependency for when JNI files should be regenerated (based upon any change to the ".class" file from which the ".h" file was originally generated) - outofdate.pl: a perl script used to create a dependency for when ".class" files should be regenerated (based upon any change to the ".java" file from which the ".class" file was originally generated) (2) As stated above, the ns/coreconf build system now separates the link phase of a program from its compilation phase. While ns/coreconf still works exactly as it used to because the $(MKPROG) variable is assigned $(CC) by default, a developer may now override this behavior by simply supplying their own unique value for $(MKPROG) on every platform. This allows a program compiled with $(CC) to link with external libraries that may contain "C++" linkage. Before this change, a programmer would need to reference their own local copy of rules.mk (see the ns/sectools/cmd/pk12util program for an example of how this used to be accomplished). (3) Currently, the ns/coreconf build system differs from the NSPR 2.0 build system which utilizes an "_s" to denote static libraries from import libraries. In fact, the ns/coreconf build system adds no prefixes or suffixes to distinguish one version of static libraries from another. Note that both the ns/coreconf build system as well as the NSPR 2.0 build system do nothing to provide a method of distinguishing 16-bit from 32-bit static libraries on the same machine, either, since: a) this might only provide difficulty during development, since static libraries always need to be embedded within a program (note this is highly unlikely, since libraries for different platforms are subdivided via a well-known subdirectory structure, and a developer may use multiple trees for development), b) this maintains backwards compatibility, something very important since no legacy programs will need to change their link phase, and c) Netscape as a company has dropped any plans of future development of 16-bit products. (4) Since several members of the Hardcore Security group did not favor NSPR 2.0's solution of adding an "_s" to static libraries on Windows platforms as a method to distinguish them from their import library cousins, a different solution was proposed and has been recently implemented for ns/coreconf: - a 16 has been added as a suffix to both dynamic and import libraries built on 16-bit Windows platforms - a 32 has been added as a suffix to both dynamic and import libraries built on 32-bit Windows platforms Since the HCL release process currently only contains a single instance of building a dynamic library, ns/security/lib/fortcrypt/fort12.dll, the impact of this change should be relatively small. (Note: HCL was the old name of NSS.) It should be noted that although this would additionally limit the 8.3 namespace on 16-bit platforms, it is highly unlikely that any future development will be performed on this platform. (5) The $(LIBRARY_VERSION) tag has been added to all non-static libraries created on UNIX operating systems to alleviate any future confusion for binary releases which utilize this tag. Again, it should be noted that this tag is only utilized on non-static libraries, since more than one version of the library may need to exist simultaneously if multiple products are utilized. Currently, only one HCL released library utilizes this tag: ns/security/lib/fortcrypt/fort12.a (e. g. - in this library, the tag has been set to '12') Again, it should be noted that although this would additionally limit the 8.3 namespace on 16-bit platforms, it is highly unlikely that any future development will be performed on this platform. (6) The $(JDK_DEBUG_SUFFIX) extension has been added to all library and program names to support debug versions of Java programs (e. g. - java_g, javac_g, etc). Once again, it should be noted that although this would additionally limit the 8.3 namespace on 16-bit platforms, it is highly unlikely that any future Java development will be performed on this platform. (7) Most (if not all) default definitions for java have been encapsulated within their own file, jdk.mk, which is always included by default in ns/coreconf/config.mk. However, the definitions within this file are only ever activated if NS_USE_JDK has been set to be 1. (8) Two perl scripts (jniregen.pl and outofdate.pl) have been added to the system to foster a more robust development environment for composing Java and JNI programs utilizing the ns/coreconf build system. Both of these perl scripts are related to resolving dependencies which can not be accomplished through normal makefile dependencies. (9) This file, README, was created in an attempt to allow developers who have familiarity with ns/coreconf a simple roadmap for what has changed, as well as a top-level view of what comprises ns/coreconf. This file was written in ASCII (rather than HTML) primarily to promote simple paginated printing. OVERVIEW of "config.mk": This file contains the configuration information necessary to build each "Core Components" source module: include file name Purpose =================== ======================================= arch.mk source and release tags command.mk default command macros (NOTE: may be overridden in $(OS_CONFIG).mk) $(OS_CONFIG).mk -specific macros (dependent upon tags) tree.mk release tags (dependent upon tags) module.mk source and release tags (NOTE: A component is also called a module or a subsystem. This file is dependent upon $(MODULE) being defined on the command line, as an environment variable, or in individual makefiles, or more appropriately, manifest.mn) version.mk release tags (dependent upon $(MODULE) being defined on the command line, as an environment variable, or in individual makefiles, or more appropriately, manifest.mn) location.mk macros to figure out binary code location (dependent upon tags) source.mk -specific source path (dependent upon , , , and tags) headers.mk include switch for support header files (dependent upon , , , and tags) prefix.mk compute program prefixes suffix.mk compute program suffixes (dependent upon tags) jdk.mk define JDK (dependent upon , , and tags) ruleset.mk Master "Core Components" rule set (should always be the last file included by config.mk) OVERVIEW of "rules.mk": The "rules.mk" file consists of four sections. The first section contains the "master" build rules for all binary releases. While this section can (and should) largely be thought of as "language" independent, it does utilize the "perl" scripting language to perform both the "import" and "release" of binary modules. The rules which dwell in this section and their purpose: CATEGORY/rule:: Purpose =================== ======================================= GENERAL ------- all:: "default" all-encompassing rule which performs "export libs program install" export:: recursively copy specified cross-platform header files to the $(SOURCE_XPHEADERS_DIR) directory; recursively copy specified machine-dependent header files to the $(SOURCE_MDHEADERS_DIR) directory; although all rules can be written to repetively "chain" into other sections, this rule is the most commonly used rule to "chain" into other sections such as Java providing a simple mechanism which allows no need for developers to memorize specialized rules libs:: recursively build static (archival) $(LIBRARY), shared (dynamic link) $(SHARED_LIBRARY), and/or import $(IMPORT_LIBRARY) libraries program:: recursively build $(PROGRAM) executable install:: recursively copy all libraries to $(SOURCE_LIB_DIR) directory; recursively copy all executables to $(SOURCE_BIN_DIR) directory clean:: remove all files specified in the $(ALL_TRASH) variable clobber:: synonym for "clean::" rule realclean:: remove all files specified by $(wildcard *.OBJ), dist, and in the $(ALL_TRASH) variable clobber_all:: synonym for "realclean::" rule private_export:: recursively copy specified cross-platform header files to the $(SOURCE_XPPRIVATE_DIR) directory IMPORT ------ import:: uses perl script to retrieve specified VERSION of the binary release from $(RELEASE_TREE) RELEASE ------- release_clean:: remove all files from the $(SOURCE_RELEASE_PREFIX) directory release:: place specified VERSION of the binary release in the appropriate $(RELEASE_TREE) directory release_export:: recursively copy specified cross-platform header files to the $(SOURCE_XPHEADERS_DIR)/include directory release_md:: recursively copy all libraries to $(SOURCE_RELEASE_PREFIX)/ $(SOURCE_RELEASE_LIB_DIR) directory; recursively copy all executables to $(SOURCE_RELEASE_PREFIX)/ $(SOURCE_RELEASE_BIN_DIR) directory release_jars:: use perl script to package appropriate files in the $(XPCLASS_JAR), $(XPHEADER_JAR), $(MDHEADER_JAR), and $(MDBINARY_JAR) jar files release_cpdistdir:: use perl script to copy the $(XPCLASS_JAR), $(XPHEADER_JAR), $(MDHEADER_JAR), and $(MDBINARY_JAR) jar files to the specified VERSION of the $(RELEASE_TREE) directory TOOLS and AUTOMATION -------------------- platform:: tool used to display the platform name as composed within the "arch.mk" file autobuild:: automation rule used by "Bonsai" and "Tinderbox" to automatically generate binary releases on various platforms tests:: automation tool used to run the "regress" and "reporter" tools on various regression test suites The second section of "rules.mk" primarily contains several "language" dependent build rules for binary releases. These are generally "computed" rules (created on the "fly"), and include rules used by "C", "C++", assembly, the preprocessor, perl, and the shell. The rules which dwell in this section and their purpose: CATEGORY/rule:: Purpose =================== ============================= LIBRARIES --------- $(LIBRARY): build the static library specified by the $(LIBRARY) variable $(IMPORT_LIBRARY): build the import library specified by the $(IMPORT_LIBRARY) variable $(SHARED_LIBRARY): build the shared (dynamic link) library specified by the $(SHARED_LIBRARY) variable PROGRAMS -------- $(PROGRAM): build the binary executable specified by the $(PROGRAM) rule $(OBJDIR)/ $(PROG_PREFIX)%.pure: build the "purified" binary executable specified by this rule OBJECTS ------- $(OBJDIR)/ $(PROG_PREFIX)%$(OBJ_SUFFIX): build the object file associated with the makefile rule dependency: %.c = C file %.cpp = C++ file %.cc = C++ file %.s = assembly file %.S = assembly file $(OBJDIR)/ $(PROG_PREFIX)%: (NOTE: deprecated rule) build the object file associated with the makefile rule dependency: %.cpp = C++ file MISCELLANEOUS ------------- %.i: build the preprocessor file associated with the makefile rule dependency: %.c = C file %.cpp = C++ file %: process the specified file using the method associated with the makefile rule dependency: %.pl = perl script %.sh = shell script alltags: tool used to recursively create a "ctags"-style file for reference The third section of "rules.mk' primarily contains several JAVA "language" build rules for binary releases. These are also generally "computed" rules (created on the "fly"). The rules which dwell in this section and their purpose: CATEGORY/rule:: Purpose =================== ============================= $(JAVA_DESTPATH):: create directory specified as the Java destination path for where classes are deposited $(JAVA_DESTPATH)/$(PACKAGE):: create directories specified within the $(PACKAGE) variable $(JMCSRCDIR):: create directory specified as the JMC destination path $(JRI_HEADER_CFILES): used to generate/regenerate JRI header files for "C" $(JRI_STUB_CFILES): used to generate/regenerate JRI stub files for "C" $(JNI_HEADERS): used to generate/regenerate JNI header files for "C" The fourth section of "rules.mk" primarily contains miscellaneous build rules for binary releases. Many of these rules are here to create new subdirectories, manage dependencies, and/or override standard gmake "Makefile" rules. The rules which dwell in this section and their purpose: CATEGORY/rule:: Purpose =================== ============================= $(PUBLIC_EXPORT_DIR):: create directory used to house public "C" header files $(PRIVATE_EXPORT_DIR):: create directory used to house private "C" header files $(SOURCE_XP_DIR)/ release/include:: create directory used to house "C" header files contained in a release $(MKDEPENDENCIES):: for UNIX systems, create a directory used to house dependencies and utilize the $(MKDEPEND) rule to create them $(MKDEPEND):: cd to the dependency directory and create them depend:: if $(OBJS) exist, perform the $(MKDEPEND) rule followed by the $(MKDEPENDENCIES) rule dependclean:: remove all files contained in the dependency repository .DEFAULT: standard gmake rule .SUFFIXES: standard gmake rule .PRECIOUS: standard gmake rule .PHONY: standard gmake rule jss-4.4.3/jss/coreconf/RISCOS.mk000066400000000000000000000010161326145000000162360ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk LIB_SUFFIX = a DLL_SUFFIX = so AR = ar cr $@ LDOPTS += -L$(SOURCE_LIB_DIR) MKSHLIB = $(CC) $(DSO_LDOPTS) -Wl,-soname -Wl,$(@:$(OBJDIR)/%.so=%.so) OS_RELEASE = OS_TARGET = RISCOS DSO_CFLAGS = -fPIC DSO_LDOPTS = -shared ifdef BUILD_OPT OPTIMIZER = -O3 endif jss-4.4.3/jss/coreconf/ReliantUNIX.mk000066400000000000000000000026731326145000000173500ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = cc ifdef NS_USE_GCC ## gcc-2.7.2 homebrewn CC = gcc CCC = g++ AS = $(CC) ASFLAGS += -x assembler-with-cpp LD = gld ODD_CFLAGS = -pipe -Wall -Wno-format -Wno-switch ifdef BUILD_OPT OPTIMIZER += -O6 endif MKSHLIB = $(LD) MKSHLIB += -G -h $(@:$(OBJDIR)/%.so=%.so) DSO_LDOPTS += -G -Xlinker -Blargedynsym else ## native compiler (CDS++ 1.0) # CC = /usr/bin/cc CC = cc CCC = /usr/bin/CC AS = /usr/bin/cc ODD_CFLAGS = ifdef BUILD_OPT OPTIMIZER += -O -F Olimit,4000 endif MKSHLIB = $(CC) MKSHLIB += -G -h $(@:$(OBJDIR)/%.so=%.so) DSO_LDOPTS += -G -W l,-Blargedynsym endif ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ NOSUCHFILE = /sni-rm-f-sucks ODD_CFLAGS += -DSVR4 -DSNI -DRELIANTUNIX CPU_ARCH = mips RANLIB = /bin/true # For purify NOMD_OS_CFLAGS += $(ODD_CFLAGS) # we do not have -MDupdate ... OS_CFLAGS += $(NOMD_OS_CFLAGS) OS_LIBS += -lsocket -lnsl -lresolv -lgen -ldl -lc /usr/ucblib/libucb.a ifdef DSO_BACKEND DSO_LDOPTS += -h $(DSO_NAME) endif jss-4.4.3/jss/coreconf/ReliantUNIX5.4.mk000066400000000000000000000003671326145000000175750ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/ReliantUNIX.mk jss-4.4.3/jss/coreconf/SCOOS5.0.mk000066400000000000000000000003661326145000000163540ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/SCO_SV3.2.mk jss-4.4.3/jss/coreconf/SCO_SV3.2.mk000066400000000000000000000032301326145000000165130ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = cc CC = cc OS_CFLAGS += -b elf -KPIC CCC = g++ CCC += -b elf -DPRFSTREAMS_BROKEN -I/usr/local/lib/g++-include # CCC = $(CORE_DEPTH)/build/hcpp # CCC += +.cpp +w RANLIB = /bin/true # # -DSCO_PM - Policy Manager AKA: SCO Licensing # -DSCO - Changes to Netscape source (consistent with AIX, LINUX, etc..) # -Dsco - Needed for /usr/include/X11/* # OS_CFLAGS += -DSCO_SV -DSYSV -D_SVID3 -DHAVE_STRERROR -DSW_THREADS -DSCO_PM -DSCO -Dsco #OS_LIBS += -lpmapi -lsocket -lc MKSHLIB = $(LD) MKSHLIB += $(DSO_LDOPTS) XINC = /usr/include/X11 MOTIFLIB += -lXm INCLUDES += -I$(XINC) CPU_ARCH = x86 GFX_ARCH = x ARCH = sco LOCALE_MAP = $(CORE_DEPTH)/cmd/xfe/intl/sco.lm EN_LOCALE = C DE_LOCALE = de_DE.ISO8859-1 FR_LOCALE = fr_FR.ISO8859-1 JP_LOCALE = ja SJIS_LOCALE = ja_JP.SJIS KR_LOCALE = ko_KR.EUC CN_LOCALE = zh TW_LOCALE = zh I2_LOCALE = i2 LOC_LIB_DIR = /usr/lib/X11 NOSUCHFILE = /solaris-rm-f-sucks BSDECHO = /bin/echo ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ # # These defines are for building unix plugins # BUILD_UNIX_PLUGINS = 1 #DSO_LDOPTS += -b elf -G -z defs DSO_LDOPTS += -b elf -G # Used for Java compiler EXPORT_FLAGS += -W l,-Bexport jss-4.4.3/jss/coreconf/SunOS4.1.3_U1.mk000066400000000000000000000016221326145000000171770ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = cc INCLUDES += -I/usr/dt/include -I/usr/openwin/include -I/home/motif/usr/include # SunOS 4 _requires_ that shared libs have a version number. # XXX FIXME: Version number should use NSPR_VERSION_NUMBER? DLL_SUFFIX = so.1.0 CC = gcc RANLIB = ranlib CPU_ARCH = sparc # Purify doesn't like -MDupdate NOMD_OS_CFLAGS += -Wall -Wno-format -Wno-switch -DSUNOS4 OS_CFLAGS += $(DSO_CFLAGS) $(NOMD_OS_CFLAGS) -MDupdate $(DEPENDENCIES) MKSHLIB = $(LD) MKSHLIB += $(DSO_LDOPTS) NOSUCHFILE = /solaris-rm-f-sucks DSO_LDOPTS = # -fPIC generates position-independent code for use in a shared library. DSO_CFLAGS += -fPIC jss-4.4.3/jss/coreconf/SunOS5.mk000066400000000000000000000063741326145000000163440ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. include $(CORE_DEPTH)/coreconf/UNIX.mk # Sun's WorkShop defines v8, v8plus and v9 architectures. # gcc on Solaris defines v8 and v9 "cpus". # gcc's v9 is equivalent to Workshop's v8plus. # gcc's -m64 is equivalent to Workshop's v9 ifeq ($(USE_64), 1) ifdef NS_USE_GCC ARCHFLAG=-m64 else ifeq ($(OS_TEST),i86pc) ARCHFLAG=-xarch=amd64 else ARCHFLAG=-xarch=v9 endif endif else ifneq ($(OS_TEST),i86pc) ifdef NS_USE_GCC ARCHFLAG=-mcpu=v9 else ARCHFLAG=-xarch=v8plus endif endif endif DEFAULT_COMPILER = cc ifdef NS_USE_GCC CC = gcc OS_CFLAGS += -Wall -Wno-format -Werror-implicit-function-declaration -Wno-switch CCC = g++ CCC += -Wall -Wno-format ASFLAGS += -x assembler-with-cpp OS_CFLAGS += $(NOMD_OS_CFLAGS) $(ARCHFLAG) ifdef USE_MDUPDATE OS_CFLAGS += -MDupdate $(DEPENDENCIES) endif ifdef BUILD_OPT OPTIMIZER = -O2 # Enable this for accurate dtrace profiling # OPTIMIZER += -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer endif else CC = cc CCC = CC ASFLAGS += -Wa,-P OS_CFLAGS += $(NOMD_OS_CFLAGS) $(ARCHFLAG) ifndef BUILD_OPT OS_CFLAGS += -xs else OPTIMIZER = -xO4 endif ifdef USE_TCOV CC += -xprofile=tcov CCC += -xprofile=tcov endif endif RANLIB = echo CPU_ARCH = sparc OS_DEFINES += -DSVR4 -DSYSV -D__svr4 -D__svr4__ -DSOLARIS -D_REENTRANT ifeq ($(OS_TEST),i86pc) ifeq ($(USE_64),1) CPU_ARCH = x86_64 else CPU_ARCH = x86 OS_DEFINES += -Di386 endif endif # Purify doesn't like -MDupdate NOMD_OS_CFLAGS += $(DSO_CFLAGS) $(OS_DEFINES) $(SOL_CFLAGS) MKSHLIB = $(CC) $(DSO_LDOPTS) $(RPATH) ifdef NS_USE_GCC ifeq (GNU,$(findstring GNU,$(shell `$(CC) -print-prog-name=ld` -v 2>&1))) GCC_USE_GNU_LD = 1 endif endif ifdef MAPFILE ifdef NS_USE_GCC ifdef GCC_USE_GNU_LD MKSHLIB += -Wl,--version-script,$(MAPFILE) else MKSHLIB += -Wl,-M,$(MAPFILE) endif else MKSHLIB += -M $(MAPFILE) endif endif PROCESS_MAP_FILE = grep -v ';-' $< | \ sed -e 's,;+,,' -e 's; DATA ;;' -e 's,;;,,' -e 's,;.*,;,' > $@ # ld options: # -G: produce a shared object # -z defs: no unresolved symbols allowed ifdef NS_USE_GCC ifeq ($(USE_64), 1) DSO_LDOPTS += -m64 endif DSO_LDOPTS += -shared -h $(notdir $@) else ifeq ($(USE_64), 1) ifeq ($(OS_TEST),i86pc) DSO_LDOPTS +=-xarch=amd64 else DSO_LDOPTS +=-xarch=v9 endif endif DSO_LDOPTS += -G -h $(notdir $@) endif DSO_LDOPTS += -z combreloc -z defs -z ignore # -KPIC generates position independent code for use in shared libraries. # (Similarly for -fPIC in case of gcc.) ifdef NS_USE_GCC DSO_CFLAGS += -fPIC else DSO_CFLAGS += -KPIC endif NOSUCHFILE = /solaris-rm-f-sucks ifeq ($(BUILD_SUN_PKG), 1) # The -R '$ORIGIN' linker option instructs this library to search for its # dependencies in the same directory where it resides. ifeq ($(USE_64), 1) RPATH = -R '$$ORIGIN:/usr/lib/mps/secv1/64:/usr/lib/mps/64' else RPATH = -R '$$ORIGIN:/usr/lib/mps/secv1:/usr/lib/mps' endif else RPATH = -R '$$ORIGIN' endif OS_LIBS += -lthread -lnsl -lsocket -lposix4 -ldl -lc jss-4.4.3/jss/coreconf/UNIX.mk000066400000000000000000000036371326145000000160320ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. XP_DEFINE += -DXP_UNIX LIB_SUFFIX = a DLL_SUFFIX = so AR = ar cr $@ LDOPTS += -L$(SOURCE_LIB_DIR) ifdef BUILD_OPT OPTIMIZER += -O DEFINES += -UDEBUG -DNDEBUG else OPTIMIZER += -g USERNAME := $(shell whoami) USERNAME := $(subst -,_,$(USERNAME)) DEFINES += -DDEBUG -UNDEBUG -DDEBUG_$(USERNAME) endif ifdef BUILD_TREE NSINSTALL_DIR = $(BUILD_TREE)/nss NSINSTALL = $(BUILD_TREE)/nss/nsinstall else NSINSTALL_DIR = $(CORE_DEPTH)/coreconf/nsinstall NSINSTALL = $(NSINSTALL_DIR)/$(OBJDIR_NAME)/nsinstall endif MKDEPEND_DIR = $(CORE_DEPTH)/coreconf/mkdepend MKDEPEND = $(MKDEPEND_DIR)/$(OBJDIR_NAME)/mkdepend MKDEPENDENCIES = $(OBJDIR_NAME)/depend.mk #################################################################### # # One can define the makefile variable NSDISTMODE to control # how files are published to the 'dist' directory. If not # defined, the default is "install using relative symbolic # links". The two possible values are "copy", which copies files # but preserves source mtime, and "absolute_symlink", which # installs using absolute symbolic links. # - THIS IS NOT PART OF THE NEW BINARY RELEASE PLAN for 9/30/97 # - WE'RE KEEPING IT ONLY FOR BACKWARDS COMPATIBILITY #################################################################### ifeq ($(NSDISTMODE),copy) # copy files, but preserve source mtime INSTALL = $(NSINSTALL) INSTALL += -t else ifeq ($(NSDISTMODE),absolute_symlink) # install using absolute symbolic links INSTALL = $(NSINSTALL) INSTALL += -L `pwd` else # install using relative symbolic links INSTALL = $(NSINSTALL) INSTALL += -R endif endif define MAKE_OBJDIR if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi endef jss-4.4.3/jss/coreconf/UNIXWARE2.1.mk000066400000000000000000000014361326145000000167250ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Config stuff for SCO Unixware 2.1 # include $(CORE_DEPTH)/coreconf/UNIX.mk DEFAULT_COMPILER = $(CORE_DEPTH)/build/hcc CC = $(CORE_DEPTH)/build/hcc CCC = $(CORE_DEPTH)/build/hcpp RANLIB = true OS_CFLAGS = -KPIC -DSVR4 -DSYSV -DUNIXWARE MKSHLIB = $(LD) MKSHLIB += $(DSO_LDOPTS) DSO_LDOPTS += -G CPU_ARCH = x86 ARCH = sco NOSUCHFILE = /solaris-rm-f-sucks ifdef MAPFILE # Add LD options to restrict exported symbols to those in the map file endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ jss-4.4.3/jss/coreconf/WIN32.mk000066400000000000000000000220521326145000000160410ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Configuration common to all versions of Windows NT # and Windows 95 # DEFAULT_COMPILER = cl ifdef NS_USE_GCC CC = gcc CCC = g++ LINK = ld AR = ar AR += cr $@ RANLIB = ranlib BSDECHO = echo RC = windres.exe -O coff --use-temp-file LINK_DLL = $(CC) $(OS_DLLFLAGS) $(DLLFLAGS) else CC = cl CCC = cl LINK = link AR = lib AR += -NOLOGO -OUT:"$@" RANLIB = echo BSDECHO = echo RC = rc.exe MT = mt.exe # Determine compiler version CC_VERSION := $(shell $(CC) 2>&1 | sed -ne \ 's|.* \([0-9]\+\.[0-9]\+\.[0-9]\+\(\.[0-9]\+\)\?\).*|\1|p') # Change the dots to spaces. _CC_VERSION_WORDS := $(subst ., ,$(CC_VERSION)) _CC_VMAJOR := $(word 1,$(_CC_VERSION_WORDS)) _CC_VMINOR := $(word 2,$(_CC_VERSION_WORDS)) _CC_RELEASE := $(word 3,$(_CC_VERSION_WORDS)) _CC_BUILD := $(word 4,$(_CC_VERSION_WORDS)) _MSC_VER = $(_CC_VMAJOR)$(_CC_VMINOR) _MSC_VER_6 = 1200 ifeq ($(_CC_VMAJOR),14) # -DYNAMICBASE is only supported on VC8SP1 or newer, # so be very specific here! # VC8 is 14.00.50727.42, VC8SP1 is 14.00.50727.762 ifeq ($(_CC_RELEASE).$(_CC_BUILD),50727.42) USE_DYNAMICBASE = else ifeq ($(_CC_RELEASE).$(_CC_BUILD),50727.762) USE_DYNAMICBASE = 1 else _LOSER := $(error Unknown compiler version $(CC_VERSION)) endif endif endif # if $(_CC_VMAJOR) >= 15 # NOTE: 'sort' sorts the words in lexical order, so this test works # only if $(_CC_VMAJOR) is two digits. ifeq ($(firstword $(sort $(_CC_VMAJOR) 15)),15) USE_DYNAMICBASE = 1 endif endif ifdef BUILD_TREE NSINSTALL_DIR = $(BUILD_TREE)/nss else NSINSTALL_DIR = $(CORE_DEPTH)/coreconf/nsinstall endif NSINSTALL = nsinstall MKDEPEND_DIR = $(CORE_DEPTH)/coreconf/mkdepend MKDEPEND = $(MKDEPEND_DIR)/$(OBJDIR_NAME)/mkdepend.exe # Note: MKDEPENDENCIES __MUST__ be a relative pathname, not absolute. # If it is absolute, gmake will crash unless the named file exists. MKDEPENDENCIES = $(OBJDIR_NAME)/depend.mk INSTALL = $(NSINSTALL) MAKE_OBJDIR = mkdir MAKE_OBJDIR += $(OBJDIR) GARBAGE += $(OBJDIR)/vc20.pdb $(OBJDIR)/vc40.pdb XP_DEFINE += -DXP_PC ifdef NS_USE_GCC LIB_SUFFIX = a else LIB_SUFFIX = lib endif DLL_SUFFIX = dll ifdef NS_USE_GCC # The -mnop-fun-dllimport flag allows us to avoid a drawback of # the dllimport attribute that a pointer to a function marked as # dllimport cannot be used as as a constant address. OS_CFLAGS += -mwindows -mms-bitfields -mnop-fun-dllimport _GEN_IMPORT_LIB=-Wl,--out-implib,$(IMPORT_LIBRARY) DLLFLAGS += -mwindows -o $@ -shared -Wl,--export-all-symbols $(if $(IMPORT_LIBRARY),$(_GEN_IMPORT_LIB)) ifdef BUILD_OPT ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE)) OPTIMIZER += -Os else OPTIMIZER += -O2 endif DEFINES += -UDEBUG -U_DEBUG -DNDEBUG else OPTIMIZER += -g NULLSTRING := SPACE := $(NULLSTRING) # end of the line USERNAME := $(subst $(SPACE),_,$(USERNAME)) USERNAME := $(subst -,_,$(USERNAME)) DEFINES += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME) endif else # !NS_USE_GCC OS_CFLAGS += -W3 -nologo -D_CRT_SECURE_NO_WARNINGS \ -D_CRT_NONSTDC_NO_WARNINGS OS_DLLFLAGS += -nologo -DLL -SUBSYSTEM:WINDOWS ifeq ($(_MSC_VER),$(_MSC_VER_6)) ifndef MOZ_DEBUG_SYMBOLS OS_DLLFLAGS += -PDB:NONE endif endif ifdef USE_DYNAMICBASE OS_DLLFLAGS += -DYNAMICBASE endif ifdef BUILD_OPT OS_CFLAGS += -MD ifeq (11,$(ALLOW_OPT_CODE_SIZE)$(OPT_CODE_SIZE)) OPTIMIZER += -O1 else OPTIMIZER += -O2 endif DEFINES += -UDEBUG -U_DEBUG -DNDEBUG DLLFLAGS += -OUT:"$@" ifdef MOZ_DEBUG_SYMBOLS ifdef MOZ_DEBUG_FLAGS OPTIMIZER += $(MOZ_DEBUG_FLAGS) -Fd$(OBJDIR)/ else OPTIMIZER += -Zi -Fd$(OBJDIR)/ endif DLLFLAGS += -DEBUG -OPT:REF LDFLAGS += -DEBUG -OPT:REF endif else # # Define USE_DEBUG_RTL if you want to use the debug runtime library # (RTL) in the debug build # ifdef USE_DEBUG_RTL OS_CFLAGS += -MDd -D_CRTDBG_MAP_ALLOC else OS_CFLAGS += -MD endif OPTIMIZER += -Zi -Fd$(OBJDIR)/ -Od NULLSTRING := SPACE := $(NULLSTRING) # end of the line USERNAME := $(subst $(SPACE),_,$(USERNAME)) USERNAME := $(subst -,_,$(USERNAME)) DEFINES += -DDEBUG -D_DEBUG -UNDEBUG -DDEBUG_$(USERNAME) DLLFLAGS += -DEBUG -OUT:"$@" LDFLAGS += -DEBUG ifeq ($(_MSC_VER),$(_MSC_VER_6)) ifndef MOZ_DEBUG_SYMBOLS LDFLAGS += -PDB:NONE endif endif # Purify requires /FIXED:NO when linking EXEs. LDFLAGS += /FIXED:NO endif ifneq ($(_MSC_VER),$(_MSC_VER_6)) # Convert certain deadly warnings to errors (see list at end of file) OS_CFLAGS += -we4002 -we4003 -we4004 -we4006 -we4009 -we4013 \ -we4015 -we4028 -we4033 -we4035 -we4045 -we4047 -we4053 -we4054 -we4063 \ -we4064 -we4078 -we4087 -we4098 -we4390 -we4551 -we4553 -we4715 endif # !MSVC6 endif # NS_USE_GCC ifdef USE_64 DEFINES += -DWIN64 else DEFINES += -DWIN32 endif ifeq (,$(filter-out x386 x86_64,$(CPU_ARCH))) ifdef USE_64 DEFINES += -D_AMD64_ else DEFINES += -D_X86_ endif endif ifeq ($(CPU_ARCH), ALPHA) DEFINES += -D_ALPHA_=1 endif ifdef MAPFILE ifndef NS_USE_GCC DLLFLAGS += -DEF:$(MAPFILE) endif endif # Change PROCESS to put the mapfile in the correct format for this platform PROCESS_MAP_FILE = cp $< $@ # # The following is NOT needed for the NSPR 2.0 library. # DEFINES += -D_WINDOWS # override default, which is ASFLAGS = CFLAGS ifdef NS_USE_GCC AS = $(CC) ASFLAGS = $(INCLUDES) else ifdef USE_64 AS = ml64.exe ASFLAGS = -Cp -Sn -Zi $(INCLUDES) else AS = ml.exe ASFLAGS = -Cp -Sn -Zi -coff $(INCLUDES) endif endif # # override the definitions of RELEASE_TREE found in tree.mk # ifndef RELEASE_TREE ifdef BUILD_SHIP ifdef USE_SHIPS RELEASE_TREE = $(NTBUILD_SHIP) else RELEASE_TREE = //redbuild/components endif else RELEASE_TREE = //redbuild/components endif endif # # override the definitions of IMPORT_LIB_PREFIX, LIB_PREFIX, and # DLL_PREFIX in prefix.mk # ifndef IMPORT_LIB_PREFIX ifdef NS_USE_GCC IMPORT_LIB_PREFIX = lib else IMPORT_LIB_PREFIX = $(NULL) endif endif ifndef LIB_PREFIX ifdef NS_USE_GCC LIB_PREFIX = lib else LIB_PREFIX = $(NULL) endif endif ifndef DLL_PREFIX DLL_PREFIX = $(NULL) endif # # override the definitions of various _SUFFIX symbols in suffix.mk # # # Object suffixes # ifndef OBJ_SUFFIX ifdef NS_USE_GCC OBJ_SUFFIX = .o else OBJ_SUFFIX = .obj endif endif # # Assembler source suffixes # ifndef ASM_SUFFIX ifdef NS_USE_GCC ASM_SUFFIX = .s else ASM_SUFFIX = .asm endif endif # # Library suffixes # ifndef IMPORT_LIB_SUFFIX IMPORT_LIB_SUFFIX = .$(LIB_SUFFIX) endif ifndef DYNAMIC_LIB_SUFFIX_FOR_LINKING DYNAMIC_LIB_SUFFIX_FOR_LINKING = $(IMPORT_LIB_SUFFIX) endif # # Program suffixes # ifndef PROG_SUFFIX PROG_SUFFIX = .exe endif # # When the processor is NOT 386-based on Windows NT, override the # value of $(CPU_TAG). For WinNT, 95, 16, not CE. # ifneq ($(CPU_ARCH),x386) CPU_TAG = _$(CPU_ARCH) endif # # override ruleset.mk, removing the "lib" prefix for library names, and # adding the "32" after the LIBRARY_VERSION. # ifdef LIBRARY_NAME SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)32$(JDK_DEBUG_SUFFIX).dll IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)32$(JDK_DEBUG_SUFFIX).lib endif # # override the TARGETS defined in ruleset.mk, adding IMPORT_LIBRARY # ifndef TARGETS TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(PROGRAM) endif # list of MSVC warnings converted to errors above: # 4002: too many actual parameters for macro 'identifier' # 4003: not enough actual parameters for macro 'identifier' # 4004: incorrect construction after 'defined' # 4006: #undef expected an identifier # 4009: string too big; trailing characters truncated # 4015: 'identifier' : type of bit field must be integral # 4028: formal parameter different from declaration # 4033: 'function' must return a value # 4035: 'function' : no return value # 4045: 'identifier' : array bounds overflow # 4047: 'function' : 'type 1' differs in levels of indirection from 'type 2' # 4053: one void operand for '?:' # 4054: 'conversion' : from function pointer 'type1' to data pointer 'type2' # 4059: pascal string too big, length byte is length % 256 # 4063: case 'identifier' is not a valid value for switch of enum 'identifier' # 4064: switch of incomplete enum 'identifier' # 4078: case constant 'value' too big for the type of the switch expression # 4087: 'function' : declared with 'void' parameter list # 4098: 'function' : void function returning a value # 4390: ';' : empty controlled statement found; is this the intent? # 4541: RTTI train wreck # 4715: not all control paths return a value # 4013: function undefined; assuming extern returning int # 4553: '==' : operator has no effect; did you intend '='? # 4551: function call missing argument list jss-4.4.3/jss/coreconf/WIN95.mk000066400000000000000000000005661326145000000160600ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Config stuff for OS_TARGET=WIN95 # include $(CORE_DEPTH)/coreconf/WIN32.mk DEFINES += -DWIN95 # WINNT uses the lib prefix, Win95 doesn't NSPR31_LIB_PREFIX = $(NULL) jss-4.4.3/jss/coreconf/WINNT.mk000066400000000000000000000006631326145000000161420ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Config stuff for OS_TARGET=WINNT # include $(CORE_DEPTH)/coreconf/WIN32.mk DEFINES += -DWINNT # # Win NT needs -GT so that fibers can work # OS_CFLAGS += -GT # WINNT uses the lib prefix, Win95 doesn't NSPR31_LIB_PREFIX = lib jss-4.4.3/jss/coreconf/arch.mk000066400000000000000000000164311326145000000161600ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master "Core Components" macros for getting the OS architecture # # defines these symbols: # 64BIT_TAG # OS_ARCH (from uname -r) # OS_TEST (from uname -m) # OS_RELEASE (from uname -v and/or -r) # OS_TARGET User defined, or set to OS_ARCH # CPU_ARCH (from unmame -m or -p, ONLY on WINNT) # OS_CONFIG OS_TARGET + OS_RELEASE # OBJDIR_TAG # OBJDIR_NAME ####################################################################### # # Macros for getting the OS architecture # ifeq ($(USE_64), 1) 64BIT_TAG=_64 else 64BIT_TAG= endif OS_ARCH := $(subst /,_,$(shell uname -s)) # # Attempt to differentiate between sparc and x86 Solaris # OS_TEST := $(shell uname -m) ifeq ($(OS_TEST),i86pc) OS_RELEASE := $(shell uname -r)_$(OS_TEST) else OS_RELEASE := $(shell uname -r) endif # # Force the IRIX64 machines to use IRIX. # ifeq ($(OS_ARCH),IRIX64) OS_ARCH = IRIX endif # # Force the older BSD/OS versions to use the new arch name. # ifeq ($(OS_ARCH),BSD_386) OS_ARCH = BSD_OS endif # # Catch Deterim if SVR4 is NCR or UNIXWARE # ifeq ($(OS_ARCH),UNIX_SV) ifneq ($(findstring NCR, $(shell grep NCR /etc/bcheckrc | head -1 )),) OS_ARCH = NCR else # Make UnixWare something human readable OS_ARCH = UNIXWARE endif # Get the OS release number, not 4.2 OS_RELEASE := $(shell uname -v) endif ifeq ($(OS_ARCH),UNIX_System_V) OS_ARCH = NEC endif ifeq ($(OS_ARCH),AIX) OS_RELEASE := $(shell uname -v).$(shell uname -r) endif # # Distinguish between OSF1 V4.0B and V4.0D # ifeq ($(OS_ARCH)$(OS_RELEASE),OSF1V4.0) OS_VERSION := $(shell uname -v) ifeq ($(OS_VERSION),564) OS_RELEASE := V4.0B endif ifeq ($(OS_VERSION),878) OS_RELEASE := V4.0D endif endif # # SINIX changes name to ReliantUNIX with 5.43 # ifeq ($(OS_ARCH),ReliantUNIX-N) OS_ARCH = ReliantUNIX OS_RELEASE = 5.4 endif ifeq ($(OS_ARCH),SINIX-N) OS_ARCH = ReliantUNIX OS_RELEASE = 5.4 endif # # Handle FreeBSD 2.2-STABLE, Linux 2.0.30-osfmach3, and # IRIX 6.5-ALPHA-1289139620. # ifeq (,$(filter-out Linux FreeBSD IRIX,$(OS_ARCH))) OS_RELEASE := $(shell echo $(OS_RELEASE) | sed 's/-.*//') endif ifeq ($(OS_ARCH),Linux) OS_RELEASE := $(subst ., ,$(OS_RELEASE)) ifneq ($(words $(OS_RELEASE)),1) OS_RELEASE := $(word 1,$(OS_RELEASE)).$(word 2,$(OS_RELEASE)) endif endif # # For OS/2 # ifeq ($(OS_ARCH),OS_2) OS_ARCH = OS2 OS_RELEASE := $(shell uname -v) endif ####################################################################### # Master "Core Components" macros for getting the OS target # ####################################################################### # # Note: OS_TARGET should be specified on the command line for gmake. # When OS_TARGET=WIN95 is specified, then a Windows 95 target is built. # The difference between the Win95 target and the WinNT target is that # the WinNT target uses Windows NT specific features not available # in Windows 95. The Win95 target will run on Windows NT, but (supposedly) # at lesser performance (the Win95 target uses threads; the WinNT target # uses fibers). # # If OS_TARGET is not specified, it defaults to $(OS_ARCH), i.e., no # cross-compilation. # # # The following hack allows one to build on a WIN95 machine (as if # s/he were cross-compiling on a WINNT host for a WIN95 target). # It also accomodates for MKS's and Cygwin's uname.exe. # ifeq ($(OS_ARCH),WIN95) OS_ARCH = WINNT OS_TARGET = WIN95 endif ifeq ($(OS_ARCH),Windows_95) OS_ARCH = Windows_NT OS_TARGET = WIN95 endif ifeq ($(OS_ARCH),CYGWIN_95-4.0) OS_ARCH = CYGWIN_NT-4.0 OS_TARGET = WIN95 endif ifeq ($(OS_ARCH),CYGWIN_98-4.10) OS_ARCH = CYGWIN_NT-4.0 OS_TARGET = WIN95 endif ifeq ($(OS_ARCH),CYGWIN_ME-4.90) OS_ARCH = CYGWIN_NT-4.0 OS_TARGET = WIN95 endif # # On WIN32, we also define the variable CPU_ARCH, if it isn't already. # ifndef CPU_ARCH ifeq ($(OS_ARCH), WINNT) CPU_ARCH := $(shell uname -p) ifeq ($(CPU_ARCH),I386) CPU_ARCH = x386 endif endif endif # If uname -s returns "Windows_NT", we assume that we are using # the uname.exe in MKS toolkit. # # The -r option of MKS uname only returns the major version number. # So we need to use its -v option to get the minor version number. # Moreover, it doesn't have the -p option, so we need to use uname -m. # ifeq ($(OS_ARCH), Windows_NT) OS_ARCH = WINNT OS_MINOR_RELEASE := $(shell uname -v) # strip leading 0 OS_MINOR_RELEASE := $(patsubst 0%,%,$(OS_MINOR_RELEASE)) OS_RELEASE := $(OS_RELEASE).$(OS_MINOR_RELEASE) ifndef CPU_ARCH CPU_ARCH := $(shell uname -m) # # MKS's uname -m returns "586" on a Pentium machine. # ifneq (,$(findstring 86,$(CPU_ARCH))) CPU_ARCH = x386 endif endif endif # # If uname -s returns "CYGWIN_NT-4.0", we assume that we are using # the uname.exe in the Cygwin tools. # ifeq (CYGWIN_NT,$(findstring CYGWIN_NT,$(OS_ARCH))) OS_RELEASE := $(patsubst CYGWIN_NT-%,%,$(OS_ARCH)) OS_ARCH = WINNT ifndef CPU_ARCH ifeq (WOW64,$(findstring WOW64,$(OS_RELEASE))) OS_RELEASE := $(patsubst %-WOW64,%,$(OS_RELEASE)) endif CPU_ARCH := $(shell uname -m) # # Cygwin's uname -m returns "i686" on a Pentium Pro machine. # ifneq (,$(findstring 86,$(CPU_ARCH))) CPU_ARCH = x386 endif endif endif # # If uname -s returns "MINGW32_NT-5.1", we assume that we are using # the uname.exe in the MSYS toolkit. # ifeq (MINGW32_NT,$(findstring MINGW32_NT,$(OS_ARCH))) OS_RELEASE := $(patsubst MINGW32_NT-%,%,$(OS_ARCH)) OS_ARCH = WINNT USE_MSYS = 1 ifndef CPU_ARCH CPU_ARCH := $(shell uname -m) # # MSYS's uname -m returns "i686" on a Pentium Pro machine. # ifneq (,$(findstring 86,$(CPU_ARCH))) CPU_ARCH = x386 endif endif endif ifeq ($(OS_TARGET),Android) # # this should be configurable from the user # OS_TEST := arm OS_ARCH = Android ifndef OS_TARGET_RELEASE OS_TARGET_RELEASE := 8 endif endif ifndef OS_TARGET OS_TARGET = $(OS_ARCH) endif ifeq ($(OS_TARGET), WIN95) OS_RELEASE = 4.0 endif ifdef OS_TARGET_RELEASE OS_RELEASE = $(OS_TARGET_RELEASE) endif # # This variable is used to get OS_CONFIG.mk. # OS_CONFIG = $(OS_TARGET)$(OS_RELEASE) # # OBJDIR_TAG depends on the predefined variable BUILD_OPT, # to distinguish between debug and release builds. # ifdef BUILD_OPT OBJDIR_TAG = $(64BIT_TAG)_OPT else ifdef BUILD_IDG OBJDIR_TAG = $(64BIT_TAG)_IDG else OBJDIR_TAG = $(64BIT_TAG)_DBG endif endif # # The following flags are defined in the individual $(OS_CONFIG).mk # files. # # CPU_TAG is defined if the CPU is not the most common CPU. # COMPILER_TAG is defined if the compiler is not the default compiler. # IMPL_STRATEGY may be defined too. # OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(COMPILER_TAG)$(LIBC_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJ ifeq (,$(filter-out WIN%,$(OS_TARGET))) ifndef BUILD_OPT # # Define USE_DEBUG_RTL if you want to use the debug runtime library # (RTL) in the debug build # ifdef USE_DEBUG_RTL OBJDIR_NAME = $(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(COMPILER_TAG)$(IMPL_STRATEGY)$(OBJDIR_TAG).OBJD endif endif endif MK_ARCH = included jss-4.4.3/jss/coreconf/command.mk000066400000000000000000000025021326145000000166530ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master "Core Components" default command macros; # # can be overridden in .mk # ####################################################################### AS = $(CC) ASFLAGS += $(CFLAGS) CCF = $(CC) $(CFLAGS) LINK_DLL = $(LINK) $(OS_DLLFLAGS) $(DLLFLAGS) LINK_EXE = $(LINK) $(OS_LFLAGS) $(LFLAGS) CFLAGS = $(OPTIMIZER) $(OS_CFLAGS) $(XP_DEFINE) $(DEFINES) $(INCLUDES) \ $(XCFLAGS) PERL = perl RANLIB = echo TAR = /bin/tar # # For purify # NOMD_CFLAGS += $(OPTIMIZER) $(NOMD_OS_CFLAGS) $(XP_DEFINE) $(DEFINES) \ $(INCLUDES) $(XCFLAGS) # Optimization of code for size # OPT_CODE_SIZE # =1: The code can be optimized for size. # The code is actually optimized for size only if ALLOW_OPT_CODE_SIZE=1 # in a given source code directory (in manifest.mn) # =0: Never optimize the code for size. # # Default value = 0 # Can be overridden from the make command line. ifndef OPT_CODE_SIZE OPT_CODE_SIZE = 0 endif MK_COMMAND = included jss-4.4.3/jss/coreconf/config.mk000066400000000000000000000163731326145000000165150ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Configuration information for building in the "Core Components" source module ####################################################################### # [1.0] Master "Core Components" source and release # # tags # ####################################################################### ifndef MK_ARCH include $(CORE_DEPTH)/coreconf/arch.mk endif ####################################################################### # [2.0] Master "Core Components" default command macros # # (NOTE: may be overridden in $(OS_TARGET)$(OS_RELEASE).mk) # ####################################################################### ifndef MK_COMMAND include $(CORE_DEPTH)/coreconf/command.mk endif ####################################################################### # [3.0] Master "Core Components" -specific macros # # (dependent upon tags) # # # # We are moving towards just having a $(OS_TARGET).mk file # # as opposed to multiple $(OS_TARGET)$(OS_RELEASE).mk files, # # one for each OS release. # ####################################################################### TARGET_OSES = FreeBSD BSD_OS NetBSD OpenUNIX OS2 QNX Darwin BeOS OpenBSD \ AIX RISCOS WINNT WIN95 Linux Android ifeq (,$(filter-out $(TARGET_OSES),$(OS_TARGET))) include $(CORE_DEPTH)/coreconf/$(OS_TARGET).mk else ifeq ($(OS_TARGET),SunOS) include $(CORE_DEPTH)/coreconf/SunOS5.mk else include $(CORE_DEPTH)/coreconf/$(OS_TARGET)$(OS_RELEASE).mk endif endif ####################################################################### # [4.0] Master "Core Components" source and release tags # # (dependent upon tags) # ####################################################################### PLATFORM = $(OBJDIR_NAME) ####################################################################### # [5.0] Master "Core Components" release tags # # (dependent upon tags) # ####################################################################### ifndef MK_TREE include $(CORE_DEPTH)/coreconf/tree.mk endif ####################################################################### # [6.0] Master "Core Components" source and release tags # # NOTE: A component is also called a module or a subsystem. # # (dependent upon $(MODULE) being defined on the # # command line, as an environment variable, or in individual # # makefiles, or more appropriately, manifest.mn) # ####################################################################### ifndef MK_MODULE include $(CORE_DEPTH)/coreconf/module.mk endif ####################################################################### # [7.0] Master "Core Components" release tags # # (dependent upon $(MODULE) being defined on the # # command line, as an environment variable, or in individual # # makefiles, or more appropriately, manifest.mn) # ####################################################################### ifndef MK_VERSION include $(CORE_DEPTH)/coreconf/version.mk endif ####################################################################### # [8.0] Master "Core Components" macros to figure out # # binary code location # # (dependent upon tags) # ####################################################################### ifndef MK_LOCATION include $(CORE_DEPTH)/coreconf/location.mk endif ####################################################################### # [9.0] Master "Core Components" -specific source path # # (dependent upon , , # # , and tags) # ####################################################################### ifndef MK_SOURCE include $(CORE_DEPTH)/coreconf/source.mk endif ####################################################################### # [10.0] Master "Core Components" include switch for support header # # files # # (dependent upon , , , # # and tags) # ####################################################################### ifndef MK_HEADERS include $(CORE_DEPTH)/coreconf/headers.mk endif ####################################################################### # [11.0] Master "Core Components" for computing program prefixes # ####################################################################### ifndef MK_PREFIX include $(CORE_DEPTH)/coreconf/prefix.mk endif ####################################################################### # [12.0] Master "Core Components" for computing program suffixes # # (dependent upon tags) # ####################################################################### ifndef MK_SUFFIX include $(CORE_DEPTH)/coreconf/suffix.mk endif ####################################################################### # [13.0] Master "Core Components" for defining JDK # # (dependent upon , , and tags)# ####################################################################### ifdef NS_USE_JDK include $(CORE_DEPTH)/coreconf/jdk.mk endif ####################################################################### # [14.0] Master "Core Components" rule set # ####################################################################### ifndef MK_RULESET include $(CORE_DEPTH)/coreconf/ruleset.mk endif ####################################################################### # [15.0] Dependencies. ####################################################################### -include $(MKDEPENDENCIES) ####################################################################### # [16.0] Global environ ment defines ####################################################################### ifdef NSS_ENABLE_ECC DEFINES += -DNSS_ENABLE_ECC endif ifdef NSS_ECC_MORE_THAN_SUITE_B DEFINES += -DNSS_ECC_MORE_THAN_SUITE_B endif ifdef NSS_ALLOW_UNSUPPORTED_CRITICAL DEFINES += -DNSS_ALLOW_UNSUPPORTED_CRITICAL endif ifdef BUILD_LIBPKIX_TESTS DEFINES += -DBUILD_LIBPKIX_TESTS endif ifdef NSS_DISABLE_DBM DEFINES += -DNSS_DISABLE_DBM endif # Avoid building object leak test code for optimized library ifndef BUILD_OPT ifdef PKIX_OBJECT_LEAK_TEST DEFINES += -DPKIX_OBJECT_LEAK_TEST endif endif # This allows all library and tools code to use the util function # implementations directly from libnssutil3, rather than the wrappers # in libnss3 which are present for binary compatibility only DEFINES += -DUSE_UTIL_DIRECTLY USE_UTIL_DIRECTLY = 1 jss-4.4.3/jss/coreconf/coreconf.dep000066400000000000000000000010101326145000000171650ustar00rootroot00000000000000/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * A dummy header file that is a dependency for all the object files. * Used to force a full recompilation of NSS in Mozilla's Tinderbox * depend builds. See comments in rules.mk. */ #error "Do not include this header file." jss-4.4.3/jss/coreconf/coreconf.pl000066400000000000000000000045661326145000000170530ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. sub recursive_copy { local($fromdir); local($todir); local(@dirlist); $fromdir = shift; $todir = shift; print STDERR "recursive copy called with $fromdir, $todir\n"; #remove any trailing slashes. $fromdir =~ s/\/$//; $todir =~ s/\/$//; opendir(DIR, $fromdir); @dirlist = readdir DIR; close DIR; foreach $file (@dirlist) { if (! (($file eq "." ) || ($file eq "..") )) { if (-d "$fromdir/$file") { print STDERR "handling directory $todir/$file\n"; &rec_mkdir("$todir/$file"); &recursive_copy("$fromdir/$file","$todir/$file"); } else { print STDERR "handling file $fromdir/$file\n"; &my_copy("$fromdir/$file","$todir/$file"); } } } } sub parse_argv { # print STDERR "Parsing Variables\n"; foreach $q ( @ARGV ) { if (! ($q =~ /=/)) { $var{$lastassigned} .= " $q"; } else { $q =~ /^([^=]*)=(.*)/; $left = $1; $right = $2; $right =~ s/ *$//; $var{$left} = $right; $lastassigned = $left; } print STDERR "Assigned $lastassigned = $var{$lastassigned}\n"; } } # usage: &my_copy("dir/fromfile","dir2/tofile"); # do a 'copy' - files only, 'to' MUST be a filename, not a directory. # fix this to be able to use copy on win nt. sub my_copy { local($from); local($to); local($cpcmd); $from = shift; $to = shift; if ( ! defined $var{OS_ARCH}) { die "OS_ARCH not defined!"; } else { if ($var{OS_ARCH} eq 'WINNT') { $cpcmd = 'cp'; } else { $cpcmd = 'cp'; } print STDERR "COPYING: $cpcmd $from $to\n"; system("$cpcmd $from $to"); } } sub old_my_copy { local($from); local($to); $from = shift; $to = shift; open(FIN, "<$from") || die("Can't read from file $from\n"); if ( ! open(FOUT,">$to")) { close FIN; die "Can't write to file $to\n"; } while (read(FIN, $buf, 100000)) { print FOUT $buf; } close (FIN); close (FOUT); } sub rec_mkdir { local($arg); local($t); local($q); $arg = shift; $t = ""; foreach $q (split(/\//,$arg)) { $t .= $q; if (! ($t =~ /\.\.$/)) { if ($t =~ /./) { mkdir($t,0775); } } $t.= '/'; } } 1; jss-4.4.3/jss/coreconf/cpdist.pl000077500000000000000000000074671326145000000165510ustar00rootroot00000000000000#! /usr/local/bin/perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. require('coreconf.pl'); #######-- read in variables on command line into %var &parse_argv; ### do the copy print STDERR "RELEASE TREE / MODULE = $var{RELEASE_TREE} $var{MODULE}\n"; # 1 if ($var{RELEASE} eq "") { exit; } # Can't do release here, so exit. # 2 #if (! ($var{RELEASE} =~ /\//)) { # if no specific version is specified in RELEASE variable # $component = $var{RELEASE}; #} #else { # if a subcomponent/version is given in the RELEASE variable # $var{RELEASE} =~ m|^([^/]*)/|; # $component = $1; # everything before the first slash; # } # 3 $path = $var{RELEASE}; # 4 # find out what directory we would create for 'today' $year = (localtime)[5] + 1900; $month = (localtime)[4] + 1; $day = (localtime)[3]; $today = sprintf( "%d%02d%02d", $year, $month, $day ); # 5 # if version is null, then set the version to today. if ($var{"RELEASE_VERSION"} eq "") { $var{"RELEASE_VERSION"} = $today; } #6 $version = $var{"RELEASE_VERSION"}; # set RELEASE_VERSION to passed in variable #7 # if version is today, then we will want to make a 'current' link. if ($version eq $today) { $create_current = 1; } #8 # version can be a) passed in value from command line, b) value in manifest.mn # or c) computed value such as '19970909' $dir = "$var{'RELEASE_TREE'}/$path"; #9 if (! (-e "$dir/$version" && -d "$dir/$version")) { print "making dir $dir \n"; &rec_mkdir("$dir/$version"); } print "version = $version\n"; print "path = $path\n"; print "var{release_tree} = $var{'RELEASE_TREE'}\n"; print "dir = $dir = RELEASE_TREE/path\n"; #10 if ($create_current == 1) { # unlinking and linking always occurs, even if the link is correct print "unlinking $dir/current\n"; unlink("$dir/current"); print "putting version number $today into 'current' file.."; open(FILE,">$dir/current") || die " couldn't open current\n"; print FILE "$today\n"; close(FILE); print " ..done\n" } &rec_mkdir("$dir/$version/$var{'RELEASE_MD_DIR'}"); &rec_mkdir("$dir/$version/$var{'RELEASE_XP_DIR'}"); foreach $jarfile (split(/ /,$var{FILES}) ) { print STDERR "---------------------------------------------\n"; $jarinfo = $var{$jarfile}; ($jardir,$jaropts) = split(/\|/,$jarinfo); if ($jaropts =~ /f/) { print STDERR "Copying files $jardir....\n"; } else { print STDERR "Copying jar file $jarfile....\n"; } print "jaropts = $jaropts\n"; if ($jaropts =~ /m/) { $destdir = $var{"RELEASE_MD_DIR"}; print "found m, using MD dir $destdir\n"; } elsif ($jaropts =~ /x/) { $destdir = $var{"RELEASE_XP_DIR"}; print "found x, using XP dir $destdir\n"; } else { die "Error: must specify m or x in jar options in $jarinfo line\n"; } $distdir = "$dir/$version/$destdir"; if ($jaropts =~ /f/) { print "splitting: \"$jardir\"\n"; for $srcfile (split(/ /,$jardir)) { #if srcfile has a slash if ($srcfile =~ m|/|) { #pull out everything before the last slash into $1 $srcfile =~ m|(.*)/|; $distsubdir = "/$1"; print "making dir $distdir$distsubdir\n"; &rec_mkdir("$distdir$distsubdir"); } print "copy: from $srcfile\n"; print " to $distdir$distsubdir\n"; $srcprefix = ""; if ($jaropts =~/m/) { $srcprefix = "$var{'PLATFORM'}/"; } system("cp $srcprefix$srcfile $distdir$distsubdir"); } } else { $srcfile = "$var{SOURCE_RELEASE_PREFIX}/$jardir/$jarfile"; print "copy: from $srcfile\n"; print " to $distdir\n"; system("cp $srcfile $distdir"); } } jss-4.4.3/jss/coreconf/headers.mk000066400000000000000000000013301326145000000166460ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master "Core Components" include switch for support header files # ####################################################################### # # Always append source-side machine-dependent (md) and cross-platform # (xp) include paths # INCLUDES += -I$(SOURCE_MDHEADERS_DIR) -I$(SOURCE_XPHEADERS_DIR) # # Only append source-side private cross-platform include paths for # sectools # INCLUDES += -I$(SOURCE_XPPRIVATE_DIR) MK_HEADERS = included jss-4.4.3/jss/coreconf/import.pl000077500000000000000000000116001326145000000165550ustar00rootroot00000000000000#! /usr/local/bin/perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. print STDERR "import.pl\n"; require('coreconf.pl'); $returncode =0; #######-- read in variables on command line into %var $var{UNZIP} = "unzip -o"; &parse_argv; if (! ($var{IMPORTS} =~ /\w/)) { print STDERR "nothing to import\n"; } ######-- Do the import! foreach $import (split(/ /,$var{IMPORTS}) ) { print STDERR "\n\nIMPORTING .... $import\n-----------------------------\n"; # if a specific version specified in IMPORT variable # (if $import has a slash in it) if ($import =~ /\//) { # $component=everything before the first slash of $import $import =~ m|^([^/]*)/|; $component = $1; $import =~ m|^(.*)/([^/]*)$|; # $path=everything before the last slash of $import $path = $1; # $version=everything after the last slash of $import $version = $2; if ($var{VERSION} ne "current") { $version = $var{VERSION}; } } else { $component = $import; $path = $import; $version = $var{VERSION}; } $releasejardir = "$var{RELEASE_TREE}/$path"; if ($version eq "current") { print STDERR "Current version specified. Reading 'current' file ... \n"; open(CURRENT,"$releasejardir/current") || die "NO CURRENT FILE\n"; $version = ; $version =~ s/(\r?\n)*$//; # remove any trailing [CR/]LF's close(CURRENT); print STDERR "Using version $version\n"; if ( $version eq "") { die "Current version file empty. Stopping\n"; } } $releasejardir = "$releasejardir/$version"; if ( ! -d $releasejardir) { die "$releasejardir doesn't exist (Invalid Version?)\n"; } foreach $jarfile (split(/ /,$var{FILES})) { ($relpath,$distpath,$options) = split(/\|/, $var{$jarfile}); if ($var{'OVERRIDE_IMPORT_CHECK'} eq 'YES') { $options =~ s/v//g; } if ( $relpath ne "") { $releasejarpathname = "$releasejardir/$relpath";} else { $releasejarpathname = $releasejardir; } # If a component doesn't have IDG versions, import the DBG ones if( ! -e "$releasejarpathname/$jarfile" ) { if( $relpath =~ /IDG\.OBJ$/ ) { $relpath =~ s/IDG.OBJ/DBG.OBJ/; $releasejarpathname = "$releasejardir/$relpath"; } elsif( $relpath =~ /IDG\.OBJD$/ ) { $relpath =~ s/IDG.OBJD/DBG.OBJD/; $releasejarpathname = "$releasejardir/$relpath"; } } if (-e "$releasejarpathname/$jarfile") { print STDERR "\nWorking on jarfile: $jarfile\n"; if ($distpath =~ m|/$|) { $distpathname = "$distpath$component"; } else { $distpathname = "$distpath"; } #the block below is used to determine whether or not the xp headers have #already been imported for this component $doimport = 1; if ($options =~ /v/) { # if we should check the imported version print STDERR "Checking if version file exists $distpathname/version\n"; if (-e "$distpathname/version") { open( VFILE, "<$distpathname/version") || die "Cannot open $distpathname/version for reading. Permissions?\n"; $importversion = ; close (VFILE); $importversion =~ s/\r?\n$//; # Strip off any trailing CR/LF if ($version eq $importversion) { print STDERR "$distpathname version '$importversion' already imported. Skipping...\n"; $doimport =0; } } } if ($doimport == 1) { if (! -d "$distpathname") { &rec_mkdir("$distpathname"); } # delete the stuff in there already. # (this should really be recursive delete.) if ($options =~ /v/) { $remheader = "\nREMOVING files in '$distpathname/' :"; opendir(DIR,"$distpathname") || die ("Cannot read directory $distpathname\n"); @filelist = readdir(DIR); closedir(DIR); foreach $file ( @filelist ) { if (! ($file =~ m!/.?.$!) ) { if (! (-d $file)) { $file =~ m!([^/]*)$!; print STDERR "$remheader $1"; $remheader = " "; unlink "$distpathname/$file"; } } } } print STDERR "\n\n"; print STDERR "\nExtracting jarfile '$jarfile' to local directory $distpathname/\n"; print STDERR "$var{UNZIP} $releasejarpathname/$jarfile -d $distpathname\n"; system("$var{UNZIP} $releasejarpathname/$jarfile -d $distpathname"); $r = $?; if ($options =~ /v/) { if ($r == 0) { unlink ("$distpathname/version"); if (open(VFILE,">$distpathname/version")) { print VFILE "$version\n"; close(VFILE); } } else { print STDERR "Could not create '$distpathname/version'. Permissions?\n"; $returncode ++; } } } # if (doimport) } # if (-e releasejarpathname/jarfile) } # foreach jarfile) } # foreach IMPORT exit($returncode); jss-4.4.3/jss/coreconf/jdk.mk000066400000000000000000000263151326145000000160150ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ifdef NS_USE_JDK ####################################################################### # [1] Define preliminary JDK "Core Components" toolset options # ####################################################################### # set default JDK java threading model ifeq ($(JDK_THREADING_MODEL),) JDK_THREADING_MODEL = native_threads # no such thing as -native flag JDK_THREADING_MODEL_OPT = endif ####################################################################### # [2] Define platform-independent JDK "Core Components" options # ####################################################################### # set default location of the java classes repository ifeq ($(JAVA_DESTPATH),) ifdef BUILD_OPT JAVA_DESTPATH = $(SOURCE_CLASSES_DIR) else JAVA_DESTPATH = $(SOURCE_CLASSES_DBG_DIR) endif endif # set default location of the package under the java classes repository # note that this overrides the default package value in ruleset.mk ifeq ($(PACKAGE),) PACKAGE = . endif # set default location of the java source code repository ifeq ($(JAVA_SOURCEPATH),) JAVA_SOURCEPATH = . endif # add JNI directory to default include search path ifneq ($(JNI_GEN),) ifdef NSBUILDROOT INCLUDES += -I$(JNI_GEN_DIR) -I$(SOURCE_XP_DIR) else INCLUDES += -I$(JNI_GEN_DIR) endif endif ####################################################################### # [3] Define platform-dependent JDK "Core Components" options # ####################################################################### # set [Microsoft Windows] platforms ifeq ($(OS_ARCH), WINNT) JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/lib/rt.jar endif endif PATH_SEPARATOR = ; # (2) specify "header" information JAVA_ARCH = win32 INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # currently, disable JIT option on this platform JDK_JIT_OPT = -nojit endif # set [Sun Solaris] platforms ifeq ($(OS_ARCH), SunOS) JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/lib/rt.jar endif endif PATH_SEPARATOR = : # (2) specify "header" information JAVA_ARCH = solaris INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # currently, disable JIT option on this platform JDK_JIT_OPT = endif # set [Hewlett Packard HP-UX] platforms ifeq ($(OS_ARCH), HP-UX) JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/lib/rt.jar endif endif PATH_SEPARATOR = : # (2) specify "header" information JAVA_ARCH = hp-ux INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # no JIT option available on this platform JDK_JIT_OPT = endif # set [Redhat Linux] platforms ifeq ($(OS_ARCH), Linux) JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/lib/rt.jar endif endif PATH_SEPARATOR = : # (2) specify "header" information JAVA_ARCH = linux INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # no JIT option available on this platform JDK_JIT_OPT = endif # set [Mac OS X] platforms ifeq ($(OS_ARCH), Darwin) JAVA_CLASSES = $(JAVA_HOME)/../Classes/classes.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/../Classes/classes.jar endif endif PATH_SEPARATOR = : # (2) specify "header" information JAVA_ARCH = darwin INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # no JIT option available on this platform JDK_JIT_OPT = endif # set [IBM AIX] platforms ifeq ($(OS_ARCH), AIX) JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/lib/rt.jar endif endif PATH_SEPARATOR = : # (2) specify "header" information JAVA_ARCH = aix INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # no JIT option available on this platform JDK_JIT_OPT = endif # set [Digital UNIX] platforms ifeq ($(OS_ARCH), OSF1) JAVA_CLASSES = $(JAVA_HOME)/jre/lib/rt.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/lib/rt.jar endif endif PATH_SEPARATOR = : # (2) specify "header" information JAVA_ARCH = alpha INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # no JIT option available on this platform JDK_JIT_OPT = endif # set [Silicon Graphics IRIX] platforms ifeq ($(OS_ARCH), IRIX) JAVA_CLASSES = $(JAVA_HOME)/lib/dev.jar:$(JAVA_HOME)/lib/rt.jar ifeq ($(JRE_HOME),) JRE_HOME = $(JAVA_HOME) JRE_CLASSES = $(JAVA_CLASSES) else ifeq ($(JRE_CLASSES),) JRE_CLASSES = $(JRE_HOME)/lib/dev.jar:$(JRE_HOME)/lib/rt.jar endif endif PATH_SEPARATOR = : # (2) specify "header" information JAVA_ARCH = irix INCLUDES += -I$(JAVA_HOME)/include INCLUDES += -I$(JAVA_HOME)/include/$(JAVA_ARCH) # no JIT option available on this platform JDK_JIT_OPT = endif ####################################################################### # [4] Define remaining JDK "Core Components" default toolset options # ####################################################################### # set JDK optimization model ifeq ($(BUILD_OPT),1) JDK_OPTIMIZER_OPT = -O else JDK_OPTIMIZER_OPT = -g endif # set minimal JDK debugging model ifeq ($(JDK_DEBUG),1) JDK_DEBUG_OPT = -debug else JDK_DEBUG_OPT = endif # set default path to repository for JDK classes ifeq ($(JDK_CLASS_REPOSITORY_OPT),) JDK_CLASS_REPOSITORY_OPT = -d $(JAVA_DESTPATH) endif # define a default JDK classpath ifeq ($(JDK_CLASSPATH),) JDK_CLASSPATH = '$(JAVA_DESTPATH)$(PATH_SEPARATOR)$(JAVA_SOURCEPATH)$(PATH_SEPARATOR)$(JAVA_CLASSES)' endif # by default, override CLASSPATH environment variable using the JDK classpath option with $(JDK_CLASSPATH) ifeq ($(JDK_CLASSPATH_OPT),) JDK_CLASSPATH_OPT = -classpath $(JDK_CLASSPATH) endif ifeq ($(USE_64), 1) JDK_USE_64 = -d64 endif endif ####################################################################### # [5] Define JDK "Core Components" toolset; # # (always allow a user to override these values) # ####################################################################### # # (1) appletviewer # ifeq ($(APPLETVIEWER),) APPLETVIEWER_PROG = $(JAVA_HOME)/bin/appletviewer$(PROG_SUFFIX) APPLETVIEWER_FLAGS = $(JDK_THREADING_MODEL_OPT) APPLETVIEWER_FLAGS += $(JDK_DEBUG_OPT) APPLETVIEWER_FLAGS += $(JDK_JIT_OPT) APPLETVIEWER = $(APPLETVIEWER_PROG) $(APPLETVIEWER_FLAGS) endif # # (2) jar # ifeq ($(JAR),) JAR_PROG = $(JAVA_HOME)/bin/jar$(PROG_SUFFIX) JAR_FLAGS = $(JDK_THREADING_MODEL_OPT) JAR = $(JAR_PROG) $(JAR_FLAGS) endif # # (3) java # ifeq ($(JAVA),) JAVA_PROG = $(JAVA_HOME)/bin/java$(PROG_SUFFIX) JAVA_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVA_FLAGS += $(JDK_DEBUG_OPT) JAVA_FLAGS += $(JDK_CLASSPATH_OPT) JAVA_FLAGS += $(JDK_JIT_OPT) JAVA_FLAGS += $(JDK_USE_64) JAVA = $(JAVA_PROG) $(JAVA_FLAGS) endif # # (4) javac # ifeq ($(JAVAC),) JAVAC_PROG = $(JAVA_HOME)/bin/javac$(PROG_SUFFIX) JAVAC_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVAC_FLAGS += $(JDK_OPTIMIZER_OPT) JAVAC_FLAGS += $(JDK_DEBUG_OPT) JAVAC_FLAGS += $(JDK_CLASSPATH_OPT) JAVAC_FLAGS += $(JDK_CLASS_REPOSITORY_OPT) JAVAC_FLAGS += $(JDK_USE_64) JAVAC = $(JAVAC_PROG) $(JAVAC_FLAGS) endif # # (5) javadoc # ifeq ($(JAVADOC),) JAVADOC_PROG = $(JAVA_HOME)/bin/javadoc$(PROG_SUFFIX) JAVADOC_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVADOC_FLAGS += $(JDK_CLASSPATH_OPT) JAVADOC = $(JAVADOC_PROG) $(JAVADOC_FLAGS) endif # # (6) javah # ifeq ($(JAVAH),) JAVAH_PROG = $(JAVA_HOME)/bin/javah$(PROG_SUFFIX) JAVAH_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVAH_FLAGS += $(JDK_CLASSPATH_OPT) JAVAH = $(JAVAH_PROG) $(JAVAH_FLAGS) endif # # (7) javakey # ifeq ($(JAVAKEY),) JAVAKEY_PROG = $(JAVA_HOME)/bin/javakey$(PROG_SUFFIX) JAVAKEY_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVAKEY = $(JAVAKEY_PROG) $(JAVAKEY_FLAGS) endif # # (8) javap # ifeq ($(JAVAP),) JAVAP_PROG = $(JAVA_HOME)/bin/javap$(PROG_SUFFIX) JAVAP_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVAP_FLAGS += $(JDK_CLASSPATH_OPT) JAVAP = $(JAVAP_PROG) $(JAVAP_FLAGS) endif # # (9) javat # ifeq ($(JAVAT),) JAVAT_PROG = $(JAVA_HOME)/bin/javat$(PROG_SUFFIX) JAVAT_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVAT = $(JAVAT_PROG) $(JAVAT_FLAGS) endif # # (10) javaverify # ifeq ($(JAVAVERIFY),) JAVAVERIFY_PROG = $(JAVA_HOME)/bin/javaverify$(PROG_SUFFIX) JAVAVERIFY_FLAGS = $(JDK_THREADING_MODEL_OPT) JAVAVERIFY = $(JAVAVERIFY_PROG) $(JAVAVERIFY_FLAGS) endif # # (11) javaw # ifeq ($(JAVAW),) jJAVAW_PROG = $(JAVA_HOME)/bin/javaw$(PROG_SUFFIX) jJAVAW_FLAGS = $(JDK_THREADING_MODEL_OPT) jJAVAW_FLAGS += $(JDK_DEBUG_OPT) jJAVAW_FLAGS += $(JDK_CLASSPATH_OPT) jJAVAW_FLAGS += $(JDK_JIT_OPT) jJAVAW = $(JAVAW_PROG) $(JAVAW_FLAGS) endif # # (12) jdb # ifeq ($(JDB),) JDB_PROG = $(JAVA_HOME)/bin/jdb$(PROG_SUFFIX) JDB_FLAGS = $(JDK_THREADING_MODEL_OPT) JDB_FLAGS += $(JDK_DEBUG_OPT) JDB_FLAGS += $(JDK_CLASSPATH_OPT) JDB_FLAGS += $(JDK_JIT_OPT) JDB = $(JDB_PROG) $(JDB_FLAGS) endif # # (13) jre # ifeq ($(JRE),) JRE_PROG = $(JAVA_HOME)/bin/jre$(PROG_SUFFIX) JRE_FLAGS = $(JDK_THREADING_MODEL_OPT) JRE_FLAGS += $(JDK_CLASSPATH_OPT) JRE_FLAGS += $(JDK_JIT_OPT) JRE = $(JRE_PROG) $(JRE_FLAGS) endif # # (14) jrew # ifeq ($(JREW),) JREW_PROG = $(JAVA_HOME)/bin/jrew$(PROG_SUFFIX) JREW_FLAGS = $(JDK_THREADING_MODEL_OPT) JREW_FLAGS += $(JDK_CLASSPATH_OPT) JREW_FLAGS += $(JDK_JIT_OPT) JREW = $(JREW_PROG) $(JREW_FLAGS) endif # # (15) native2ascii # ifeq ($(NATIVE2ASCII),) NATIVE2ASCII_PROG = $(JAVA_HOME)/bin/native2ascii$(PROG_SUFFIX) NATIVE2ASCII_FLAGS = $(JDK_THREADING_MODEL_OPT) NATIVE2ASCII = $(NATIVE2ASCII_PROG) $(NATIVE2ASCII_FLAGS) endif # # (16) rmic # ifeq ($(RMIC),) RMIC_PROG = $(JAVA_HOME)/bin/rmic$(PROG_SUFFIX) RMIC_FLAGS = $(JDK_THREADING_MODEL_OPT) RMIC_FLAGS += $(JDK_OPTIMIZER_OPT) RMIC_FLAGS += $(JDK_CLASSPATH_OPT) RMIC = $(RMIC_PROG) $(RMIC_FLAGS) endif # # (17) rmiregistry # ifeq ($(RMIREGISTRY),) RMIREGISTRY_PROG = $(JAVA_HOME)/bin/rmiregistry$(PROG_SUFFIX) RMIREGISTRY_FLAGS = $(JDK_THREADING_MODEL_OPT) RMIREGISTRY = $(RMIREGISTRY_PROG) $(RMIREGISTRY_FLAGS) endif # # (18) serialver # ifeq ($(SERIALVER),) SERIALVER_PROG = $(JAVA_HOME)/bin/serialver$(PROG_SUFFIX) SERIALVER_FLAGS = $(JDK_THREADING_MODEL_OPT) SERIALVER = $(SERIALVER_PROG) $(SERIALVER_FLAGS) endif jss-4.4.3/jss/coreconf/jniregen.pl000077500000000000000000000044111326145000000170460ustar00rootroot00000000000000#!/usr/local/bin/perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Input: -d dir -j javahcmd foo1 foo2 . . . # Compares generated "_jni/foo1.h" file with "foo1.class", and # generated "_jni/foo2.h" file with "foo2.class", etc. # (NOTE: unlike its closely related cousin, outofdate.pl, # the "-d dir" must always be specified) # Runs the javahcmd on all files that are different. # # Returns: list of headers which are OLDER than corresponding class # files (non-existent class files are considered to be real old :-) my $javah = ""; my $classdir = ""; while(1) { if ($ARGV[0] eq '-d') { $classdir = $ARGV[1]; $classdir .= "/"; shift; shift; } elsif($ARGV[0] eq '-j') { $javah = $ARGV[1]; shift; shift; } else { last; } } if( $javah eq "") { die "Must specify -j "; } if( $classdir eq "") { die "Must specify -d "; } foreach $filename (@ARGV) { $headerfilename = "_jni/"; $headerfilename .= $filename; $headerfilename =~ s/\./_/g; $headerfilename .= ".h"; $classfilename = $filename; $classfilename =~ s|\.|/|g; $classfilename .= ".class"; $classfilename = $classdir . $classfilename; ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $headermtime, $ctime, $blksize, $blocks ) = stat( $headerfilename ); ( $dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $classmtime, $ctime, $blksize, $blocks ) = stat( $classfilename ); if( $headermtime < $classmtime ) { # NOTE: Since this is used by "javah", and "javah" refuses to overwrite # an existing file, we force an unlink from this script, since # we actually want to regenerate the header file at this time. unlink $headerfilename; push @filelist, $filename; } } if( @filelist ) { $cmd = "$javah " . join(" ",@filelist); $cmd =~ s/\'/\"/g; # because windows doesn't understand single quote print "$cmd\n"; exit (system($cmd) >> 8); } else { print "All JNI header files up to date.\n" } jss-4.4.3/jss/coreconf/location.mk000066400000000000000000000031511326145000000170460ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master "Core Components" macros to figure out binary code location # ####################################################################### # # Figure out where the binary code lives. # ifdef BUILD_TREE ifdef LIBRARY_NAME BUILD = $(BUILD_TREE)/nss/$(LIBRARY_NAME) OBJDIR = $(BUILD_TREE)/nss/$(LIBRARY_NAME) DEPENDENCIES = $(BUILD_TREE)/nss/$(LIBRARY_NAME)/.md else BUILD = $(BUILD_TREE)/nss OBJDIR = $(BUILD_TREE)/nss DEPENDENCIES = $(BUILD_TREE)/nss/.md endif else BUILD = $(PLATFORM) OBJDIR = $(PLATFORM) DEPENDENCIES = $(PLATFORM)/.md endif DIST = $(SOURCE_PREFIX)/$(PLATFORM) ifdef BUILD_DEBUG_GC DEFINES += -DDEBUG_GC endif GARBAGE += $(DEPENDENCIES) core $(wildcard core.[0-9]*) ifdef NSPR_INCLUDE_DIR INCLUDES += -I$(NSPR_INCLUDE_DIR) endif ifndef NSPR_LIB_DIR NSPR_LIB_DIR = $(DIST)/lib endif ifdef NSS_INCLUDE_DIR INCLUDES += -I$(NSS_INCLUDE_DIR) endif ifndef NSS_LIB_DIR NSS_LIB_DIR = $(DIST)/lib endif ifdef NSSUTIL_INCLUDE_DIR INCLUDES += -I$(NSSUTIL_INCLUDE_DIR) endif ifndef NSSUTIL_LIB_DIR NSSUTIL_LIB_DIR = $(DIST)/lib endif ifdef SOFTOKEN_INCLUDE_DIR INCLUDES += -I$(SOFTOKEN_INCLUDE_DIR) endif ifndef SOFTOKEN_LIB_DIR SOFTOKEN_LIB_DIR = $(DIST)/lib endif ifndef SQLITE_LIB_NAME SQLITE_LIB_NAME = sqlite3 endif MK_LOCATION = included jss-4.4.3/jss/coreconf/mkdepend/000077500000000000000000000000001326145000000164745ustar00rootroot00000000000000jss-4.4.3/jss/coreconf/mkdepend/Makefile000066400000000000000000000021561326145000000201400ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DEPTH = ../.. CORE_DEPTH = ../.. MODULE = coreconf CSRCS = \ cppsetup.c \ ifparser.c \ include.c \ main.c \ parse.c \ pr.c PROGRAM = mkdepend # Indicate that this directory builds build tools. INTERNAL_TOOLS = 1 include $(DEPTH)/coreconf/config.mk TARGETS = $(PROGRAM) ifeq (,$(filter-out OS2 WIN%,$(OS_TARGET))) DEFINES += -DNO_X11 else INSTALL = true endif ifdef NATIVE_CC CC=$(NATIVE_CC) endif ifdef NATIVE_FLAGS OS_CFLAGS=$(NATIVE_FLAGS) endif include $(DEPTH)/coreconf/rules.mk ifdef GNU_CC OPTIMIZER = -O3 else ifeq ($(OS_ARCH),SunOS) OPTIMIZER = -fast endif ifeq ($(OS_ARCH),WINNT) OPTIMIZER = -Ox endif endif DEFINES += -DINCLUDEDIR=\"/usr/include\" -DOBJSUFFIX=\".$(OBJ_SUFFIX)\" # Redefine MAKE_OBJDIR for just this directory define MAKE_OBJDIR if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); fi endef jss-4.4.3/jss/coreconf/mkdepend/cppsetup.c000066400000000000000000000122131326145000000205020ustar00rootroot00000000000000/* $Xorg: cppsetup.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */ /* Copyright (c) 1993, 1994, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/config/makedepend/cppsetup.c,v 3.11 2001/12/17 20:52:22 dawes Exp $ */ #include "def.h" #ifdef CPP /* * This file is strictly for the sake of cpy.y and yylex.c (if * you indeed have the source for cpp). */ #define IB 1 #define SB 2 #define NB 4 #define CB 8 #define QB 16 #define WB 32 #define SALT '#' #if defined(pdp11) || defined(vax) || defined(ns16000) || defined(mc68000) || defined(ibm032) #define COFF 128 #else #define COFF 0 #endif /* * These variables used by cpy.y and yylex.c */ extern char *outp, *inp, *newp, *pend; extern char *ptrtab; extern char fastab[]; extern char slotab[]; /* * cppsetup */ struct filepointer *currentfile; struct inclist *currentinc; int cppsetup(char *line, struct filepointer *filep, struct inclist *inc) { char *p, savec; static boolean setupdone = FALSE; boolean value; if (!setupdone) { cpp_varsetup(); setupdone = TRUE; } currentfile = filep; currentinc = inc; inp = newp = line; for (p=newp; *p; p++) ; /* * put a newline back on the end, and set up pend, etc. */ *p++ = '\n'; savec = *p; *p = '\0'; pend = p; ptrtab = slotab+COFF; *--inp = SALT; outp=inp; value = yyparse(); *p = savec; return(value); } struct symtab **lookup(symbol) char *symbol; { static struct symtab *undefined; struct symtab **sp; sp = isdefined(symbol, currentinc, NULL); if (sp == NULL) { sp = &undefined; (*sp)->s_value = NULL; } return (sp); } pperror(tag, x0,x1,x2,x3,x4) int tag,x0,x1,x2,x3,x4; { warning("\"%s\", line %d: ", currentinc->i_file, currentfile->f_line); warning(x0,x1,x2,x3,x4); } yyerror(s) register char *s; { fatalerr("Fatal error: %s\n", s); } #else /* not CPP */ #include "ifparser.h" struct _parse_data { struct filepointer *filep; struct inclist *inc; char *filename; const char *line; }; static const char * my_if_errors (IfParser *ip, const char *cp, const char *expecting) { struct _parse_data *pd = (struct _parse_data *) ip->data; int lineno = pd->filep->f_line; char *filename = pd->filename; char prefix[300]; int prefixlen; int i; sprintf (prefix, "\"%s\":%d", filename, lineno); prefixlen = strlen(prefix); fprintf (stderr, "%s: %s", prefix, pd->line); i = cp - pd->line; if (i > 0 && pd->line[i-1] != '\n') { putc ('\n', stderr); } for (i += prefixlen + 3; i > 0; i--) { putc (' ', stderr); } fprintf (stderr, "^--- expecting %s\n", expecting); return NULL; } #define MAXNAMELEN 256 static struct symtab ** lookup_variable (IfParser *ip, const char *var, int len) { char tmpbuf[MAXNAMELEN + 1]; struct _parse_data *pd = (struct _parse_data *) ip->data; if (len > MAXNAMELEN) return 0; strncpy (tmpbuf, var, len); tmpbuf[len] = '\0'; return isdefined (tmpbuf, pd->inc, NULL); } static int my_eval_defined (IfParser *ip, const char *var, int len) { if (lookup_variable (ip, var, len)) return 1; else return 0; } #define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_') static long my_eval_variable (IfParser *ip, const char *var, int len) { long val; struct symtab **s; s = lookup_variable (ip, var, len); if (!s) return 0; do { var = (*s)->s_value; if (!isvarfirstletter(*var) || !strcmp((*s)->s_name, var)) break; s = lookup_variable (ip, var, strlen(var)); } while (s); var = ParseIfExpression(ip, var, &val); if (var && *var) debug(4, ("extraneous: '%s'\n", var)); return val; } int cppsetup(char *filename, char *line, struct filepointer *filep, struct inclist *inc) { IfParser ip; struct _parse_data pd; long val = 0; pd.filep = filep; pd.inc = inc; pd.line = line; pd.filename = filename; ip.funcs.handle_error = my_if_errors; ip.funcs.eval_defined = my_eval_defined; ip.funcs.eval_variable = my_eval_variable; ip.data = (char *) &pd; (void) ParseIfExpression (&ip, line, &val); if (val) return IF; else return IFFALSE; } #endif /* CPP */ jss-4.4.3/jss/coreconf/mkdepend/def.h000066400000000000000000000135031326145000000174050ustar00rootroot00000000000000/* $Xorg: def.h,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */ /* Copyright (c) 1993, 1994, 1998 The Open Group. Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/config/makedepend/def.h,v 3.14 2003/01/17 17:09:49 tsi Exp $ */ #ifndef NO_X11 #include #include #endif #include #include #include #include #if 0 #ifndef X_NOT_POSIX #ifndef _POSIX_SOURCE #define _POSIX_SOURCE #endif #endif #endif #include #include #include #define MAXDEFINES 512 #define MAXFILES 1024 #define MAXINCFILES 256 /* "-include" files */ #define MAXDIRS 1024 #define SYMTABINC 10 /* must be > 1 for define() to work right */ #define TRUE 1 #define FALSE 0 /* the following must match the directives table in main.c */ #define IF 0 #define IFDEF 1 #define IFNDEF 2 #define ELSE 3 #define ENDIF 4 #define DEFINE 5 #define UNDEF 6 #define INCLUDE 7 #define LINE 8 #define PRAGMA 9 #define ERROR 10 #define IDENT 11 #define SCCS 12 #define ELIF 13 #define EJECT 14 #define WARNING 15 #define INCLUDENEXT 16 #define IFFALSE 17 /* pseudo value --- never matched */ #define ELIFFALSE 18 /* pseudo value --- never matched */ #define INCLUDEDOT 19 /* pseudo value --- never matched */ #define IFGUESSFALSE 20 /* pseudo value --- never matched */ #define ELIFGUESSFALSE 21 /* pseudo value --- never matched */ #define INCLUDENEXTDOT 22 /* pseudo value --- never matched */ #ifdef DEBUG extern int _debugmask; /* * debug levels are: * * 0 show ifn*(def)*,endif * 1 trace defined/!defined * 2 show #include * 3 show #include SYMBOL * 4-6 unused */ #define debug(level,arg) { if (_debugmask & (1 << level)) warning arg; } #else #define debug(level,arg) /**/ #endif /* DEBUG */ typedef unsigned char boolean; struct symtab { char *s_name; char *s_value; }; /* possible i_flag */ #define DEFCHECKED (1<<0) /* whether defines have been checked */ #define NOTIFIED (1<<1) /* whether we have revealed includes */ #define MARKED (1<<2) /* whether it's in the makefile */ #define SEARCHED (1<<3) /* whether we have read this */ #define FINISHED (1<<4) /* whether we are done reading this */ #define INCLUDED_SYM (1<<5) /* whether #include SYMBOL was found Can't use i_list if TRUE */ struct inclist { char *i_incstring; /* string from #include line */ char *i_file; /* path name of the include file */ struct inclist **i_list; /* list of files it itself includes */ int i_listlen; /* length of i_list */ struct symtab **i_defs; /* symbol table for this file and its children when merged */ int i_ndefs; /* current # defines */ boolean *i_merged; /* whether we have merged child defines */ unsigned char i_flags; }; struct filepointer { char *f_name; char *f_p; char *f_base; char *f_end; long f_len; long f_line; long cmdinc_count; char **cmdinc_list; long cmdinc_line; }; #include #if defined(macII) && !defined(__STDC__) /* stdlib.h fails to define these */ char *malloc(), *realloc(); #endif /* macII */ char *copy(char *str); int match(char *str, char **list); char *base_name(char *file); char *getnextline(struct filepointer *fp); struct symtab **slookup(char *symbol, struct inclist *file); struct symtab **isdefined(char *symbol, struct inclist *file, struct inclist **srcfile); struct symtab **fdefined(char *symbol, struct inclist *file, struct inclist **srcfile); struct filepointer *getfile(char *file); void included_by(struct inclist *ip, struct inclist *newfile); struct inclist *newinclude(char *newfile, char *incstring); void inc_clean (void); struct inclist *inc_path(char *file, char *include, int type); void freefile(struct filepointer *fp); void define2(char *name, char *val, struct inclist *file); void define(char *def, struct inclist *file); void undefine(char *symbol, struct inclist *file); int find_includes(struct filepointer *filep, struct inclist *file, struct inclist *file_red, int recursion, boolean failOK); void recursive_pr_include(struct inclist *head, char *file, char *base); void add_include(struct filepointer *filep, struct inclist *file, struct inclist *file_red, char *include, int type, boolean failOK); int cppsetup(char *filename, char *line, struct filepointer *filep, struct inclist *inc); extern void fatalerr(char *, ...); extern void warning(char *, ...); extern void warning1(char *, ...); jss-4.4.3/jss/coreconf/mkdepend/ifparser.c000066400000000000000000000300311326145000000204500ustar00rootroot00000000000000/* * $Xorg: ifparser.c,v 1.3 2000/08/17 19:41:50 cpqbld Exp $ * * Copyright 1992 Network Computing Devices, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Network Computing Devices may not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Network Computing Devices makes * no representations about the suitability of this software for any purpose. * It is provided ``as is'' without express or implied warranty. * * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Jim Fulton * Network Computing Devices, Inc. * * Simple if statement processor * * This module can be used to evaluate string representations of C language * if constructs. It accepts the following grammar: * * EXPRESSION := VALUE * | VALUE BINOP EXPRESSION * | VALUE '?' EXPRESSION ':' EXPRESSION * * VALUE := '(' EXPRESSION ')' * | '!' VALUE * | '-' VALUE * | '+' VALUE * | '~' VALUE * | 'defined' '(' variable ')' * | 'defined' variable * | # variable '(' variable-list ')' * | variable * | number * * BINOP := '*' | '/' | '%' * | '+' | '-' * | '<<' | '>>' * | '<' | '>' | '<=' | '>=' * | '==' | '!=' * | '&' | '^' | '|' * | '&&' | '||' * * The normal C order of precedence is supported. * * * External Entry Points: * * ParseIfExpression parse a string for #if */ /* $XFree86: xc/config/makedepend/ifparser.c,v 3.11 2002/09/23 01:48:08 tsi Exp $ */ #include "ifparser.h" #include #include #include /**************************************************************************** Internal Macros and Utilities for Parser ****************************************************************************/ #define DO(val) if (!(val)) return NULL #define CALLFUNC(ggg,fff) (*((ggg)->funcs.fff)) #define SKIPSPACE(ccc) while (isspace(*ccc)) ccc++ #define isvarfirstletter(ccc) (isalpha(ccc) || (ccc) == '_') static const char * parse_variable (IfParser *g, const char *cp, const char **varp) { SKIPSPACE (cp); if (!isvarfirstletter (*cp)) return CALLFUNC(g, handle_error) (g, cp, "variable name"); *varp = cp; /* EMPTY */ for (cp++; isalnum(*cp) || *cp == '_'; cp++) ; return cp; } static const char * parse_number (IfParser *g, const char *cp, long *valp) { long base = 10; SKIPSPACE (cp); if (!isdigit(*cp)) return CALLFUNC(g, handle_error) (g, cp, "number"); *valp = 0; if (*cp == '0') { cp++; if ((*cp == 'x') || (*cp == 'X')) { base = 16; cp++; } else { base = 8; } } /* Ignore overflows and assume ASCII, what source is usually written in */ while (1) { int increment = -1; if (base == 8) { if ((*cp >= '0') && (*cp <= '7')) increment = *cp++ - '0'; } else if (base == 16) { if ((*cp >= '0') && (*cp <= '9')) increment = *cp++ - '0'; else if ((*cp >= 'A') && (*cp <= 'F')) increment = *cp++ - ('A' - 10); else if ((*cp >= 'a') && (*cp <= 'f')) increment = *cp++ - ('a' - 10); } else { /* Decimal */ if ((*cp >= '0') && (*cp <= '9')) increment = *cp++ - '0'; } if (increment < 0) break; *valp = (*valp * base) + increment; } /* Skip trailing qualifiers */ while (*cp == 'U' || *cp == 'u' || *cp == 'L' || *cp == 'l') cp++; return cp; } static const char * parse_character (IfParser *g, const char *cp, long *valp) { char val; SKIPSPACE (cp); if (*cp == '\\') switch (cp[1]) { case 'n': val = '\n'; break; case 't': val = '\t'; break; case 'v': val = '\v'; break; case 'b': val = '\b'; break; case 'r': val = '\r'; break; case 'f': val = '\f'; break; case 'a': val = '\a'; break; case '\\': val = '\\'; break; case '?': val = '\?'; break; case '\'': val = '\''; break; case '\"': val = '\"'; break; case 'x': val = (char) strtol (cp + 2, NULL, 16); break; default: val = (char) strtol (cp + 1, NULL, 8); break; } else val = *cp; while (*cp != '\'') cp++; *valp = (long) val; return cp; } static const char * parse_value (IfParser *g, const char *cp, long *valp) { const char *var, *varend; *valp = 0; SKIPSPACE (cp); if (!*cp) return cp; switch (*cp) { case '(': DO (cp = ParseIfExpression (g, cp + 1, valp)); SKIPSPACE (cp); if (*cp != ')') return CALLFUNC(g, handle_error) (g, cp, ")"); return cp + 1; /* skip the right paren */ case '!': DO (cp = parse_value (g, cp + 1, valp)); *valp = !(*valp); return cp; case '-': DO (cp = parse_value (g, cp + 1, valp)); *valp = -(*valp); return cp; case '+': DO (cp = parse_value (g, cp + 1, valp)); return cp; case '~': DO (cp = parse_value (g, cp + 1, valp)); *valp = ~(*valp); return cp; case '#': DO (cp = parse_variable (g, cp + 1, &var)); SKIPSPACE (cp); if (*cp != '(') return CALLFUNC(g, handle_error) (g, cp, "("); do { DO (cp = parse_variable (g, cp + 1, &var)); SKIPSPACE (cp); } while (*cp && *cp != ')'); if (*cp != ')') return CALLFUNC(g, handle_error) (g, cp, ")"); *valp = 1; /* XXX */ return cp + 1; case '\'': DO (cp = parse_character (g, cp + 1, valp)); if (*cp != '\'') return CALLFUNC(g, handle_error) (g, cp, "'"); return cp + 1; case 'd': if (strncmp (cp, "defined", 7) == 0 && !isalnum(cp[7])) { int paren = 0; int len; cp += 7; SKIPSPACE (cp); if (*cp == '(') { paren = 1; cp++; } DO (cp = parse_variable (g, cp, &var)); len = cp - var; SKIPSPACE (cp); if (paren && *cp != ')') return CALLFUNC(g, handle_error) (g, cp, ")"); *valp = (*(g->funcs.eval_defined)) (g, var, len); return cp + paren; /* skip the right paren */ } /* fall out */ } if (isdigit(*cp)) { DO (cp = parse_number (g, cp, valp)); } else if (!isvarfirstletter(*cp)) return CALLFUNC(g, handle_error) (g, cp, "variable or number"); else { DO (cp = parse_variable (g, cp, &var)); varend = cp; SKIPSPACE(cp); if (*cp != '(') { *valp = (*(g->funcs.eval_variable)) (g, var, varend - var); } else { do { long dummy; DO (cp = ParseIfExpression (g, cp + 1, &dummy)); SKIPSPACE(cp); if (*cp == ')') break; if (*cp != ',') return CALLFUNC(g, handle_error) (g, cp, ","); } while (1); *valp = 1; /* XXX */ cp++; } } return cp; } static const char * parse_product (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_value (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '*': DO (cp = parse_product (g, cp + 1, &rightval)); *valp = (*valp * rightval); break; case '/': DO (cp = parse_product (g, cp + 1, &rightval)); if (rightval == 0) return CALLFUNC(g, handle_error) (g, cp, "0"); *valp = (*valp / rightval); break; case '%': DO (cp = parse_product (g, cp + 1, &rightval)); *valp = (*valp % rightval); break; } return cp; } static const char * parse_sum (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_product (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '+': DO (cp = parse_sum (g, cp + 1, &rightval)); *valp = (*valp + rightval); break; case '-': DO (cp = parse_sum (g, cp + 1, &rightval)); *valp = (*valp - rightval); break; } return cp; } static const char * parse_shift (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_sum (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '<': if (cp[1] == '<') { DO (cp = parse_shift (g, cp + 2, &rightval)); *valp = (*valp << rightval); } break; case '>': if (cp[1] == '>') { DO (cp = parse_shift (g, cp + 2, &rightval)); *valp = (*valp >> rightval); } break; } return cp; } static const char * parse_inequality (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_shift (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '<': if (cp[1] == '=') { DO (cp = parse_inequality (g, cp + 2, &rightval)); *valp = (*valp <= rightval); } else { DO (cp = parse_inequality (g, cp + 1, &rightval)); *valp = (*valp < rightval); } break; case '>': if (cp[1] == '=') { DO (cp = parse_inequality (g, cp + 2, &rightval)); *valp = (*valp >= rightval); } else { DO (cp = parse_inequality (g, cp + 1, &rightval)); *valp = (*valp > rightval); } break; } return cp; } static const char * parse_equality (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_inequality (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '=': if (cp[1] == '=') cp++; DO (cp = parse_equality (g, cp + 1, &rightval)); *valp = (*valp == rightval); break; case '!': if (cp[1] != '=') break; DO (cp = parse_equality (g, cp + 2, &rightval)); *valp = (*valp != rightval); break; } return cp; } static const char * parse_band (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_equality (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '&': if (cp[1] != '&') { DO (cp = parse_band (g, cp + 1, &rightval)); *valp = (*valp & rightval); } break; } return cp; } static const char * parse_bxor (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_band (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '^': DO (cp = parse_bxor (g, cp + 1, &rightval)); *valp = (*valp ^ rightval); break; } return cp; } static const char * parse_bor (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_bxor (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '|': if (cp[1] != '|') { DO (cp = parse_bor (g, cp + 1, &rightval)); *valp = (*valp | rightval); } break; } return cp; } static const char * parse_land (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_bor (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '&': if (cp[1] != '&') return CALLFUNC(g, handle_error) (g, cp, "&&"); DO (cp = parse_land (g, cp + 2, &rightval)); *valp = (*valp && rightval); break; } return cp; } static const char * parse_lor (IfParser *g, const char *cp, long *valp) { long rightval; DO (cp = parse_land (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '|': if (cp[1] != '|') return CALLFUNC(g, handle_error) (g, cp, "||"); DO (cp = parse_lor (g, cp + 2, &rightval)); *valp = (*valp || rightval); break; } return cp; } static const char * parse_cond(IfParser *g, const char *cp, long *valp) { long trueval, falseval; DO (cp = parse_lor (g, cp, valp)); SKIPSPACE (cp); switch (*cp) { case '?': DO (cp = parse_cond (g, cp + 1, &trueval)); SKIPSPACE (cp); if (*cp != ':') return CALLFUNC(g, handle_error) (g, cp, ":"); DO (cp = parse_cond (g, cp + 1, &falseval)); *valp = (*valp ? trueval : falseval); break; } return cp; } /**************************************************************************** External Entry Points ****************************************************************************/ const char * ParseIfExpression (IfParser *g, const char *cp, long *valp) { return parse_cond (g, cp, valp); } jss-4.4.3/jss/coreconf/mkdepend/ifparser.h000066400000000000000000000052201326145000000204570ustar00rootroot00000000000000/* * $Xorg: ifparser.h,v 1.3 2000/08/17 19:41:51 cpqbld Exp $ * * Copyright 1992 Network Computing Devices, Inc. * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, provided * that the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Network Computing Devices may not be * used in advertising or publicity pertaining to distribution of the software * without specific, written prior permission. Network Computing Devices makes * no representations about the suitability of this software for any purpose. * It is provided ``as is'' without express or implied warranty. * * NETWORK COMPUTING DEVICES DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, * IN NO EVENT SHALL NETWORK COMPUTING DEVICES BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Jim Fulton * Network Computing Devices, Inc. * * Simple if statement processor * * This module can be used to evaluate string representations of C language * if constructs. It accepts the following grammar: * * EXPRESSION := VALUE * | VALUE BINOP EXPRESSION * | VALUE '?' EXPRESSION ':' EXPRESSION * * VALUE := '(' EXPRESSION ')' * | '!' VALUE * | '-' VALUE * | '~' VALUE * | 'defined' '(' variable ')' * | variable * | number * * BINOP := '*' | '/' | '%' * | '+' | '-' * | '<<' | '>>' * | '<' | '>' | '<=' | '>=' * | '==' | '!=' * | '&' | '^' | '|' * | '&&' | '||' * * The normal C order of precedence is supported. * * * External Entry Points: * * ParseIfExpression parse a string for #if */ /* $XFree86: xc/config/makedepend/ifparser.h,v 3.5 2001/07/25 15:04:40 dawes Exp $ */ #include typedef int Bool; #define False 0 #define True 1 typedef struct _if_parser { struct { /* functions */ const char *(*handle_error) (struct _if_parser *, const char *, const char *); long (*eval_variable) (struct _if_parser *, const char *, int); int (*eval_defined) (struct _if_parser *, const char *, int); } funcs; char *data; } IfParser; const char *ParseIfExpression ( IfParser *, const char *, long * ); jss-4.4.3/jss/coreconf/mkdepend/imakemdep.h000066400000000000000000000363671326145000000206200ustar00rootroot00000000000000 /* $XConsortium: imakemdep.h,v 1.83 95/04/07 19:47:46 kaleb Exp $ */ /* $XFree86: xc/config/imake/imakemdep.h,v 3.12 1995/07/08 10:22:17 dawes Exp $ */ /* Copyright (c) 1993, 1994 X Consortium Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium. */ /* * This file contains machine-dependent constants for the imake utility. * When porting imake, read each of the steps below and add in any necessary * definitions. In general you should *not* edit ccimake.c or imake.c! */ #ifdef CCIMAKE /* * Step 1: imake_ccflags * Define any special flags that will be needed to get imake.c to compile. * These will be passed to the compile along with the contents of the * make variable BOOTSTRAPCFLAGS. */ #ifdef hpux #ifdef hp9000s800 #define imake_ccflags "-DSYSV" #else #define imake_ccflags "-Wc,-Nd4000,-Ns3000 -DSYSV" #endif #endif #if defined(macII) || defined(_AUX_SOURCE) #define imake_ccflags "-DmacII -DSYSV" #endif #ifdef stellar #define imake_ccflags "-DSYSV" #endif #if defined(USL) || defined(Oki) || defined(NCR) #define imake_ccflags "-Xc -DSVR4" #endif #ifdef sony #if defined(SYSTYPE_SYSV) || defined(_SYSTYPE_SYSV) #define imake_ccflags "-DSVR4" #else #include #if NEWSOS < 41 #define imake_ccflags "-Dbsd43 -DNOSTDHDRS" #else #if NEWSOS < 42 #define imake_ccflags "-Dbsd43" #endif #endif #endif #endif #ifdef _CRAY #define imake_ccflags "-DSYSV -DUSG" #endif #if defined(_IBMR2) || defined(aix) #define imake_ccflags "-Daix -DSYSV" #endif #ifdef Mips # if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43) # define imake_ccflags "-DBSD43" # else # define imake_ccflags "-DSYSV" # endif #endif #ifdef is68k #define imake_ccflags "-Dluna -Duniosb" #endif #ifdef SYSV386 # ifdef SVR4 # define imake_ccflags "-Xc -DSVR4" # else # define imake_ccflags "-DSYSV" # endif #endif #ifdef SVR4 # ifdef i386 # define imake_ccflags "-Xc -DSVR4" # endif #endif #ifdef SYSV # ifdef i386 # define imake_ccflags "-DSYSV" # endif #endif #ifdef __convex__ #define imake_ccflags "-fn -tm c1" #endif #ifdef apollo #define imake_ccflags "-DX_NOT_POSIX" #endif #ifdef WIN32 #define imake_ccflags "-nologo -batch -D__STDC__" #endif #ifdef __uxp__ #define imake_ccflags "-DSVR4 -DANSICPP" #endif #ifdef __sxg__ #define imake_ccflags "-DSYSV -DUSG -DNOSTDHDRS" #endif #ifdef sequent #define imake_ccflags "-DX_NOT_STDC_ENV -DX_NOT_POSIX" #endif #ifdef _SEQUENT_ #define imake_ccflags "-DSYSV -DUSG" #endif #if defined(SX) || defined(PC_UX) #define imake_ccflags "-DSYSV" #endif #ifdef nec_ews_svr2 #define imake_ccflags "-DUSG" #endif #if defined(nec_ews_svr4) || defined(_nec_ews_svr4) || defined(_nec_up) || defined(_nec_ft) #define imake_ccflags "-DSVR4" #endif #ifdef MACH #define imake_ccflags "-DNOSTDHDRS" #endif /* this is for OS/2 under EMX. This won't work with DOS */ #if defined(__EMX__) #define imake_ccflags "-DBSD43" #endif #else /* not CCIMAKE */ #ifndef MAKEDEPEND /* * Step 2: dup2 * If your OS doesn't have a dup2() system call to duplicate one file * descriptor onto another, define such a mechanism here (if you don't * already fall under the existing category(ies). */ #if defined(SYSV) && !defined(_CRAY) && !defined(Mips) && !defined(_SEQUENT_) #define dup2(fd1,fd2) ((fd1 == fd2) ? fd1 : (close(fd2), \ fcntl(fd1, F_DUPFD, fd2))) #endif /* * Step 3: FIXUP_CPP_WHITESPACE * If your cpp collapses tabs macro expansions into a single space and * replaces escaped newlines with a space, define this symbol. This will * cause imake to attempt to patch up the generated Makefile by looking * for lines that have colons in them (this is why the rules file escapes * all colons). One way to tell if you need this is to see whether or not * your Makefiles have no tabs in them and lots of @@ strings. */ #if defined(sun) || defined(SYSV) || defined(SVR4) || defined(hcx) || defined(WIN32) || (defined(AMOEBA) && defined(CROSS_COMPILE)) #define FIXUP_CPP_WHITESPACE #endif #ifdef WIN32 #define REMOVE_CPP_LEADSPACE #define INLINE_SYNTAX #define MAGIC_MAKE_VARS #endif #ifdef __minix_vmd #define FIXUP_CPP_WHITESPACE #endif /* * Step 4: USE_CC_E, DEFAULT_CC, DEFAULT_CPP * If you want to use cc -E instead of cpp, define USE_CC_E. * If use cc -E but want a different compiler, define DEFAULT_CC. * If the cpp you need is not in /lib/cpp, define DEFAULT_CPP. */ #ifdef hpux #define USE_CC_E #endif #ifdef WIN32 #define USE_CC_E #define DEFAULT_CC "cl" #endif #ifdef apollo #define DEFAULT_CPP "/usr/lib/cpp" #endif #if defined(_IBMR2) && !defined(DEFAULT_CPP) #define DEFAULT_CPP "/usr/lpp/X11/Xamples/util/cpp/cpp" #endif #if defined(sun) && defined(SVR4) #define DEFAULT_CPP "/usr/ccs/lib/cpp" #endif #ifdef __bsdi__ #define DEFAULT_CPP "/usr/bin/cpp" #endif #ifdef __uxp__ #define DEFAULT_CPP "/usr/ccs/lib/cpp" #endif #ifdef __sxg__ #define DEFAULT_CPP "/usr/lib/cpp" #endif #ifdef _CRAY #define DEFAULT_CPP "/lib/pcpp" #endif #if defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) #define DEFAULT_CPP "/usr/libexec/cpp" #endif #ifdef MACH #define USE_CC_E #endif #ifdef __minix_vmd #define DEFAULT_CPP "/usr/lib/cpp" #endif #if defined(__EMX__) /* expects cpp in PATH */ #define DEFAULT_CPP "cpp" #endif /* * Step 5: cpp_argv * The following table contains the flags that should be passed * whenever a Makefile is being generated. If your preprocessor * doesn't predefine any unique symbols, choose one and add it to the * end of this table. Then, do the following: * * a. Use this symbol in Imake.tmpl when setting MacroFile. * b. Put this symbol in the definition of BootstrapCFlags in your * .cf file. * c. When doing a make World, always add "BOOTSTRAPCFLAGS=-Dsymbol" * to the end of the command line. * * Note that you may define more than one symbol (useful for platforms * that support multiple operating systems). */ #define ARGUMENTS 50 /* number of arguments in various arrays */ char *cpp_argv[ARGUMENTS] = { "cc", /* replaced by the actual program to exec */ "-I.", /* add current directory to include path */ #ifdef unix "-Uunix", /* remove unix symbol so that filename unix.c okay */ #endif #if defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(MACH) # ifdef __i386__ "-D__i386__", # endif # ifdef __x86_64__ "-D__x86_64__", # endif # ifdef __GNUC__ "-traditional", # endif #endif #ifdef M4330 "-DM4330", /* Tektronix */ #endif #ifdef M4310 "-DM4310", /* Tektronix */ #endif #if defined(macII) || defined(_AUX_SOURCE) "-DmacII", /* Apple A/UX */ #endif #ifdef USL "-DUSL", /* USL */ #endif #ifdef sony "-Dsony", /* Sony */ #if !defined(SYSTYPE_SYSV) && !defined(_SYSTYPE_SYSV) && NEWSOS < 42 "-Dbsd43", #endif #endif #ifdef _IBMR2 "-D_IBMR2", /* IBM RS-6000 (we ensured that aix is defined above */ #ifndef aix #define aix /* allow BOOTSTRAPCFLAGS="-D_IBMR2" */ #endif #endif /* _IBMR2 */ #ifdef aix "-Daix", /* AIX instead of AOS */ #ifndef ibm #define ibm /* allow BOOTSTRAPCFLAGS="-Daix" */ #endif #endif /* aix */ #ifdef ibm "-Dibm", /* IBM PS/2 and RT under both AOS and AIX */ #endif #ifdef luna "-Dluna", /* OMRON luna 68K and 88K */ #ifdef luna1 "-Dluna1", #endif #ifdef luna88k /* need not on UniOS-Mach Vers. 1.13 */ "-traditional", /* for some older version */ #endif /* instead of "-DXCOMM=\\#" */ #ifdef uniosb "-Duniosb", #endif #ifdef uniosu "-Duniosu", #endif #endif /* luna */ #ifdef _CRAY /* Cray */ "-Ucray", #endif #ifdef Mips "-DMips", /* Define and use Mips for Mips Co. OS/mach. */ # if defined(SYSTYPE_BSD) || defined(BSD) || defined(BSD43) "-DBSD43", /* Mips RISCOS supports two environments */ # else "-DSYSV", /* System V environment is the default */ # endif #endif /* Mips */ #ifdef MOTOROLA "-DMOTOROLA", /* Motorola Delta Systems */ # ifdef SYSV "-DSYSV", # endif # ifdef SVR4 "-DSVR4", # endif #endif /* MOTOROLA */ #ifdef i386 "-Di386", # ifdef SVR4 "-DSVR4", # endif # ifdef SYSV "-DSYSV", # ifdef ISC "-DISC", # ifdef ISC40 "-DISC40", /* ISC 4.0 */ # else # ifdef ISC202 "-DISC202", /* ISC 2.0.2 */ # else # ifdef ISC30 "-DISC30", /* ISC 3.0 */ # else "-DISC22", /* ISC 2.2.1 */ # endif # endif # endif # endif # ifdef SCO "-DSCO", # ifdef SCO324 "-DSCO324", # endif # endif # endif # ifdef ESIX "-DESIX", # endif # ifdef ATT "-DATT", # endif # ifdef DELL "-DDELL", # endif #endif #ifdef SYSV386 /* System V/386 folks, obsolete */ "-Di386", # ifdef SVR4 "-DSVR4", # endif # ifdef ISC "-DISC", # ifdef ISC40 "-DISC40", /* ISC 4.0 */ # else # ifdef ISC202 "-DISC202", /* ISC 2.0.2 */ # else # ifdef ISC30 "-DISC30", /* ISC 3.0 */ # else "-DISC22", /* ISC 2.2.1 */ # endif # endif # endif # endif # ifdef SCO "-DSCO", # ifdef SCO324 "-DSCO324", # endif # endif # ifdef ESIX "-DESIX", # endif # ifdef ATT "-DATT", # endif # ifdef DELL "-DDELL", # endif #endif #ifdef __osf__ "-D__osf__", # ifdef __mips__ "-D__mips__", # endif # ifdef __alpha "-D__alpha", # endif # ifdef __i386__ "-D__i386__", # endif # ifdef __GNUC__ "-traditional", # endif #endif #ifdef Oki "-DOki", #endif #ifdef sun #ifdef SVR4 "-DSVR4", #endif #endif #ifdef WIN32 "-DWIN32", "-nologo", "-batch", "-D__STDC__", #endif #ifdef NCR "-DNCR", /* NCR */ #endif #ifdef linux "-traditional", "-Dlinux", #endif #ifdef __uxp__ "-D__uxp__", #endif #ifdef __sxg__ "-D__sxg__", #endif #ifdef nec_ews_svr2 "-Dnec_ews_svr2", #endif #ifdef AMOEBA "-DAMOEBA", # ifdef CROSS_COMPILE "-DCROSS_COMPILE", # ifdef CROSS_i80386 "-Di80386", # endif # ifdef CROSS_sparc "-Dsparc", # endif # ifdef CROSS_mc68000 "-Dmc68000", # endif # else # ifdef i80386 "-Di80386", # endif # ifdef sparc "-Dsparc", # endif # ifdef mc68000 "-Dmc68000", # endif # endif #endif #ifdef __minix_vmd "-Dminix", #endif #if defined(__EMX__) "-traditional", "-Demxos2", #endif }; #else /* else MAKEDEPEND */ /* * Step 6: predefs * If your compiler and/or preprocessor define any specific symbols, add * them to the the following table. The definition of struct symtab is * in util/makedepend/def.h. */ #define QUOTEIT(x) #x #define QUOTEEXPANSION(x) QUOTEIT(x) struct symtab predefs[] = { #ifdef apollo {"apollo", "1"}, #endif #ifdef ibm032 {"ibm032", "1"}, #endif #ifdef ibm {"ibm", "1"}, #endif #ifdef aix {"aix", "1"}, #endif #ifdef sun {"sun", "1"}, #endif #ifdef sun2 {"sun2", "1"}, #endif #ifdef sun3 {"sun3", "1"}, #endif #ifdef sun4 {"sun4", "1"}, #endif #ifdef sparc {"sparc", "1"}, #endif #ifdef __sparc__ {"__sparc__", "1"}, #endif #ifdef hpux {"hpux", "1"}, #endif #ifdef __hpux {"__hpux", "1"}, #endif #ifdef __hp9000s800 {"__hp9000s800", "1"}, #endif #ifdef __hp9000s700 {"__hp9000s700", "1"}, #endif #ifdef vax {"vax", "1"}, #endif #ifdef VMS {"VMS", "1"}, #endif #ifdef cray {"cray", "1"}, #endif #ifdef CRAY {"CRAY", "1"}, #endif #ifdef _CRAY {"_CRAY", "1"}, #endif #ifdef att {"att", "1"}, #endif #ifdef mips {"mips", "1"}, #endif #ifdef __mips__ {"__mips__", "1"}, #endif #ifdef ultrix {"ultrix", "1"}, #endif #ifdef stellar {"stellar", "1"}, #endif #ifdef mc68000 {"mc68000", "1"}, #endif #ifdef mc68020 {"mc68020", "1"}, #endif #ifdef __GNUC__ {"__GNUC__", "1"}, #endif #if __STDC__ {"__STDC__", "1"}, #endif #ifdef __HIGHC__ {"__HIGHC__", "1"}, #endif #ifdef CMU {"CMU", "1"}, #endif #ifdef luna {"luna", "1"}, #ifdef luna1 {"luna1", "1"}, #endif #ifdef luna2 {"luna2", "1"}, #endif #ifdef luna88k {"luna88k", "1"}, #endif #ifdef uniosb {"uniosb", "1"}, #endif #ifdef uniosu {"uniosu", "1"}, #endif #endif #ifdef ieeep754 {"ieeep754", "1"}, #endif #ifdef is68k {"is68k", "1"}, #endif #ifdef m68k {"m68k", "1"}, #endif #ifdef m88k {"m88k", "1"}, #endif #ifdef __m88k__ {"__m88k__", "1"}, #endif #ifdef bsd43 {"bsd43", "1"}, #endif #ifdef hcx {"hcx", "1"}, #endif #ifdef sony {"sony", "1"}, #ifdef SYSTYPE_SYSV {"SYSTYPE_SYSV", "1"}, #endif #ifdef _SYSTYPE_SYSV {"_SYSTYPE_SYSV", "1"}, #endif #endif #ifdef __OSF__ {"__OSF__", "1"}, #endif #ifdef __osf__ {"__osf__", "1"}, #endif #ifdef __alpha {"__alpha", "1"}, #endif #ifdef __DECC {"__DECC", "1"}, #endif #ifdef __decc {"__decc", "1"}, #endif #ifdef __uxp__ {"__uxp__", "1"}, #endif #ifdef __sxg__ {"__sxg__", "1"}, #endif #ifdef _SEQUENT_ {"_SEQUENT_", "1"}, {"__STDC__", "1"}, #endif #ifdef __bsdi__ {"__bsdi__", "1"}, #endif #ifdef nec_ews_svr2 {"nec_ews_svr2", "1"}, #endif #ifdef nec_ews_svr4 {"nec_ews_svr4", "1"}, #endif #ifdef _nec_ews_svr4 {"_nec_ews_svr4", "1"}, #endif #ifdef _nec_up {"_nec_up", "1"}, #endif #ifdef SX {"SX", "1"}, #endif #ifdef nec {"nec", "1"}, #endif #ifdef _nec_ft {"_nec_ft", "1"}, #endif #ifdef PC_UX {"PC_UX", "1"}, #endif #ifdef sgi {"sgi", "1"}, #endif #ifdef __sgi {"__sgi", "1"}, #endif #ifdef __FreeBSD__ {"__FreeBSD__", "1"}, #endif #ifdef __NetBSD__ {"__NetBSD__", "1"}, #endif #ifdef __OpenBSD__ {"__OpenBSD__", "1"}, #endif #ifdef __EMX__ {"__EMX__", "1"}, #endif /* ADDED THE FOLLOWING SYMBOLS FOR WINDOWS */ #ifdef _WIN32 {"_WIN32", QUOTEEXPANSION(_WIN32) }, #endif #ifdef _WIN64 {"_WIN64", QUOTEEXPANSION(_WIN64) }, #endif #ifdef _X86 {"_X86", QUOTEEXPANSION(_X86) }, #endif #ifdef _X86_ {"_X86_", QUOTEEXPANSION(_X86_) }, #endif #ifdef _X86_64 {"_X86_64", QUOTEEXPANSION(_X86_64) }, #endif #ifdef _X86_64_ {"_X86_64_", QUOTEEXPANSION(_X86_64_) }, #endif #ifdef _DEBUG {"_DEBUG", QUOTEEXPANSION(_DEBUG) }, #endif #ifdef _DLL {"_DLL", QUOTEEXPANSION(_DLL) }, #endif #ifdef _M_IX86 {"_M_IX86", QUOTEEXPANSION(_M_IX86) }, #endif #ifdef _M_X64 {"_M_X64", QUOTEEXPANSION(_M_X64) }, #endif #ifdef _MSC_FULL_VER {"_MSC_FULL_VER", QUOTEEXPANSION(_MSC_FULL_VER) }, #endif #ifdef _MSC_VER {"_MSC_VER", QUOTEEXPANSION(_MSC_VER) }, #endif #ifdef _MSVC_RUNTIME_CHECKS {"_MSVC_RUNTIME_CHECKS", QUOTEEXPANSION(_MSVC_RUNTIME_CHECKS) }, #endif #ifdef _MT {"_MT", QUOTEEXPANSION(_MT) }, #endif #ifdef _CHAR_UNSIGNED {"_CHAR_UNSIGNED", QUOTEEXPANSION(_CHAR_UNSIGNED) }, #endif /* add any additional symbols before this line */ {NULL, NULL} }; #endif /* MAKEDEPEND */ #endif /* CCIMAKE */ jss-4.4.3/jss/coreconf/mkdepend/include.c000066400000000000000000000177021326145000000202720ustar00rootroot00000000000000/* $Xorg: include.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */ /* Copyright (c) 1993, 1994, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/config/makedepend/include.c,v 3.7 2001/12/14 19:53:20 dawes Exp $ */ #include "def.h" #ifdef _MSC_VER #include static int does_file_exist(char *file) { WIN32_FILE_ATTRIBUTE_DATA data; BOOL b = GetFileAttributesExA(file, GetFileExInfoStandard, &data); if (!b) return 0; return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0; } #else static int does_file_exist(char *file) { struct stat sb; return stat(file, &sb) == 0 && !S_ISDIR(sb.st_mode); } #endif extern struct inclist inclist[ MAXFILES ], *inclistp, *inclistnext; extern char *includedirs[ ], **includedirsnext; extern char *notdotdot[ ]; extern boolean show_where_not; extern boolean warn_multiple; static boolean isdot(char *p) { if(p && *p++ == '.' && *p++ == '\0') return(TRUE); return(FALSE); } static boolean isdotdot(char *p) { if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0') return(TRUE); return(FALSE); } static boolean issymbolic(char *dir, char *component) { #ifdef S_IFLNK struct stat st; char buf[ BUFSIZ ], **pp; sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component); for (pp=notdotdot; *pp; pp++) if (strcmp(*pp, buf) == 0) return (TRUE); if (lstat(buf, &st) == 0 && (st.st_mode & S_IFMT) == S_IFLNK) { *pp++ = copy(buf); if (pp >= ¬dotdot[ MAXDIRS ]) fatalerr("out of .. dirs, increase MAXDIRS\n"); return(TRUE); } #endif return(FALSE); } /* * Occasionally, pathnames are created that look like .../x/../y * Any of the 'x/..' sequences within the name can be eliminated. * (but only if 'x' is not a symbolic link!!) */ static void remove_dotdot(char *path) { register char *end, *from, *to, **cp; char *components[ MAXFILES ], newpath[ BUFSIZ ]; boolean component_copied; /* * slice path up into components. */ to = newpath; if (*path == '/') *to++ = '/'; *to = '\0'; cp = components; for (from=end=path; *end; end++) if (*end == '/') { while (*end == '/') *end++ = '\0'; if (*from) *cp++ = from; from = end; } *cp++ = from; *cp = NULL; /* * Recursively remove all 'x/..' component pairs. */ cp = components; while(*cp) { if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1)) && !issymbolic(newpath, *cp)) { char **fp = cp + 2; char **tp = cp; do *tp++ = *fp; /* move all the pointers down */ while (*fp++); if (cp != components) cp--; /* go back and check for nested ".." */ } else { cp++; } } /* * Concatenate the remaining path elements. */ cp = components; component_copied = FALSE; while(*cp) { if (component_copied) *to++ = '/'; component_copied = TRUE; for (from = *cp; *from; ) *to++ = *from++; *to = '\0'; cp++; } *to++ = '\0'; /* * copy the reconstituted path back to our pointer. */ strcpy(path, newpath); } /* * Add an include file to the list of those included by 'file'. */ struct inclist * newinclude(char *newfile, char *incstring) { register struct inclist *ip; /* * First, put this file on the global list of include files. */ ip = inclistp++; if (inclistp == inclist + MAXFILES - 1) fatalerr("out of space: increase MAXFILES\n"); ip->i_file = copy(newfile); if (incstring == NULL) ip->i_incstring = ip->i_file; else ip->i_incstring = copy(incstring); inclistnext = inclistp; return(ip); } void included_by(struct inclist *ip, struct inclist *newfile) { register int i; if (ip == NULL) return; /* * Put this include file (newfile) on the list of files included * by 'file'. If 'file' is NULL, then it is not an include * file itself (i.e. was probably mentioned on the command line). * If it is already on the list, don't stick it on again. */ if (ip->i_list == NULL) { ip->i_list = (struct inclist **) malloc(sizeof(struct inclist *) * ++ip->i_listlen); ip->i_merged = (boolean *) malloc(sizeof(boolean) * ip->i_listlen); } else { for (i=0; ii_listlen; i++) if (ip->i_list[ i ] == newfile) { i = strlen(newfile->i_file); if (!(ip->i_flags & INCLUDED_SYM) && !(i > 2 && newfile->i_file[i-1] == 'c' && newfile->i_file[i-2] == '.')) { /* only bitch if ip has */ /* no #include SYMBOL lines */ /* and is not a .c file */ if (warn_multiple) { warning("%s includes %s more than once!\n", ip->i_file, newfile->i_file); warning1("Already have\n"); for (i=0; ii_listlen; i++) warning1("\t%s\n", ip->i_list[i]->i_file); } } return; } ip->i_list = (struct inclist **) realloc(ip->i_list, sizeof(struct inclist *) * ++ip->i_listlen); ip->i_merged = (boolean *) realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen); } ip->i_list[ ip->i_listlen-1 ] = newfile; ip->i_merged[ ip->i_listlen-1 ] = FALSE; } void inc_clean (void) { register struct inclist *ip; for (ip = inclist; ip < inclistp; ip++) { ip->i_flags &= ~MARKED; } } struct inclist * inc_path(char *file, char *include, int type) { static char path[ BUFSIZ ]; register char **pp, *p; register struct inclist *ip; /* * Check all previously found include files for a path that * has already been expanded. */ if ((type == INCLUDE) || (type == INCLUDEDOT)) inclistnext = inclist; ip = inclistnext; for (; ip->i_file; ip++) { if ((strcmp(ip->i_incstring, include) == 0) && !(ip->i_flags & INCLUDED_SYM)) { inclistnext = ip + 1; return ip; } } if (inclistnext == inclist) { /* * If the path was surrounded by "" or is an absolute path, * then check the exact path provided. */ if ((type == INCLUDEDOT) || (type == INCLUDENEXTDOT) || (*include == '/')) { if (does_file_exist(include)) return newinclude(include, include); if (show_where_not) warning1("\tnot in %s\n", include); } /* * If the path was surrounded by "" see if this include file is * in the directory of the file being parsed. */ if ((type == INCLUDEDOT) || (type == INCLUDENEXTDOT)) { for (p=file+strlen(file); p>file; p--) if (*p == '/') break; if (p == file) { strcpy(path, include); } else { strncpy(path, file, (p-file) + 1); path[ (p-file) + 1 ] = '\0'; strcpy(path + (p-file) + 1, include); } remove_dotdot(path); if (does_file_exist(path)) return newinclude(path, include); if (show_where_not) warning1("\tnot in %s\n", path); } } /* * Check the include directories specified. Standard include dirs * should be at the end. */ if ((type == INCLUDE) || (type == INCLUDEDOT)) includedirsnext = includedirs; pp = includedirsnext; for (; *pp; pp++) { sprintf(path, "%s/%s", *pp, include); remove_dotdot(path); if (does_file_exist(path)) { includedirsnext = pp + 1; return newinclude(path, include); } if (show_where_not) warning1("\tnot in %s\n", path); } return NULL; } jss-4.4.3/jss/coreconf/mkdepend/main.c000066400000000000000000000461771326145000000176030ustar00rootroot00000000000000/* $Xorg: main.c,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ */ /* Copyright (c) 1993, 1994, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/config/makedepend/main.c,v 3.32 2003/03/26 20:43:48 tsi Exp $ */ #include "def.h" #ifdef hpux #define sigvec sigvector #endif /* hpux */ #ifdef X_POSIX_C_SOURCE #define _POSIX_C_SOURCE X_POSIX_C_SOURCE #include #undef _POSIX_C_SOURCE #else #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE) #include #else #define _POSIX_SOURCE #include #undef _POSIX_SOURCE #endif #endif #include #ifdef _WIN32 #include #endif #ifdef MINIX #define USE_CHMOD 1 #endif #ifdef DEBUG int _debugmask; #endif /* #define DEBUG_DUMP */ #ifdef DEBUG_DUMP #define DBG_PRINT(file, fmt, args) fprintf(file, fmt, args) #else #define DBG_PRINT(file, fmt, args) /* empty */ #endif #define DASH_INC_PRE "#include \"" #define DASH_INC_POST "\"" char *ProgramName; char *directives[] = { "if", "ifdef", "ifndef", "else", "endif", "define", "undef", "include", "line", "pragma", "error", "ident", "sccs", "elif", "eject", "warning", "include_next", NULL }; #define MAKEDEPEND #include "imakemdep.h" /* from config sources */ #undef MAKEDEPEND struct inclist inclist[ MAXFILES ], *inclistp = inclist, *inclistnext = inclist, maininclist; static char *filelist[ MAXFILES ]; char *includedirs[ MAXDIRS + 1 ], **includedirsnext = includedirs; char *notdotdot[ MAXDIRS ]; static int cmdinc_count = 0; static char *cmdinc_list[ 2 * MAXINCFILES ]; char *objprefix = ""; char *objsuffix = OBJSUFFIX; static char *startat = "# DO NOT DELETE"; int width = 78; static boolean append = FALSE; boolean printed = FALSE; boolean verbose = FALSE; boolean show_where_not = FALSE; /* Warn on multiple includes of same file */ boolean warn_multiple = FALSE; static void setfile_cmdinc(struct filepointer *filep, long count, char **list); static void redirect(char *line, char *makefile); static #ifdef SIGNALRETURNSINT int #else void #endif catch (int sig) { fflush (stdout); fatalerr ("got signal %d\n", sig); } #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(__UNIXOS2__) || defined(Lynx_22) || defined(__CYGWIN__) #define USGISH #endif #ifndef USGISH #ifdef X_NOT_POSIX #define sigaction sigvec #define sa_handler sv_handler #define sa_mask sv_mask #define sa_flags sv_flags #endif struct sigaction sig_act; #endif /* USGISH */ int main(int argc, char *argv[]) { char **fp = filelist; char **incp = includedirs; char *p; struct inclist *ip; char *makefile = NULL; struct filepointer *filecontent; struct symtab *psymp = predefs; char *endmarker = NULL; char *defincdir = NULL; char **undeflist = NULL; int numundefs = 0, i; register char offset; ProgramName = argv[0]; while (psymp->s_name) { define2(psymp->s_name, psymp->s_value, &maininclist); psymp++; } if (argc == 2 && argv[1][0] == '@') { struct stat ast; int afd; char *args; char **nargv; int nargc; char quotechar = '\0'; nargc = 1; if ((afd = open(argv[1]+1, O_RDONLY)) < 0) fatalerr("cannot open \"%s\"\n", argv[1]+1); fstat(afd, &ast); args = (char *)malloc(ast.st_size + 1); if ((ast.st_size = read(afd, args, ast.st_size)) < 0) fatalerr("failed to read %s\n", argv[1]+1); args[ast.st_size] = '\0'; close(afd); for (p = args; *p; p++) { if (quotechar) { if (quotechar == '\\' || (*p == quotechar && p[-1] != '\\')) quotechar = '\0'; continue; } switch (*p) { case '\\': case '"': case '\'': quotechar = *p; break; case ' ': case '\n': *p = '\0'; if (p > args && p[-1]) nargc++; break; } } if (p[-1]) nargc++; nargv = (char **)malloc(nargc * sizeof(char *)); nargv[0] = argv[0]; argc = 1; for (p = args; argc < nargc; p += strlen(p) + 1) if (*p) nargv[argc++] = p; argv = nargv; } for(argc--, argv++; argc; argc--, argv++) { /* if looking for endmarker then check before parsing */ if (endmarker && strcmp (endmarker, *argv) == 0) { endmarker = NULL; continue; } if (**argv != '-') { /* treat +thing as an option for C++ */ if (endmarker && **argv == '+') continue; *fp++ = argv[0]; continue; } switch(argv[0][1]) { case '-': endmarker = &argv[0][2]; if (endmarker[0] == '\0') endmarker = "--"; break; case 'D': offset = 2; if (argv[0][2] == '\0') { argv++; argc--; offset = 0; } /* offset +1 here since first def letter * cannot be `=` */ for (p = argv[0] + offset + 1; *p; p++) if (*p == '=') { *p = ' '; break; } define(argv[0] + offset, &maininclist); break; case 'I': if (incp >= includedirs + MAXDIRS) fatalerr("Too many -I flags.\n"); *incp++ = argv[0]+2; if (**(incp-1) == '\0') { *(incp-1) = *(++argv); argc--; } break; case 'U': /* Undef's override all -D's so save them up */ numundefs++; if (numundefs == 1) undeflist = malloc(sizeof(char *)); else undeflist = realloc(undeflist, numundefs * sizeof(char *)); offset = 2; if (argv[0][2] == '\0') { argv++; argc--; offset = 0; } undeflist[numundefs - 1] = argv[0] + offset; break; case 'Y': defincdir = argv[0]+2; break; /* do not use if endmarker processing */ case 'a': if (endmarker) break; append = TRUE; break; case 'w': if (endmarker) break; if (argv[0][2] == '\0') { argv++; argc--; width = atoi(argv[0]); } else width = atoi(argv[0]+2); break; case 'o': if (endmarker) break; if (argv[0][2] == '\0') { argv++; argc--; objsuffix = argv[0]; } else objsuffix = argv[0]+2; break; case 'p': if (endmarker) break; if (argv[0][2] == '\0') { argv++; argc--; objprefix = argv[0]; } else objprefix = argv[0]+2; break; case 'v': if (endmarker) break; verbose = TRUE; #ifdef DEBUG if (argv[0][2]) _debugmask = atoi(argv[0]+2); #endif break; case 's': if (endmarker) break; startat = argv[0]+2; if (*startat == '\0') { startat = *(++argv); argc--; } if (*startat != '#') fatalerr("-s flag's value should start %s\n", "with '#'."); break; case 'f': if (endmarker) break; makefile = argv[0]+2; if (*makefile == '\0') { makefile = *(++argv); argc--; } break; case 'm': warn_multiple = TRUE; break; /* Ignore -O, -g so we can just pass ${CFLAGS} to makedepend */ case 'O': case 'g': break; case 'i': if (strcmp(&argv[0][1],"include") == 0) { char *buf; if (argc<2) fatalerr("option -include is a " "missing its parameter\n"); if (cmdinc_count >= MAXINCFILES) fatalerr("Too many -include flags.\n"); argc--; argv++; buf = malloc(strlen(DASH_INC_PRE) + strlen(argv[0]) + strlen(DASH_INC_POST) + 1); if(!buf) fatalerr("out of memory at " "-include string\n"); cmdinc_list[2 * cmdinc_count + 0] = argv[0]; cmdinc_list[2 * cmdinc_count + 1] = buf; cmdinc_count++; break; } /* intentional fall through */ default: if (endmarker) break; /* fatalerr("unknown opt = %s\n", argv[0]); */ warning("ignoring option %s\n", argv[0]); } } /* Now do the undefs from the command line */ for (i = 0; i < numundefs; i++) undefine(undeflist[i], &maininclist); if (numundefs > 0) free(undeflist); if (!defincdir) { #ifdef PREINCDIR if (incp >= includedirs + MAXDIRS) fatalerr("Too many -I flags.\n"); *incp++ = PREINCDIR; #endif #if defined(__UNIXOS2__) || defined(_MSC_VER) { #if defined(_MSC_VER) char *includepath = getenv("INCLUDE"); #else char *includepath = getenv("C_INCLUDE_PATH"); #endif /* can have more than one component */ if (includepath) { char *beg, *end; beg= (char*)strdup(includepath); for (;;) { end = (char*)strchr(beg,';'); if (end) *end = 0; if (incp >= includedirs + MAXDIRS) fatalerr("Too many include dirs\n"); *incp++ = beg; if (!end) break; beg = end+1; } } } #else /* !__UNIXOS2__ && !_MSC_VER, does not use INCLUDEDIR at all */ if (incp >= includedirs + MAXDIRS) fatalerr("Too many -I flags.\n"); *incp++ = INCLUDEDIR; #endif #ifdef EXTRAINCDIR if (incp >= includedirs + MAXDIRS) fatalerr("Too many -I flags.\n"); *incp++ = EXTRAINCDIR; #endif #ifdef POSTINCDIR if (incp >= includedirs + MAXDIRS) fatalerr("Too many -I flags.\n"); *incp++ = POSTINCDIR; #endif } else if (*defincdir) { if (incp >= includedirs + MAXDIRS) fatalerr("Too many -I flags.\n"); *incp++ = defincdir; } redirect(startat, makefile); /* * catch signals. */ #ifdef USGISH /* should really reset SIGINT to SIG_IGN if it was. */ #ifdef SIGHUP signal (SIGHUP, catch); #endif signal (SIGINT, catch); #ifdef SIGQUIT signal (SIGQUIT, catch); #endif signal (SIGILL, catch); #ifdef SIGBUS signal (SIGBUS, catch); #endif signal (SIGSEGV, catch); #ifdef SIGSYS signal (SIGSYS, catch); #endif #else sig_act.sa_handler = catch; #if defined(_POSIX_SOURCE) || !defined(X_NOT_POSIX) sigemptyset(&sig_act.sa_mask); sigaddset(&sig_act.sa_mask, SIGINT); sigaddset(&sig_act.sa_mask, SIGQUIT); #ifdef SIGBUS sigaddset(&sig_act.sa_mask, SIGBUS); #endif sigaddset(&sig_act.sa_mask, SIGILL); sigaddset(&sig_act.sa_mask, SIGSEGV); sigaddset(&sig_act.sa_mask, SIGHUP); sigaddset(&sig_act.sa_mask, SIGPIPE); #ifdef SIGSYS sigaddset(&sig_act.sa_mask, SIGSYS); #endif #else sig_act.sa_mask = ((1<<(SIGINT -1)) |(1<<(SIGQUIT-1)) #ifdef SIGBUS |(1<<(SIGBUS-1)) #endif |(1<<(SIGILL-1)) |(1<<(SIGSEGV-1)) |(1<<(SIGHUP-1)) |(1<<(SIGPIPE-1)) #ifdef SIGSYS |(1<<(SIGSYS-1)) #endif ); #endif /* _POSIX_SOURCE */ sig_act.sa_flags = 0; sigaction(SIGHUP, &sig_act, (struct sigaction *)0); sigaction(SIGINT, &sig_act, (struct sigaction *)0); sigaction(SIGQUIT, &sig_act, (struct sigaction *)0); sigaction(SIGILL, &sig_act, (struct sigaction *)0); #ifdef SIGBUS sigaction(SIGBUS, &sig_act, (struct sigaction *)0); #endif sigaction(SIGSEGV, &sig_act, (struct sigaction *)0); #ifdef SIGSYS sigaction(SIGSYS, &sig_act, (struct sigaction *)0); #endif #endif /* USGISH */ /* * now peruse through the list of files. */ for(fp=filelist; *fp; fp++) { DBG_PRINT(stderr,"file: %s\n",*fp); filecontent = getfile(*fp); setfile_cmdinc(filecontent, cmdinc_count, cmdinc_list); ip = newinclude(*fp, (char *)NULL); find_includes(filecontent, ip, ip, 0, FALSE); freefile(filecontent); recursive_pr_include(ip, ip->i_file, base_name(*fp)); inc_clean(); } if (printed) printf("\n"); return 0; } #ifdef __UNIXOS2__ /* * eliminate \r chars from file */ static int elim_cr(char *buf, int sz) { int i,wp; for (i= wp = 0; if_name = file; if ((fd = open(file, O_RDONLY)) < 0) { warning("cannot open \"%s\"\n", file); content->f_p = content->f_base = content->f_end = (char *)malloc(1); *content->f_p = '\0'; return(content); } fstat(fd, &st); content->f_base = (char *)malloc(st.st_size+1); if (content->f_base == NULL) fatalerr("cannot allocate mem\n"); if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0) fatalerr("failed to read %s\n", file); #ifdef __UNIXOS2__ st.st_size = elim_cr(content->f_base,st.st_size); #endif close(fd); content->f_len = st.st_size+1; content->f_p = content->f_base; content->f_end = content->f_base + st.st_size; *content->f_end = '\0'; content->f_line = 0; content->cmdinc_count = 0; content->cmdinc_list = NULL; content->cmdinc_line = 0; return(content); } void setfile_cmdinc(struct filepointer* filep, long count, char** list) { filep->cmdinc_count = count; filep->cmdinc_list = list; filep->cmdinc_line = 0; } void freefile(struct filepointer *fp) { free(fp->f_base); free(fp); } char *copy(char *str) { char *p = (char *)malloc(strlen(str) + 1); strcpy(p, str); return(p); } int match(char *str, char **list) { int i; for (i=0; *list; i++, list++) if (strcmp(str, *list) == 0) return(i); return(-1); } /* * Get the next line. We only return lines beginning with '#' since that * is all this program is ever interested in. */ char *getnextline(struct filepointer *filep) { char *p, /* walking pointer */ *eof, /* end of file pointer */ *bol; /* beginning of line pointer */ int lineno; /* line number */ boolean whitespace = FALSE; /* * Fake the "-include" line files in form of #include to the * start of each file. */ if (filep->cmdinc_line < filep->cmdinc_count) { char *inc = filep->cmdinc_list[2 * filep->cmdinc_line + 0]; char *buf = filep->cmdinc_list[2 * filep->cmdinc_line + 1]; filep->cmdinc_line++; sprintf(buf,"%s%s%s",DASH_INC_PRE,inc,DASH_INC_POST); DBG_PRINT(stderr,"%s\n",buf); return(buf); } p = filep->f_p; eof = filep->f_end; if (p >= eof) return((char *)NULL); lineno = filep->f_line; for (bol = p--; ++p < eof; ) { if ((bol == p) && ((*p == ' ') || (*p == '\t'))) { /* Consume leading white-spaces for this line */ while (((p+1) < eof) && ((*p == ' ') || (*p == '\t'))) { p++; bol++; } whitespace = TRUE; } if (*p == '/' && (p+1) < eof && *(p+1) == '*') { /* Consume C comments */ *(p++) = ' '; *(p++) = ' '; while (p < eof && *p) { if (*p == '*' && (p+1) < eof && *(p+1) == '/') { *(p++) = ' '; *(p++) = ' '; break; } if (*p == '\n') lineno++; *(p++) = ' '; } --p; } else if (*p == '/' && (p+1) < eof && *(p+1) == '/') { /* Consume C++ comments */ *(p++) = ' '; *(p++) = ' '; while (p < eof && *p) { if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') { *(p++) = ' '; lineno++; } else if (*p == '?' && (p+3) < eof && *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') { *(p++) = ' '; *(p++) = ' '; *(p++) = ' '; lineno++; } else if (*p == '\n') break; /* to process end of line */ *(p++) = ' '; } --p; } else if (*p == '\\' && (p+1) < eof && *(p+1) == '\n') { /* Consume backslash line terminations */ *(p++) = ' '; *p = ' '; lineno++; } else if (*p == '?' && (p+3) < eof && *(p+1) == '?' && *(p+2) == '/' && *(p+3) == '\n') { /* Consume trigraph'ed backslash line terminations */ *(p++) = ' '; *(p++) = ' '; *(p++) = ' '; *p = ' '; lineno++; } else if (*p == '\n') { lineno++; if (*bol == '#') { char *cp; *(p++) = '\0'; /* punt lines with just # (yacc generated) */ for (cp = bol+1; *cp && (*cp == ' ' || *cp == '\t'); cp++); if (*cp) goto done; --p; } bol = p+1; whitespace = FALSE; } } if (*bol != '#') bol = NULL; done: #if !defined(__UNIXOS2__) && !defined(_MSC_VER) && !defined(_WIN32) /* Don't print warnings for system header files */ if (bol && whitespace && !strstr(filep->f_name, INCLUDEDIR)) { warning("%s: non-portable whitespace encountered at line %d\n", filep->f_name, lineno); } #endif filep->f_p = p; filep->f_line = lineno; #ifdef DEBUG_DUMP if (bol) DBG_PRINT(stderr,"%s\n",bol); #endif return(bol); } /* * Strip the file name down to what we want to see in the Makefile. * It will have objprefix and objsuffix around it. */ char *base_name(char *file) { char *p; file = copy(file); for(p=file+strlen(file); p>file && *p != '.'; p--) ; if (*p == '.') *p = '\0'; return(file); } #if defined(USG) && !defined(CRAY) && !defined(SVR4) && !defined(__UNIXOS2__) && !defined(clipper) && !defined(__clipper__) int rename (char *from, char *to) { (void) unlink (to); if (link (from, to) == 0) { unlink (from); return 0; } else { return -1; } } #endif /* USGISH */ void redirect(char *line, char *makefile) { struct stat st; FILE *fdin, *fdout; char backup[ BUFSIZ ], buf[ BUFSIZ ]; boolean found = FALSE; int len; /* * if makefile is "-" then let it pour onto stdout. */ if (makefile && *makefile == '-' && *(makefile+1) == '\0') { puts(line); return; } /* * use a default makefile is not specified. */ if (!makefile) { if (stat("Makefile", &st) == 0) makefile = "Makefile"; else if (stat("makefile", &st) == 0) makefile = "makefile"; else fatalerr("[mM]akefile is not present\n"); } else stat(makefile, &st); if ((fdin = fopen(makefile, "r")) == NULL) fatalerr("cannot open \"%s\"\n", makefile); sprintf(backup, "%s.bak", makefile); unlink(backup); #if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__) fclose(fdin); #endif if (rename(makefile, backup) < 0) fatalerr("cannot rename %s to %s\n", makefile, backup); #if defined(WIN32) || defined(__UNIXOS2__) || defined(__CYGWIN__) if ((fdin = fopen(backup, "r")) == NULL) fatalerr("cannot open \"%s\"\n", backup); #endif if ((fdout = freopen(makefile, "w", stdout)) == NULL) fatalerr("cannot open \"%s\"\n", backup); len = strlen(line); while (!found && fgets(buf, BUFSIZ, fdin)) { if (*buf == '#' && strncmp(line, buf, len) == 0) found = TRUE; fputs(buf, fdout); } if (!found) { if (verbose) warning("Adding new delimiting line \"%s\" and dependencies...\n", line); puts(line); /* same as fputs(fdout); but with newline */ } else if (append) { while (fgets(buf, BUFSIZ, fdin)) { fputs(buf, fdout); } } fflush(fdout); #if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD) chmod(makefile, st.st_mode); #else fchmod(fileno(fdout), st.st_mode); #endif /* USGISH */ } void fatalerr(char *msg, ...) { va_list args; fprintf(stderr, "%s: error: ", ProgramName); va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); exit (1); } void warning(char *msg, ...) { va_list args; fprintf(stderr, "%s: warning: ", ProgramName); va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); } void warning1(char *msg, ...) { va_list args; va_start(args, msg); vfprintf(stderr, msg, args); va_end(args); } jss-4.4.3/jss/coreconf/mkdepend/mkdepend.man000066400000000000000000000227031326145000000207640ustar00rootroot00000000000000.\" $Xorg: mkdepend.man,v 1.5 2001/02/09 02:03:16 xorgcvs Exp $ .\" Copyright (c) 1993, 1994, 1998 The Open Group .\" .\" Permission to use, copy, modify, distribute, and sell this software and its .\" documentation for any purpose is hereby granted without fee, provided that .\" the above copyright notice appear in all copies and that both that .\" copyright notice and this permission notice appear in supporting .\" documentation. .\" .\" The above copyright notice and this permission notice shall be included in .\" all copies or substantial portions of the Software. .\" .\" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR .\" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, .\" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL .\" THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, .\" WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF .\" OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE .\" SOFTWARE. .\" .\" Except as contained in this notice, the name of The Open Group shall not .\" be used in advertising or otherwise to promote the sale, use or other .\" dealing in this Software without prior written authorization from The .\" Open Group. .\" .\" $XFree86: xc/config/makedepend/mkdepend.man,v 1.7 2002/12/14 02:39:45 dawes Exp $ .\" .TH MAKEDEPEND 1 __xorgversion__ .UC 4 .SH NAME makedepend \- create dependencies in makefiles .SH SYNOPSIS .B makedepend [ .BI \-D name\fB=\fPdef ] [ .BI \-D name ] [ .BI \-I includedir ] [ .BI \-Y includedir ] [ .B \-a ] [ .BI \-f makefile ] [ .BI \-include \ file ] [ .BI \-o objsuffix ] [ .BI \-p objprefix ] [ .BI \-s string ] [ .BI \-w width ] [ .B \-v ] [ .B \-m ] [ \-\^\- .I otheroptions \-\^\- ] .I sourcefile \&.\|.\|. .br .SH DESCRIPTION The .B makedepend program reads each .I sourcefile in sequence and parses it like a C-preprocessor, processing all .I #include, .I #define, .I #undef, .I #ifdef, .I #ifndef, .I #endif, .I #if, .I #elif and .I #else directives so that it can correctly tell which .I #include, directives would be used in a compilation. Any .I #include, directives can reference files having other .I #include directives, and parsing will occur in these files as well. .PP Every file that a .I sourcefile includes, directly or indirectly, is what .B makedepend calls a \fIdependency.\fP These dependencies are then written to a .I makefile in such a way that .B make(1) will know which object files must be recompiled when a dependency has changed. .PP By default, .B makedepend places its output in the file named .I makefile if it exists, otherwise .I Makefile. An alternate makefile may be specified with the .B \-f option. It first searches the makefile for the line .sp \& # DO NOT DELETE THIS LINE \-\^\- make depend depends on it. .sp or one provided with the .B \-s option, as a delimiter for the dependency output. If it finds it, it will delete everything following this to the end of the makefile and put the output after this line. If it doesn't find it, the program will append the string to the end of the makefile and place the output following that. For each .I sourcefile appearing on the command line, .B makedepend puts lines in the makefile of the form .sp sourcefile.o:\0dfile .\|.\|. .sp Where \fIsourcefile.o\fP is the name from the command line with its suffix replaced with ``.o'', and \fIdfile\fP is a dependency discovered in a .I #include directive while parsing .I sourcefile or one of the files it included. .SH EXAMPLE Normally, .B makedepend will be used in a makefile target so that typing ``make depend'' will bring the dependencies up to date for the makefile. For example, .nf SRCS\0=\0file1.c\0file2.c\0.\|.\|. CFLAGS\0=\0\-O\0\-DHACK\0\-I\^.\^.\^/foobar\0\-xyz depend: makedepend\0\-\^\-\0$(CFLAGS)\0\-\^\-\0$(SRCS) .fi .SH OPTIONS The program will ignore any option that it does not understand so that you may use the same arguments that you would for .B cc(1). .TP 5 .B \-D\fIname\fP=\fIdef\fP \fRor\fP \-D\fIname\fP Define. This places a definition for .I name in .B makedepend's symbol table. Without .I =def\| the symbol becomes defined as ``1''. .TP 5 .B \-I\fIincludedir\fP Include directory. This option tells .B makedepend to prepend .I includedir to its list of directories to search when it encounters a .I #include directive. By default, .B makedepend only searches the standard include directories (usually /usr/include and possibly a compiler-dependent directory). .TP 5 .B \-Y\fIincludedir\fP Replace all of the standard include directories with the single specified include directory; you can omit the .I includedir to simply prevent searching the standard include directories. .TP 5 .B \-a Append the dependencies to the end of the file instead of replacing them. .TP 5 .B \-f\fImakefile\fP Filename. This allows you to specify an alternate makefile in which .B makedepend can place its output. Specifying ``\-'' as the file name (i.e., \fB\-f\-\fP) sends the output to standard output instead of modifying an existing file. .TP 5 .B \-include \fIfile\fP Process file as input, and include all the resulting output before processing the regular input file. This has the same affect as if the specified file is an include statement that appears before the very first line of the regular input file. .TP 5 .B \-o\fIobjsuffix\fP Object file suffix. Some systems may have object files whose suffix is something other than ``.o''. This option allows you to specify another suffix, such as ``.b'' with .I \-o.b or ``:obj'' with .I \-o:obj and so forth. .TP 5 .B \-p\fIobjprefix\fP Object file prefix. The prefix is prepended to the name of the object file. This is usually used to designate a different directory for the object file. The default is the empty string. .TP 5 .B \-s\fIstring\fP Starting string delimiter. This option permits you to specify a different string for .B makedepend to look for in the makefile. .TP 5 .B \-w\fIwidth\fP Line width. Normally, .B makedepend will ensure that every output line that it writes will be no wider than 78 characters for the sake of readability. This option enables you to change this width. .TP 5 .B \-v Verbose operation. This option causes .B makedepend to emit the list of files included by each input file. .TP 5 .B \-m Warn about multiple inclusion. This option causes .B makedepend to produce a warning if any input file includes another file more than once. In previous versions of .B makedepend this was the default behavior; the default has been changed to better match the behavior of the C compiler, which does not consider multiple inclusion to be an error. This option is provided for backward compatibility, and to aid in debugging problems related to multiple inclusion. .TP 5 .B "\-\^\- \fIoptions\fP \-\^\-" If .B makedepend encounters a double hyphen (\-\^\-) in the argument list, then any unrecognized argument following it will be silently ignored; a second double hyphen terminates this special treatment. In this way, .B makedepend can be made to safely ignore esoteric compiler arguments that might normally be found in a CFLAGS .B make macro (see the .B EXAMPLE section above). All options that .B makedepend recognizes and appear between the pair of double hyphens are processed normally. .SH ALGORITHM The approach used in this program enables it to run an order of magnitude faster than any other ``dependency generator'' I have ever seen. Central to this performance are two assumptions: that all files compiled by a single makefile will be compiled with roughly the same .I \-I and .I \-D options; and that most files in a single directory will include largely the same files. .PP Given these assumptions, .B makedepend expects to be called once for each makefile, with all source files that are maintained by the makefile appearing on the command line. It parses each source and include file exactly once, maintaining an internal symbol table for each. Thus, the first file on the command line will take an amount of time proportional to the amount of time that a normal C preprocessor takes. But on subsequent files, if it encounters an include file that it has already parsed, it does not parse it again. .PP For example, imagine you are compiling two files, .I file1.c and .I file2.c, they each include the header file .I header.h, and the file .I header.h in turn includes the files .I def1.h and .I def2.h. When you run the command .sp makedepend\0file1.c\0file2.c .sp .B makedepend will parse .I file1.c and consequently, .I header.h and then .I def1.h and .I def2.h. It then decides that the dependencies for this file are .sp file1.o:\0header.h\0def1.h\0def2.h .sp But when the program parses .I file2.c and discovers that it, too, includes .I header.h, it does not parse the file, but simply adds .I header.h, .I def1.h and .I def2.h to the list of dependencies for .I file2.o. .SH "SEE ALSO" cc(1), make(1) .SH BUGS .B makedepend parses, but does not currently evaluate, the SVR4 #predicate(token-list) preprocessor expression; such expressions are simply assumed to be true. This may cause the wrong .I #include directives to be evaluated. .PP Imagine you are parsing two files, say .I file1.c and .I file2.c, each includes the file .I def.h. The list of files that .I def.h includes might truly be different when .I def.h is included by .I file1.c than when it is included by .I file2.c. But once .B makedepend arrives at a list of dependencies for a file, it is cast in concrete. .SH AUTHOR Todd Brunhoff, Tektronix, Inc. and MIT Project Athena jss-4.4.3/jss/coreconf/mkdepend/parse.c000066400000000000000000000405711326145000000177610ustar00rootroot00000000000000/* $Xorg: parse.c,v 1.6 2001/02/09 02:03:16 xorgcvs Exp $ */ /* Copyright (c) 1993, 1994, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/config/makedepend/parse.c,v 1.12 2002/02/26 05:09:10 tsi Exp $ */ #include "def.h" extern char *directives[]; extern struct inclist inclist[ MAXFILES ], *inclistnext, maininclist; extern char *includedirs[ ], **includedirsnext; static int deftype (char *line, struct filepointer *filep, struct inclist *file_red, struct inclist *file, int parse_it); static int zero_value(char *filename, char *exp, struct filepointer *filep, struct inclist *file_red); static int merge2defines(struct inclist *file1, struct inclist *file2); static int gobble(struct filepointer *filep, struct inclist *file, struct inclist *file_red) { char *line; int type; while ((line = getnextline(filep))) { switch(type = deftype(line, filep, file_red, file, FALSE)) { case IF: case IFFALSE: case IFGUESSFALSE: case IFDEF: case IFNDEF: type = gobble(filep, file, file_red); while ((type == ELIF) || (type == ELIFFALSE) || (type == ELIFGUESSFALSE)) type = gobble(filep, file, file_red); if (type == ELSE) (void)gobble(filep, file, file_red); break; case ELSE: case ENDIF: debug(0,("%s, line %d: #%s\n", file->i_file, filep->f_line, directives[type])); return(type); case DEFINE: case UNDEF: case INCLUDE: case INCLUDEDOT: case PRAGMA: case ERROR: case IDENT: case SCCS: case EJECT: case WARNING: case INCLUDENEXT: case INCLUDENEXTDOT: break; case ELIF: case ELIFFALSE: case ELIFGUESSFALSE: return(type); case -1: warning("%s", file_red->i_file); if (file_red != file) warning1(" (reading %s)", file->i_file); warning1(", line %d: unknown directive == \"%s\"\n", filep->f_line, line); break; } } return(-1); } /* * Decide what type of # directive this line is. */ static int deftype (char *line, struct filepointer *filep, struct inclist *file_red, struct inclist *file, int parse_it) { register char *p; char *directive, savechar, *q; register int ret; /* * Parse the directive... */ directive=line+1; while (*directive == ' ' || *directive == '\t') directive++; p = directive; while ((*p == '_') || (*p >= 'a' && *p <= 'z')) p++; savechar = *p; *p = '\0'; ret = match(directive, directives); *p = savechar; /* If we don't recognize this compiler directive or we happen to just * be gobbling up text while waiting for an #endif or #elif or #else * in the case of an #elif we must check the zero_value and return an * ELIF or an ELIFFALSE. */ if (ret == ELIF && !parse_it) { while (*p == ' ' || *p == '\t') p++; /* * parse an expression. */ debug(0,("%s, line %d: #elif %s ", file->i_file, filep->f_line, p)); ret = zero_value(file->i_file, p, filep, file_red); if (ret != IF) { debug(0,("false...\n")); if (ret == IFFALSE) return(ELIFFALSE); else return(ELIFGUESSFALSE); } else { debug(0,("true...\n")); return(ELIF); } } if (ret < 0 || ! parse_it) return(ret); /* * now decide how to parse the directive, and do it. */ while (*p == ' ' || *p == '\t') p++; q = p + strlen(p); do { q--; } while (*q == ' ' || *q == '\t'); q[1] = '\0'; switch (ret) { case IF: /* * parse an expression. */ ret = zero_value(file->i_file, p, filep, file_red); debug(0,("%s, line %d: %s #if %s\n", file->i_file, filep->f_line, ret?"false":"true", p)); break; case IFDEF: case IFNDEF: debug(0,("%s, line %d: #%s %s\n", file->i_file, filep->f_line, directives[ret], p)); case UNDEF: /* * separate the name of a single symbol. */ while (isalnum(*p) || *p == '_') *line++ = *p++; *line = '\0'; break; case INCLUDE: case INCLUDENEXT: debug(2,("%s, line %d: #include%s %s\n", file->i_file, filep->f_line, (ret == INCLUDE) ? "" : "_next", p)); /* Support ANSI macro substitution */ while (1) { struct symtab **sym; if (!*p || *p == '"' || *p == '<') break; sym = isdefined(p, file_red, NULL); if (!sym) break; p = (*sym)->s_value; debug(3,("%s : #includes SYMBOL %s = %s\n", file->i_incstring, (*sym) -> s_name, (*sym) -> s_value)); /* mark file as having included a 'soft include' */ file->i_flags |= INCLUDED_SYM; } /* * Separate the name of the include file. */ while (*p && *p != '"' && *p != '<') p++; if (! *p) return(-2); if (*p++ == '"') { if (ret == INCLUDE) ret = INCLUDEDOT; else ret = INCLUDENEXTDOT; while (*p && *p != '"') *line++ = *p++; } else while (*p && *p != '>') *line++ = *p++; *line = '\0'; break; case DEFINE: /* * copy the definition back to the beginning of the line. */ strcpy (line, p); break; case ELSE: case ENDIF: case ELIF: case PRAGMA: case ERROR: case IDENT: case SCCS: case EJECT: case WARNING: debug(0,("%s, line %d: #%s\n", file->i_file, filep->f_line, directives[ret])); /* * nothing to do. */ break; } return(ret); } struct symtab ** fdefined(char *symbol, struct inclist *file, struct inclist **srcfile) { struct inclist **ip; struct symtab **val; int i; static int recurse_lvl = 0; if (file->i_flags & DEFCHECKED) return(NULL); debug(2,("Looking for %s in %s\n", symbol, file->i_file)); file->i_flags |= DEFCHECKED; if ((val = slookup(symbol, file))) debug(1,("%s defined in %s as %s\n", symbol, file->i_file, (*val)->s_value)); if (val == NULL && file->i_list) { for (ip = file->i_list, i=0; i < file->i_listlen; i++, ip++) if (file->i_merged[i]==FALSE) { val = fdefined(symbol, *ip, srcfile); file->i_merged[i]=merge2defines(file,*ip); if (val!=NULL) break; } } else if (val != NULL && srcfile != NULL) *srcfile = file; recurse_lvl--; file->i_flags &= ~DEFCHECKED; return(val); } struct symtab ** isdefined(char *symbol, struct inclist *file, struct inclist **srcfile) { struct symtab **val; if ((val = slookup(symbol, &maininclist))) { debug(1,("%s defined on command line\n", symbol)); if (srcfile != NULL) *srcfile = &maininclist; return(val); } if ((val = fdefined(symbol, file, srcfile))) return(val); debug(1,("%s not defined in %s\n", symbol, file->i_file)); return(NULL); } /* * Return type based on if the #if expression evaluates to 0 */ static int zero_value(char *filename, char *exp, struct filepointer *filep, struct inclist *file_red) { if (cppsetup(filename, exp, filep, file_red)) return(IFFALSE); else return(IF); } void define2(char *name, char *val, struct inclist *file) { int first, last, below; register struct symtab **sp = NULL, **dest; struct symtab *stab; /* Make space if it's needed */ if (file->i_defs == NULL) { file->i_defs = (struct symtab **) malloc(sizeof (struct symtab*) * SYMTABINC); file->i_ndefs = 0; } else if (!(file->i_ndefs % SYMTABINC)) file->i_defs = (struct symtab **) realloc(file->i_defs, sizeof(struct symtab*)*(file->i_ndefs+SYMTABINC)); if (file->i_defs == NULL) fatalerr("malloc()/realloc() failure in insert_defn()\n"); below = first = 0; last = file->i_ndefs - 1; while (last >= first) { /* Fast inline binary search */ register char *s1; register char *s2; register int middle = (first + last) / 2; /* Fast inline strchr() */ s1 = name; s2 = file->i_defs[middle]->s_name; while (*s1++ == *s2++) if (s2[-1] == '\0') break; /* If exact match, set sp and break */ if (*--s1 == *--s2) { sp = file->i_defs + middle; break; } /* If name > i_defs[middle] ... */ if (*s1 > *s2) { below = first; first = middle + 1; } /* else ... */ else { below = last = middle - 1; } } /* Search is done. If we found an exact match to the symbol name, just replace its s_value */ if (sp != NULL) { debug(1,("redefining %s from %s to %s in file %s\n", name, (*sp)->s_value, val, file->i_file)); free((*sp)->s_value); (*sp)->s_value = copy(val); return; } sp = file->i_defs + file->i_ndefs++; dest = file->i_defs + below + 1; while (sp > dest) { *sp = sp[-1]; sp--; } stab = (struct symtab *) malloc(sizeof (struct symtab)); if (stab == NULL) fatalerr("malloc()/realloc() failure in insert_defn()\n"); debug(1,("defining %s to %s in file %s\n", name, val, file->i_file)); stab->s_name = copy(name); stab->s_value = copy(val); *sp = stab; } void define(char *def, struct inclist *file) { char *val; /* Separate symbol name and its value */ val = def; while (isalnum(*val) || *val == '_') val++; if (*val) *val++ = '\0'; while (*val == ' ' || *val == '\t') val++; if (!*val) val = "1"; define2(def, val, file); } struct symtab ** slookup(char *symbol, struct inclist *file) { register int first = 0; register int last = file->i_ndefs - 1; if (file) while (last >= first) { /* Fast inline binary search */ register char *s1; register char *s2; register int middle = (first + last) / 2; /* Fast inline strchr() */ s1 = symbol; s2 = file->i_defs[middle]->s_name; while (*s1++ == *s2++) if (s2[-1] == '\0') break; /* If exact match, we're done */ if (*--s1 == *--s2) { return file->i_defs + middle; } /* If symbol > i_defs[middle] ... */ if (*s1 > *s2) { first = middle + 1; } /* else ... */ else { last = middle - 1; } } return(NULL); } static int merge2defines(struct inclist *file1, struct inclist *file2) { int i; if ((file1==NULL) || (file2==NULL) || !(file2->i_flags & FINISHED)) return 0; for (i=0; i < file2->i_listlen; i++) if (file2->i_merged[i]==FALSE) return 0; { int first1 = 0; int last1 = file1->i_ndefs - 1; int first2 = 0; int last2 = file2->i_ndefs - 1; int first=0; struct symtab** i_defs = NULL; int deflen=file1->i_ndefs+file2->i_ndefs; debug(2,("merging %s into %s\n", file2->i_file, file1->i_file)); if (deflen>0) { /* make sure deflen % SYMTABINC == 0 is still true */ deflen += (SYMTABINC - deflen % SYMTABINC) % SYMTABINC; i_defs=(struct symtab**) malloc(deflen*sizeof(struct symtab*)); if (i_defs==NULL) return 0; } while ((last1 >= first1) && (last2 >= first2)) { char *s1=file1->i_defs[first1]->s_name; char *s2=file2->i_defs[first2]->s_name; if (strcmp(s1,s2) < 0) i_defs[first++]=file1->i_defs[first1++]; else if (strcmp(s1,s2) > 0) i_defs[first++]=file2->i_defs[first2++]; else /* equal */ { i_defs[first++]=file2->i_defs[first2++]; first1++; } } while (last1 >= first1) { i_defs[first++]=file1->i_defs[first1++]; } while (last2 >= first2) { i_defs[first++]=file2->i_defs[first2++]; } if (file1->i_defs) free(file1->i_defs); file1->i_defs=i_defs; file1->i_ndefs=first; return 1; } } void undefine(char *symbol, struct inclist *file) { register struct symtab **ptr; struct inclist *srcfile; while ((ptr = isdefined(symbol, file, &srcfile)) != NULL) { srcfile->i_ndefs--; for (; ptr < srcfile->i_defs + srcfile->i_ndefs; ptr++) *ptr = ptr[1]; } } int find_includes(struct filepointer *filep, struct inclist *file, struct inclist *file_red, int recursion, boolean failOK) { struct inclist *inclistp; char **includedirsp; register char *line; register int type; boolean recfailOK; while ((line = getnextline(filep))) { switch(type = deftype(line, filep, file_red, file, TRUE)) { case IF: doif: type = find_includes(filep, file, file_red, recursion+1, failOK); while ((type == ELIF) || (type == ELIFFALSE) || (type == ELIFGUESSFALSE)) type = gobble(filep, file, file_red); if (type == ELSE) gobble(filep, file, file_red); break; case IFFALSE: case IFGUESSFALSE: doiffalse: if (type == IFGUESSFALSE || type == ELIFGUESSFALSE) recfailOK = TRUE; else recfailOK = failOK; type = gobble(filep, file, file_red); if (type == ELSE) find_includes(filep, file, file_red, recursion+1, recfailOK); else if (type == ELIF) goto doif; else if ((type == ELIFFALSE) || (type == ELIFGUESSFALSE)) goto doiffalse; break; case IFDEF: case IFNDEF: if ((type == IFDEF && isdefined(line, file_red, NULL)) || (type == IFNDEF && !isdefined(line, file_red, NULL))) { debug(1,(type == IFNDEF ? "line %d: %s !def'd in %s via %s%s\n" : "", filep->f_line, line, file->i_file, file_red->i_file, ": doit")); type = find_includes(filep, file, file_red, recursion+1, failOK); while (type == ELIF || type == ELIFFALSE || type == ELIFGUESSFALSE) type = gobble(filep, file, file_red); if (type == ELSE) gobble(filep, file, file_red); } else { debug(1,(type == IFDEF ? "line %d: %s !def'd in %s via %s%s\n" : "", filep->f_line, line, file->i_file, file_red->i_file, ": gobble")); type = gobble(filep, file, file_red); if (type == ELSE) find_includes(filep, file, file_red, recursion+1, failOK); else if (type == ELIF) goto doif; else if (type == ELIFFALSE || type == ELIFGUESSFALSE) goto doiffalse; } break; case ELSE: case ELIFFALSE: case ELIFGUESSFALSE: case ELIF: if (!recursion) gobble(filep, file, file_red); case ENDIF: if (recursion) return(type); case DEFINE: define(line, file); break; case UNDEF: if (!*line) { warning("%s", file_red->i_file); if (file_red != file) warning1(" (reading %s)", file->i_file); warning1(", line %d: incomplete undef == \"%s\"\n", filep->f_line, line); break; } undefine(line, file_red); break; case INCLUDE: case INCLUDEDOT: case INCLUDENEXT: case INCLUDENEXTDOT: inclistp = inclistnext; includedirsp = includedirsnext; debug(2,("%s, reading %s, includes %s\n", file_red->i_file, file->i_file, line)); add_include(filep, file, file_red, line, type, failOK); inclistnext = inclistp; includedirsnext = includedirsp; break; case ERROR: case WARNING: warning("%s", file_red->i_file); if (file_red != file) warning1(" (reading %s)", file->i_file); warning1(", line %d: %s\n", filep->f_line, line); break; case PRAGMA: case IDENT: case SCCS: case EJECT: break; case -1: warning("%s", file_red->i_file); if (file_red != file) warning1(" (reading %s)", file->i_file); warning1(", line %d: unknown directive == \"%s\"\n", filep->f_line, line); break; case -2: warning("%s", file_red->i_file); if (file_red != file) warning1(" (reading %s)", file->i_file); warning1(", line %d: incomplete include == \"%s\"\n", filep->f_line, line); break; } } file->i_flags |= FINISHED; debug(2,("finished with %s\n", file->i_file)); return(-1); } jss-4.4.3/jss/coreconf/mkdepend/pr.c000066400000000000000000000070311326145000000172620ustar00rootroot00000000000000/* $Xorg: pr.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */ /* Copyright (c) 1993, 1994, 1998 The Open Group Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Except as contained in this notice, the name of The Open Group shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from The Open Group. */ /* $XFree86: xc/config/makedepend/pr.c,v 1.5 2001/12/14 19:53:21 dawes Exp $ */ #include "def.h" extern struct inclist inclist[ MAXFILES ], *inclistp; extern char *objprefix; extern char *objsuffix; extern int width; extern boolean printed; extern boolean verbose; extern boolean show_where_not; void add_include(struct filepointer *filep, struct inclist *file, struct inclist *file_red, char *include, int type, boolean failOK) { register struct inclist *newfile; register struct filepointer *content; /* * First decide what the pathname of this include file really is. */ newfile = inc_path(file->i_file, include, type); if (newfile == NULL) { if (failOK) return; if (file != file_red) warning("%s (reading %s, line %d): ", file_red->i_file, file->i_file, filep->f_line); else warning("%s, line %d: ", file->i_file, filep->f_line); warning1("cannot find include file \"%s\"\n", include); show_where_not = TRUE; newfile = inc_path(file->i_file, include, type); show_where_not = FALSE; } if (newfile) { included_by(file, newfile); if (!(newfile->i_flags & SEARCHED)) { newfile->i_flags |= SEARCHED; content = getfile(newfile->i_file); find_includes(content, newfile, file_red, 0, failOK); freefile(content); } } } static void pr(struct inclist *ip, char *file, char *base) { static char *lastfile; static int current_len; register int len, i; char buf[ BUFSIZ ]; printed = TRUE; len = strlen(ip->i_file)+1; if (current_len + len > width || file != lastfile) { lastfile = file; sprintf(buf, "\n%s%s%s: %s", objprefix, base, objsuffix, ip->i_file); len = current_len = strlen(buf); } else { buf[0] = ' '; strcpy(buf+1, ip->i_file); current_len += len; } fwrite(buf, len, 1, stdout); /* * If verbose is set, then print out what this file includes. */ if (! verbose || ip->i_list == NULL || ip->i_flags & NOTIFIED) return; ip->i_flags |= NOTIFIED; lastfile = NULL; printf("\n# %s includes:", ip->i_file); for (i=0; ii_listlen; i++) printf("\n#\t%s", ip->i_list[ i ]->i_incstring); } void recursive_pr_include(struct inclist *head, char *file, char *base) { int i; if (head->i_flags & MARKED) return; head->i_flags |= MARKED; if (head->i_file != file) pr(head, file, base); for (i=0; ii_listlen; i++) recursive_pr_include(head->i_list[ i ], file, base); } jss-4.4.3/jss/coreconf/module.mk000066400000000000000000000021011326145000000165150ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # The master "Core Components" source and release component directory # # names are ALWAYS identical and are the value of $(MODULE). # # NOTE: A component is also called a module or a subsystem. # ####################################################################### # # All "Core Components" -specific source-side tags must # always be identified for compiling/linking purposes # ifndef JAVA_SOURCE_COMPONENT JAVA_SOURCE_COMPONENT = java endif ifndef NETLIB_SOURCE_COMPONENT NETLIB_SOURCE_COMPONENT = netlib endif ifndef NSPR_SOURCE_COMPONENT NSPR_SOURCE_COMPONENT = nspr20 endif ifndef SECTOOLS_SOURCE_COMPONENT SECTOOLS_SOURCE_COMPONENT = sectools endif ifndef SECURITY_SOURCE_COMPONENT SECURITY_SOURCE_COMPONENT = security endif MK_MODULE = included jss-4.4.3/jss/coreconf/nsinstall/000077500000000000000000000000001326145000000167145ustar00rootroot00000000000000jss-4.4.3/jss/coreconf/nsinstall/Makefile000066400000000000000000000014151326145000000203550ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. DEPTH = ../.. CORE_DEPTH = ../.. MODULE = coreconf CSRCS = nsinstall.c pathsub.c PROGRAM = nsinstall # Indicate that this directory builds build tools. INTERNAL_TOOLS = 1 include $(DEPTH)/coreconf/config.mk ifeq (,$(filter-out OS2 WIN%,$(OS_TARGET))) PROGRAM = else TARGETS = $(PROGRAM) INSTALL = true endif ifdef NATIVE_CC CC=$(NATIVE_CC) endif ifdef NATIVE_FLAGS OS_CFLAGS=$(NATIVE_FLAGS) endif include $(DEPTH)/coreconf/rules.mk # Redefine MAKE_OBJDIR for just this directory define MAKE_OBJDIR if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); fi endef jss-4.4.3/jss/coreconf/nsinstall/nsinstall.c000066400000000000000000000231531326145000000210730ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* ** Netscape portable install command. */ #include /* OSF/1 requires this before grp.h, so put it first */ #include #include #include #if defined(_WINDOWS) #include typedef unsigned int mode_t; #else #include #include #include #include #include #include #endif #include #include #include "pathsub.h" #define HAVE_LCHOWN #if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) || defined(SUNOS4) || defined(SCO) || defined(UNIXWARE) || defined(NTO) || defined(DARWIN) || defined(BEOS) || defined(__riscos__) #undef HAVE_LCHOWN #endif #define HAVE_FCHMOD #if defined(BEOS) #undef HAVE_FCHMOD #endif #ifdef LINUX #include #endif #if defined(SCO) || defined(UNIXWARE) || defined(SNI) || defined(NCR) || defined(NEC) #if !defined(S_ISLNK) && defined(S_IFLNK) #define S_ISLNK(a) (((a) & S_IFMT) == S_IFLNK) #endif #endif #if defined(SNI) extern int fchmod(int fildes, mode_t mode); #endif #ifdef GETCWD_CANT_MALLOC /* * this should probably go into a utility library in case other applications * need it. */ static char * getcwd_do_malloc(char *path, int len) { if (!path) { path = malloc(PATH_MAX +1); if (!path) return NULL; } return getcwd(path, PATH_MAX); } #define GETCWD getcwd_do_malloc #else #define GETCWD getcwd #endif static void usage(void) { fprintf(stderr, "usage: %s [-C cwd] [-L linkprefix] [-m mode] [-o owner] [-g group]\n" " %*s [-DdltR] file [file ...] directory\n", program, (int)strlen(program), ""); exit(2); } /* this is more-or-less equivalent to mkdir -p */ static int mkdirs(char *path, mode_t mode) { char * cp; int rv; struct stat sb; if (!path || !path[0]) fail("Null pointer or empty string passed to mkdirs()"); while (*path == '/' && path[1] == '/') path++; for (cp = strrchr(path, '/'); cp && cp != path && *(cp - 1) == '/'; cp--); if (cp && cp != path) { *cp = '\0'; if ((stat(path, &sb) < 0 || !S_ISDIR(sb.st_mode)) && mkdirs(path, mode) < 0) { return -1; } *cp = '/'; } rv = mkdir(path, mode); if (rv) { if (errno != EEXIST) fail("mkdirs cannot make %s", path); fprintf(stderr, "directory creation race: %s\n", path); if (!stat(path, &sb) && S_ISDIR(sb.st_mode)) rv = 0; } return rv; } static uid_t touid(char *owner) { struct passwd *pw; uid_t uid; char *cp; if (!owner || !owner[0]) fail("Null pointer or empty string passed to touid()"); pw = getpwnam(owner); if (pw) return pw->pw_uid; uid = strtol(owner, &cp, 0); if (uid == 0 && cp == owner) fail("cannot find uid for %s", owner); return uid; } static gid_t togid(char *group) { struct group *gr; gid_t gid; char *cp; if (!group || !group[0]) fail("Null pointer or empty string passed to togid()"); gr = getgrnam(group); if (gr) return gr->gr_gid; gid = strtol(group, &cp, 0); if (gid == 0 && cp == group) fail("cannot find gid for %s", group); return gid; } void * const uninit = (void *)0xdeadbeef; int main(int argc, char **argv) { char * base = uninit; char * bp = uninit; char * cp = uninit; char * cwd = 0; char * group = 0; char * linkname = 0; char * linkprefix = 0; char * name = uninit; char * owner = 0; char * todir = uninit; char * toname = uninit; int bnlen = -1; int cc = 0; int dodir = 0; int dolink = 0; int dorelsymlink = 0; int dotimes = 0; int exists = 0; int fromfd = -1; int len = -1; int lplen = 0; int onlydir = 0; int opt = -1; int tdlen = -1; int tofd = -1; int wc = -1; mode_t mode = 0755; uid_t uid = -1; gid_t gid = -1; struct stat sb; struct stat tosb; struct utimbuf utb; char buf[BUFSIZ]; program = strrchr(argv[0], '/'); if (!program) program = strrchr(argv[0], '\\'); program = program ? program+1 : argv[0]; while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) { switch (opt) { case 'C': cwd = optarg; break; case 'D': onlydir = 1; break; case 'd': dodir = 1; break; case 'l': dolink = 1; break; case 'L': linkprefix = optarg; lplen = strlen(linkprefix); dolink = 1; break; case 'R': dolink = dorelsymlink = 1; break; case 'm': mode = strtoul(optarg, &cp, 8); if (mode == 0 && cp == optarg) usage(); break; case 'o': owner = optarg; break; case 'g': group = optarg; break; case 't': dotimes = 1; break; default: usage(); } } argc -= optind; argv += optind; if (argc < 2 - onlydir) usage(); todir = argv[argc-1]; if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) && mkdirs(todir, 0777) < 0) { fail("cannot mkdir -p %s", todir); } if (onlydir) return 0; if (!cwd) { cwd = GETCWD(0, PATH_MAX); if (!cwd) fail("could not get CWD"); } /* make sure we can get into todir. */ xchdir(todir); todir = GETCWD(0, PATH_MAX); if (!todir) fail("could not get CWD in todir"); tdlen = strlen(todir); /* back to original directory. */ xchdir(cwd); uid = owner ? touid(owner) : -1; gid = group ? togid(group) : -1; while (--argc > 0) { name = *argv++; len = strlen(name); base = xbasename(name); bnlen = strlen(base); toname = (char*)xmalloc(tdlen + 1 + bnlen + 1); sprintf(toname, "%s/%s", todir, base); retry: exists = (lstat(toname, &tosb) == 0); if (dodir) { /* -d means create a directory, always */ if (exists && !S_ISDIR(tosb.st_mode)) { int rv = unlink(toname); if (rv) fail("cannot unlink %s", toname); exists = 0; } if (!exists && mkdir(toname, mode) < 0) { /* we probably have two nsinstall programs in a race here. */ if (errno == EEXIST && !stat(toname, &sb) && S_ISDIR(sb.st_mode)) { fprintf(stderr, "directory creation race: %s\n", toname); goto retry; } fail("cannot make directory %s", toname); } if ((owner || group) && chown(toname, uid, gid) < 0) fail("cannot change owner of %s", toname); } else if (dolink) { if (*name == '/') { /* source is absolute pathname, link to it directly */ linkname = 0; } else { if (linkprefix) { /* -L implies -l and prefixes names with a $cwd arg. */ len += lplen + 1; linkname = (char*)xmalloc(len + 1); sprintf(linkname, "%s/%s", linkprefix, name); } else if (dorelsymlink) { /* Symlink the relative path from todir to source name. */ linkname = (char*)xmalloc(PATH_MAX); if (*todir == '/') { /* todir is absolute: skip over common prefix. */ lplen = relatepaths(todir, cwd, linkname); strcpy(linkname + lplen, name); } else { /* todir is named by a relative path: reverse it. */ reversepath(todir, name, len, linkname); xchdir(cwd); } len = strlen(linkname); } name = linkname; } /* Check for a pre-existing symlink with identical content. */ if (exists && (!S_ISLNK(tosb.st_mode) || readlink(toname, buf, sizeof buf) != len || strncmp(buf, name, len) != 0)) { int rmrv; rmrv = (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); if (rmrv < 0) { fail("destination exists, cannot remove %s", toname); } exists = 0; } if (!exists && symlink(name, toname) < 0) { if (errno == EEXIST) { fprintf(stderr, "symlink creation race: %s\n", toname); fail("symlink was attempted in working directory %s " "from %s to %s.\n", cwd, name, toname); goto retry; } diagnosePath(toname); fail("cannot make symbolic link %s", toname); } #ifdef HAVE_LCHOWN if ((owner || group) && lchown(toname, uid, gid) < 0) fail("cannot change owner of %s", toname); #endif if (linkname) { free(linkname); linkname = 0; } } else { /* Copy from name to toname, which might be the same file. */ fromfd = open(name, O_RDONLY); if (fromfd < 0 || fstat(fromfd, &sb) < 0) fail("cannot access %s", name); if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0)) { int rmrv; rmrv = (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname); if (rmrv < 0) { fail("destination exists, cannot remove %s", toname); } } tofd = open(toname, O_CREAT | O_WRONLY, 0666); if (tofd < 0) fail("cannot create %s", toname); bp = buf; while ((cc = read(fromfd, bp, sizeof buf)) > 0) { while ((wc = write(tofd, bp, cc)) > 0) { if ((cc -= wc) == 0) break; bp += wc; } if (wc < 0) fail("cannot write to %s", toname); } if (cc < 0) fail("cannot read from %s", name); if (ftruncate(tofd, sb.st_size) < 0) fail("cannot truncate %s", toname); if (dotimes) { utb.actime = sb.st_atime; utb.modtime = sb.st_mtime; if (utime(toname, &utb) < 0) fail("cannot set times of %s", toname); } #ifdef HAVE_FCHMOD if (fchmod(tofd, mode) < 0) #else if (chmod(toname, mode) < 0) #endif fail("cannot change mode of %s", toname); if ((owner || group) && fchown(tofd, uid, gid) < 0) fail("cannot change owner of %s", toname); /* Must check for delayed (NFS) write errors on close. */ if (close(tofd) < 0) fail("close reports write error on %s", toname); close(fromfd); } free(toname); } free(cwd); free(todir); return 0; } jss-4.4.3/jss/coreconf/nsinstall/pathsub.c000066400000000000000000000132721326145000000205330ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* ** Pathname subroutines. */ #include #if defined(FREEBSD) || defined(BSDI) || defined(DARWIN) #include #endif /* FREEBSD */ #include #include #include #include #include #include #include #include #include #include "pathsub.h" #ifdef USE_REENTRANT_LIBC #include "libc_r.h" #endif /* USE_REENTRANT_LIBC */ char *program; void fail(char *format, ...) { int error; va_list ap; #ifdef USE_REENTRANT_LIBC R_STRERROR_INIT_R(); #endif error = errno; fprintf(stderr, "%s: ", program); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); if (error) { #ifdef USE_REENTRANT_LIBC R_STRERROR_R(errno); fprintf(stderr, ": %s", r_strerror_r); #else fprintf(stderr, ": %s", strerror(errno)); #endif } putc('\n', stderr); abort(); exit(1); } char * getcomponent(char *path, char *name) { if (*path == '\0') return 0; if (*path == '/') { *name++ = '/'; } else { do { *name++ = *path++; } while (*path != '/' && *path != '\0'); } *name = '\0'; while (*path == '/') path++; return path; } #ifdef UNIXWARE /* The static buffer in Unixware's readdir is too small. */ struct dirent * readdir(DIR *d) { static struct dirent *buf = NULL; #define MAX_PATH_LEN 1024 if (buf == NULL) buf = (struct dirent *)xmalloc(sizeof(struct dirent) + MAX_PATH_LEN) ; return readdir_r(d, buf); } #endif /* APPARENT BUG - ignores argument "dir", uses ".." instead. */ char * ino2name(ino_t ino, char *dir) { DIR *dp; struct dirent *ep; char *name; dp = opendir(".."); /* XXX */ if (!dp) fail("cannot read parent directory"); for (;;) { if (!(ep = readdir(dp))) fail("cannot find current directory"); if (ep->d_ino == ino) break; } name = xstrdup(ep->d_name); closedir(dp); return name; } void * xmalloc(size_t size) { void *p; if (size <= 0) fail("attempted to allocate %u bytes", size); p = malloc(size); if (!p) fail("cannot allocate %u bytes", size); return p; } char * xstrdup(char *s) { if (!s || !s[0]) fail("Null pointer or empty string passed to xstrdup()"); return strcpy((char*)xmalloc(strlen(s) + 1), s); } char * xbasename(char *path) { char *cp; if (!path || !path[0]) fail("Null pointer or empty string passed to xbasename()"); while ((cp = strrchr(path, '/')) && cp[1] == '\0') *cp = '\0'; if (!cp) return path; return cp + 1; } void xchdir(char *dir) { if (!dir || !dir[0]) fail("Null pointer or empty string passed to xchdir()"); if (chdir(dir) < 0) fail("cannot change directory to %s", dir); } int relatepaths(char *from, char *to, char *outpath) { char *cp, *cp2; int len; char buf[NAME_MAX]; assert(*from == '/' && *to == '/'); if (!from || *from != '/') fail("relatepaths: from path does not start with /"); if (!to || *to != '/') fail("relatepaths: to path does not start with /"); for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++) if (*cp == '\0') break; while (cp[-1] != '/') cp--, cp2--; if (cp - 1 == to) { /* closest common ancestor is /, so use full pathname */ len = strlen(strcpy(outpath, to)); if (outpath[len] != '/') { outpath[len++] = '/'; outpath[len] = '\0'; } } else { len = 0; while ((cp2 = getcomponent(cp2, buf)) != 0) { strcpy(outpath + len, "../"); len += 3; } while ((cp = getcomponent(cp, buf)) != 0) { sprintf(outpath + len, "%s/", buf); len += strlen(outpath + len); } } return len; } void reversepath(char *inpath, char *name, int len, char *outpath) { char *cp, *cp2; char buf[NAME_MAX]; struct stat sb; cp = strcpy(outpath + PATH_MAX - (len + 1), name); cp2 = inpath; while ((cp2 = getcomponent(cp2, buf)) != 0) { if (strcmp(buf, ".") == 0) continue; if (strcmp(buf, "..") == 0) { if (stat(".", &sb) < 0) fail("cannot stat current directory"); name = ino2name(sb.st_ino, ".."); len = strlen(name); cp -= len + 1; strcpy(cp, name); cp[len] = '/'; free(name); xchdir(".."); } else { cp -= 3; strncpy(cp, "../", 3); xchdir(buf); } } strcpy(outpath, cp); } void diagnosePath(const char * path) { char * myPath; char * slash; int rv; struct stat sb; char buf[BUFSIZ]; if (!path || !path[0]) fail("Null pointer or empty string passed to mkdirs()"); myPath = strdup(path); if (!myPath) fail("strdup() failed!"); do { rv = lstat(myPath, &sb); if (rv < 0) { perror(myPath); } else if (S_ISLNK(sb.st_mode)) { rv = readlink(myPath, buf, sizeof buf); if (rv < 0) { perror("readlink"); buf[0] = 0; } else if ( rv < BUFSIZ ) { buf[rv] = 0; } else { buf[BUFSIZ-1] = 0; } fprintf(stderr, "%s is a link to %s\n", myPath, buf); } else if (S_ISDIR(sb.st_mode)) { fprintf(stderr, "%s is a directory\n", myPath); rv = access(myPath, X_OK); if (rv < 0) { fprintf(stderr, "%s: no search permission\n", myPath); } } else { fprintf(stderr, "%s is a file !?!\n", myPath); rv = access(myPath, F_OK); if (rv < 0) { fprintf(stderr, "%s does not exist\n", myPath); } } /* chop path off one level. */ slash = strrchr(myPath, '/'); if (!slash) slash = strrchr(myPath, '\\'); if (!slash) slash = myPath; *slash = 0; } while (myPath[0]); free(myPath); } jss-4.4.3/jss/coreconf/nsinstall/pathsub.h000066400000000000000000000022621326145000000205350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef pathsub_h___ #define pathsub_h___ /* ** Pathname subroutines. ** ** Brendan Eich, 8/29/95 */ #include #include #if SUNOS4 #include "sunos4.h" #endif #ifndef PATH_MAX #define PATH_MAX 1024 #endif /* * Just keep sane lengths */ #undef NAME_MAX #define NAME_MAX 256 extern char *program; extern void fail(char *format, ...); extern char *getcomponent(char *path, char *name); extern char *ino2name(ino_t ino, char *dir); extern void *xmalloc(size_t size); extern char *xstrdup(char *s); extern char *xbasename(char *path); extern void xchdir(char *dir); /* Relate absolute pathnames from and to returning the result in outpath. */ extern int relatepaths(char *from, char *to, char *outpath); /* NOTE: changes current working directory -- caveat emptor */ extern void reversepath(char *inpath, char *name, int len, char *outpath); /* stats every directory in path, reports results. */ extern void diagnosePath(const char * path); #endif /* pathsub_h___ */ jss-4.4.3/jss/coreconf/nsinstall/sunos4.h000066400000000000000000000075031326145000000203250ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef pr_sunos4_h___ #define pr_sunos4_h___ #ifndef SVR4 /* ** Hodge podge of random missing prototypes for the Sunos4 system */ #include #include #include #include #include #define PATH_MAX _POSIX_PATH_MAX struct timeval; struct timezone; struct itimerval; struct sockaddr; struct stat; struct tm; /* ctype.h */ extern int tolower(int); extern int toupper(int); /* errno.h */ extern char *sys_errlist[]; extern int sys_nerr; #define strerror(e) sys_errlist[((unsigned)(e) < sys_nerr) ? e : 0] extern void perror(const char *); /* getopt */ extern char *optarg; extern int optind; extern int getopt(int argc, char **argv, char *spec); /* math.h */ extern int srandom(long val); extern long random(void); /* memory.h */ #define memmove(to,from,len) bcopy((char*)(from),(char*)(to),len) extern void bcopy(const char *, char *, int); /* signal.h */ /* ** SunOS4 sigaction hides interrupts by default, so we can safely define ** SA_RESTART to 0 (HP-UX is a counter-example -- its sigaction does not ** hide interrupts but lacks an SA_RESTART option; you must use sigvector ** and tweak the sigcontext from within each signal handler!). */ #define SA_RESTART 0 #define SA_SIGINFO 0 /* stdio.h */ extern int printf(const char *, ...); extern int fprintf(FILE *, const char *, ...); extern int vprintf(const char *, va_list); extern int vfprintf(FILE *, const char *, va_list); extern char *vsprintf(char *, const char *, va_list); extern int scanf(const char *, ...); extern int sscanf(const char *, const char *, ...); extern int fscanf(FILE *, const char *, ...); extern int fgetc(FILE *); extern int fputc(int, FILE *); extern int fputs(const char *, FILE *); extern int puts(const char *); extern int fread(void *, size_t, size_t, FILE *); extern int fwrite(const char *, int, int, FILE *); extern int fseek(FILE *, long, int); extern long ftell(FILE *); extern int rewind(FILE *); extern int fflush(FILE *); extern int _flsbuf(unsigned char, FILE *); extern int fclose(FILE *); extern int remove(const char *); extern int setvbuf(FILE *, char *, int, size_t); extern int system(const char *); extern FILE *popen(const char *, const char *); extern int pclose(FILE *); /* stdlib.h */ #define strtoul strtol extern int isatty(int fildes); extern long strtol(const char *, char **, int); extern int putenv(const char *); extern void srand48(long); extern long lrand48(void); extern double drand48(void); /* string.h */ extern int strcasecmp(const char *, const char *); extern int strncasecmp(const char *, const char *, size_t); extern int strcoll(const char *, const char *); /* time.h */ extern time_t mktime(struct tm *); extern size_t strftime(char *, size_t, const char *, const struct tm *); extern int gettimeofday(struct timeval *, struct timezone *); extern int setitimer(int, struct itimerval *, struct itimerval *); extern time_t time(time_t *); extern time_t timegm(struct tm *); extern struct tm *localtime(const time_t *); extern struct tm *gmtime(const time_t *); /* unistd.h */ extern int rename(const char *, const char *); extern int ioctl(int, int, int *arg); extern int connect(int, struct sockaddr *, int); extern int readlink(const char *, char *, int); extern int symlink(const char *, const char *); extern int ftruncate(int, off_t); extern int fchmod(int, mode_t); extern int fchown(int, uid_t, gid_t); extern int lstat(const char *, struct stat *); extern int fstat(int, struct stat *); extern int select(int, fd_set *, fd_set *, fd_set *, struct timeval *); extern int gethostname(char *, int); extern char *getwd(char *); extern int getpagesize(void); #endif /* SVR4 */ #endif /* pr_sunos4_h___ */ jss-4.4.3/jss/coreconf/outofdate.pl000077500000000000000000000023321326145000000172370ustar00rootroot00000000000000#!/usr/local/bin/perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. #Input: [-d dir] foo1.java foo2.java #Compares with: foo1.class foo2.class (if -d specified, checks in 'dir', # otherwise assumes .class files in same directory as .java files) #Returns: list of input arguments which are newer than corresponding class #files (non-existent class files are considered to be real old :-) $found = 1; if ($ARGV[0] eq '-d') { $classdir = $ARGV[1]; $classdir .= "/"; shift; shift; } else { $classdir = "./"; } foreach $filename (@ARGV) { $classfilename = $classdir; $classfilename .= $filename; $classfilename =~ s/.java$/.class/; ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime, $ctime,$blksize,$blocks) = stat($filename); ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$classmtime, $ctime,$blksize,$blocks) = stat($classfilename); # print $filename, " ", $mtime, ", ", $classfilename, " ", $classmtime, "\n"; if ($mtime > $classmtime) { print $filename, " "; $found = 0; } } print "\n"; jss-4.4.3/jss/coreconf/prefix.mk000066400000000000000000000013561326145000000165400ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master "Core Components" for computing program prefixes # ####################################################################### # # Object prefixes # ifndef OBJ_PREFIX OBJ_PREFIX = endif # # Library suffixes # ifndef LIB_PREFIX LIB_PREFIX = lib endif ifndef DLL_PREFIX DLL_PREFIX = lib endif ifndef IMPORT_LIB_PREFIX IMPORT_LIB_PREFIX = endif # # Program prefixes # ifndef PROG_PREFIX PROG_PREFIX = endif MK_PREFIX = included jss-4.4.3/jss/coreconf/release.pl000077500000000000000000000041411326145000000166650ustar00rootroot00000000000000#! /usr/local/bin/perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. require('coreconf.pl'); #######-- read in variables on command line into %var $use_jar = 1; $ZIP = "$ENV{JAVA_HOME}/bin/jar"; if ( $ENV{JAVA_HOME} eq "" ) { $ZIP = "zip"; $use_jar = 0; } &parse_argv; ######-- Do the packaging of jars. foreach $jarfile (split(/ /,$var{FILES}) ) { print STDERR "---------------------------------------------\n"; print STDERR "Packaging jar file $jarfile....\n"; $jarinfo = $var{$jarfile}; ($jardir,$jaropts) = split(/\|/,$jarinfo); if ( $use_jar ) { $zipoptions = "-cvf"; } else { $zipoptions = "-T -r"; if ($jaropts =~ /a/) { if ($var{OS_ARCH} eq 'WINNT') { $zipoptions .= ' -ll'; } } } # just in case the directory ends in a /, remove it if ($jardir =~ /\/$/) { chop $jardir; } $dirdepth --; print STDERR "jardir = $jardir\n"; system("ls $jardir"); if (-d $jardir) { # count the number of slashes $slashes =0; foreach $i (split(//,$jardir)) { if ($i =~ /\//) { $slashes++; } } $dotdots =0; foreach $i (split(m|/|,$jardir)) { if ($i eq '..') { $dotdots ++; } } $dirdepth = ($slashes +1) - (2*$dotdots); print STDERR "changing dir $jardir\n"; chdir($jardir); print STDERR "making dir META-INF\n"; mkdir("META-INF",0755); $filelist = ""; opendir(DIR,"."); while ($_ = readdir(DIR)) { if (! ( ($_ eq '.') || ($_ eq '..'))) { if ( $jaropts =~ /i/) { if (! /^include$/) { $filelist .= "$_ "; } } else { $filelist .= "$_ "; } } } closedir(DIR); print STDERR "$ZIP $zipoptions $jarfile $filelist\n"; system("$ZIP $zipoptions $jarfile $filelist"); rmdir("META-INF"); for $i (1 .. $dirdepth) { chdir(".."); print STDERR "chdir ..\n"; } } else { print STDERR "Directory $jardir doesn't exist\n"; } } jss-4.4.3/jss/coreconf/rules.mk000066400000000000000000000720051326145000000163740ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### ### ### ### R U L E S O F E N G A G E M E N T ### ### ### ####################################################################### ####################################################################### # Double-Colon rules for utilizing the binary release model. # ####################################################################### all:: export libs ifeq ($(AUTOCLEAN),1) autobuild:: clean export private_export libs program install else autobuild:: export private_export libs program install endif platform:: @echo $(OBJDIR_NAME) ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) USE_NT_C_SYNTAX=1 endif # # IMPORTS will always be associated with a component. Therefore, # the "import" rule will always change directory to the top-level # of a component, and traverse the IMPORTS keyword from the # "manifest.mn" file located at this level only. # # note: if there is a trailing slash, the component will be appended # (see import.pl - only used for xpheader.jar) import:: @echo "== import.pl ==" @$(PERL) -I$(CORE_DEPTH)/coreconf $(CORE_DEPTH)/coreconf/import.pl \ "RELEASE_TREE=$(RELEASE_TREE)" \ "IMPORTS=$(IMPORTS)" \ "VERSION=$(VERSION)" \ "OS_ARCH=$(OS_ARCH)" \ "PLATFORM=$(PLATFORM)" \ "OVERRIDE_IMPORT_CHECK=$(OVERRIDE_IMPORT_CHECK)" \ "ALLOW_VERSION_OVERRIDE=$(ALLOW_VERSION_OVERRIDE)" \ "SOURCE_RELEASE_PREFIX=$(SOURCE_RELEASE_XP_DIR)" \ "SOURCE_MD_DIR=$(SOURCE_MD_DIR)" \ "SOURCE_XP_DIR=$(SOURCE_XP_DIR)" \ "FILES=$(IMPORT_XPCLASS_JAR) $(XPHEADER_JAR) $(MDHEADER_JAR) $(MDBINARY_JAR)" \ "$(IMPORT_XPCLASS_JAR)=$(IMPORT_XP_DIR)|$(IMPORT_XPCLASS_DIR)|" \ "$(XPHEADER_JAR)=$(IMPORT_XP_DIR)|$(SOURCE_XP_DIR)/public/|v" \ "$(MDHEADER_JAR)=$(IMPORT_MD_DIR)|$(SOURCE_MD_DIR)/include|" \ "$(MDBINARY_JAR)=$(IMPORT_MD_DIR)|$(SOURCE_MD_DIR)|" # On Mac OS X ranlib needs to be rerun after static libs are moved. ifeq ($(OS_TARGET),Darwin) find $(SOURCE_MD_DIR)/lib -name "*.a" -exec $(RANLIB) {} \; endif export:: +$(LOOP_OVER_DIRS) private_export:: +$(LOOP_OVER_DIRS) release_export:: +$(LOOP_OVER_DIRS) release_classes:: +$(LOOP_OVER_DIRS) libs program install:: $(TARGETS) ifdef LIBRARY $(INSTALL) -m 664 $(LIBRARY) $(SOURCE_LIB_DIR) endif ifdef SHARED_LIBRARY $(INSTALL) -m 775 $(SHARED_LIBRARY) $(SOURCE_LIB_DIR) ifdef MOZ_DEBUG_SYMBOLS ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(INSTALL) -m 644 $(SHARED_LIBRARY:$(DLL_SUFFIX)=pdb) $(SOURCE_LIB_DIR) endif endif endif ifdef IMPORT_LIBRARY $(INSTALL) -m 775 $(IMPORT_LIBRARY) $(SOURCE_LIB_DIR) endif ifdef PROGRAM $(INSTALL) -m 775 $(PROGRAM) $(SOURCE_BIN_DIR) ifdef MOZ_DEBUG_SYMBOLS ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(INSTALL) -m 644 $(PROGRAM:$(PROG_SUFFIX)=.pdb) $(SOURCE_BIN_DIR) endif endif endif ifdef PROGRAMS $(INSTALL) -m 775 $(PROGRAMS) $(SOURCE_BIN_DIR) endif +$(LOOP_OVER_DIRS) tests:: +$(LOOP_OVER_DIRS) clean clobber:: rm -rf $(ALL_TRASH) +$(LOOP_OVER_DIRS) realclean clobber_all:: rm -rf $(wildcard *.OBJ) dist $(ALL_TRASH) +$(LOOP_OVER_DIRS) ####################################################################### # Double-Colon rules for populating the binary release model. # ####################################################################### release_clean:: rm -rf $(SOURCE_XP_DIR)/release/$(RELEASE_MD_DIR) release:: release_clean release_export release_classes release_policy release_md release_jars release_cpdistdir release_cpdistdir:: @echo "== cpdist.pl ==" @$(PERL) -I$(CORE_DEPTH)/coreconf $(CORE_DEPTH)/coreconf/cpdist.pl \ "RELEASE_TREE=$(RELEASE_TREE)" \ "CORE_DEPTH=$(CORE_DEPTH)" \ "MODULE=${MODULE}" \ "OS_ARCH=$(OS_ARCH)" \ "RELEASE=$(RELEASE)" \ "PLATFORM=$(PLATFORM)" \ "RELEASE_VERSION=$(RELEASE_VERSION)" \ "SOURCE_RELEASE_PREFIX=$(SOURCE_RELEASE_XP_DIR)" \ "RELEASE_XP_DIR=$(RELEASE_XP_DIR)" \ "RELEASE_MD_DIR=$(RELEASE_MD_DIR)" \ "FILES=$(XPCLASS_JAR) $(XPCLASS_DBG_JAR) $(XPHEADER_JAR) $(MDHEADER_JAR) $(MDBINARY_JAR) XP_FILES MD_FILES" \ "$(XPCLASS_JAR)=$(SOURCE_RELEASE_CLASSES_DIR)|x"\ "$(XPCLASS_DBG_JAR)=$(SOURCE_RELEASE_CLASSES_DBG_DIR)|x"\ "$(XPHEADER_JAR)=$(SOURCE_RELEASE_XPHEADERS_DIR)|x" \ "$(MDHEADER_JAR)=$(SOURCE_RELEASE_MDHEADERS_DIR)|m" \ "$(MDBINARY_JAR)=$(SOURCE_RELEASE_MD_DIR)|m" \ "XP_FILES=$(XP_FILES)|xf" \ "MD_FILES=$(MD_FILES)|mf" # $(SOURCE_RELEASE_xxx_JAR) is a name like yyy.jar # $(SOURCE_RELEASE_xx_DIR) is a name like release_jars:: @echo "== release.pl ==" @$(PERL) -I$(CORE_DEPTH)/coreconf $(CORE_DEPTH)/coreconf/release.pl \ "RELEASE_TREE=$(RELEASE_TREE)" \ "PLATFORM=$(PLATFORM)" \ "OS_ARCH=$(OS_ARCH)" \ "RELEASE_VERSION=$(RELEASE_VERSION)" \ "SOURCE_RELEASE_DIR=$(SOURCE_RELEASE_DIR)" \ "FILES=$(XPCLASS_JAR) $(XPCLASS_DBG_JAR) $(XPHEADER_JAR) $(MDHEADER_JAR) $(MDBINARY_JAR)" \ "$(XPCLASS_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_CLASSES_DIR)|b"\ "$(XPCLASS_DBG_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_CLASSES_DBG_DIR)|b"\ "$(XPHEADER_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_XPHEADERS_DIR)|a" \ "$(MDHEADER_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_MDHEADERS_DIR)|a" \ "$(MDBINARY_JAR)=$(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_MD_DIR)|bi" # Rules for releasing classes. # We have to do some REALLY gross stuff to deal with multiple classes in one # file, as well as nested classes, which have a filename of the form # ContainingClass$NestedClass.class. # RELEASE_CLASSES simply performs a required patsubst on CLASSES # RELEASE_CLASS_PATH is RELEASE_CLASSES with the path (in ns/dist) prepended # RELEASE_NESTED is all the nested classes in RELEASE_CLASS_PATH. We use a # foreach and wildcard to get all the files that start out like one of the # class files, then have a $. So, for each class file, we look for file$* # RELEASE_FILES is the combination of RELEASE_NESTED and the class files # specified by RELEASE_CLASSES which have .class appended to them. Note that # the RELEASE_NESTED don't need to have .class appended because they were # read in from the wildcard as complete filenames. # # The _DBG versions are the debuggable ones. ifneq ($(CLASSES),) RELEASE_CLASSES := $(patsubst %,%,$(CLASSES)) ifdef BUILD_OPT RELEASE_CLASS_PATH := $(patsubst %,$(SOURCE_CLASSES_DIR)/$(PACKAGE)/%, $(RELEASE_CLASSES)) RELEASE_NESTED := $(foreach file,$(RELEASE_CLASS_PATH),$(wildcard $(file)$$*)) RELEASE_FILES := $(patsubst %,%.class,$(RELEASE_CLASS_PATH)) $(RELEASE_NESTED) else RELEASE_DBG_CLASS_PATH:= $(patsubst %,$(SOURCE_CLASSES_DBG_DIR)/$(PACKAGE)/%, $(RELEASE_CLASSES)) RELEASE_DBG_NESTED := $(foreach file,$(RELEASE_DBG_CLASS_PATH),$(wildcard $(file)$$*)) RELEASE_DBG_FILES := $(patsubst %,%.class,$(RELEASE_DBG_CLASS_PATH)) $(RELEASE_DBG_NESTED) endif # Substitute \$ for $ so the shell doesn't choke ifdef BUILD_OPT release_classes:: $(INSTALL) -m 444 $(subst $$,\$$,$(RELEASE_FILES)) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_CLASSES_DIR)/$(PACKAGE) else release_classes:: $(INSTALL) -m 444 $(subst $$,\$$,$(RELEASE_DBG_FILES)) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_CLASSES_DBG_DIR)/$(PACKAGE) endif endif release_policy:: +$(LOOP_OVER_DIRS) ifndef NO_MD_RELEASE ifdef LIBRARY MD_LIB_RELEASE_FILES += $(LIBRARY) endif ifdef SHARED_LIBRARY MD_LIB_RELEASE_FILES += $(SHARED_LIBRARY) endif ifdef IMPORT_LIBRARY MD_LIB_RELEASE_FILES += $(IMPORT_LIBRARY) endif ifdef PROGRAM MD_BIN_RELEASE_FILES += $(PROGRAM) endif ifdef PROGRAMS MD_BIN_RELEASE_FILES += $(PROGRAMS) endif endif release_md:: ifneq ($(MD_LIB_RELEASE_FILES),) $(INSTALL) -m 444 $(MD_LIB_RELEASE_FILES) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR) endif ifneq ($(MD_BIN_RELEASE_FILES),) $(INSTALL) -m 555 $(MD_BIN_RELEASE_FILES) $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_BIN_DIR) endif +$(LOOP_OVER_DIRS) alltags: rm -f TAGS find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs etags -a find . -name dist -prune -o \( -name '*.[hc]' -o -name '*.cp' -o -name '*.cpp' \) -print | xargs ctags -a $(PROGRAM): $(OBJS) $(EXTRA_LIBS) @$(MAKE_OBJDIR) ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(MKPROG) $(subst /,\\,$(OBJS)) -Fe$@ -link $(LDFLAGS) $(subst /,\\,$(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS)) ifdef MT if test -f $@.manifest; then \ $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ rm -f $@.manifest; \ fi endif # MSVC with manifest tool else $(MKPROG) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) endif get_objs: @echo $(OBJS) $(LIBRARY): $(OBJS) @$(MAKE_OBJDIR) rm -f $@ ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(AR) $(subst /,\\,$(OBJS)) else $(AR) $(OBJS) endif $(RANLIB) $@ ifeq ($(OS_TARGET),OS2) $(IMPORT_LIBRARY): $(MAPFILE) rm -f $@ $(IMPLIB) $@ $< $(RANLIB) $@ endif ifdef SHARED_LIBRARY_LIBS ifdef BUILD_TREE SUB_SHLOBJS = $(foreach dir,$(SHARED_LIBRARY_DIRS),$(shell $(MAKE) -C $(dir) --no-print-directory get_objs)) else SUB_SHLOBJS = $(foreach dir,$(SHARED_LIBRARY_DIRS),$(addprefix $(dir)/,$(shell $(MAKE) -C $(dir) --no-print-directory get_objs))) endif endif $(SHARED_LIBRARY): $(OBJS) $(RES) $(MAPFILE) $(SUB_SHLOBJS) @$(MAKE_OBJDIR) rm -f $@ ifeq ($(OS_TARGET)$(OS_RELEASE), AIX4.1) echo "#!" > $(OBJDIR)/lib$(LIBRARY_NAME)_syms nm -B -C -g $(OBJS) \ | awk '/ [T,D] / {print $$3}' \ | sed -e 's/^\.//' \ | sort -u >> $(OBJDIR)/lib$(LIBRARY_NAME)_syms $(LD) $(XCFLAGS) -o $@ $(OBJS) -bE:$(OBJDIR)/lib$(LIBRARY_NAME)_syms \ -bM:SRE -bnoentry $(OS_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) else ifeq (,$(filter-out WIN%,$(OS_TARGET))) ifdef NS_USE_GCC $(LINK_DLL) $(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES) else $(LINK_DLL) -MAP $(DLLBASE) $(subst /,\\,$(OBJS) $(SUB_SHLOBJS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) $(LD_LIBS) $(RES)) ifdef MT if test -f $@.manifest; then \ $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;2; \ rm -f $@.manifest; \ fi endif # MSVC with manifest tool endif else $(MKSHLIB) -o $@ $(OBJS) $(SUB_SHLOBJS) $(LD_LIBS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) chmod +x $@ endif endif ifeq (,$(filter-out WIN%,$(OS_TARGET))) $(RES): $(RESNAME) @$(MAKE_OBJDIR) # The resource compiler does not understand the -U option. ifdef NS_USE_GCC $(RC) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) -o $@ $< else $(RC) $(filter-out -U%,$(DEFINES)) $(INCLUDES) -Fo$@ $< endif @echo $(RES) finished endif $(MAPFILE): $(MAPFILE_SOURCE) @$(MAKE_OBJDIR) $(PROCESS_MAP_FILE) $(OBJDIR)/$(PROG_PREFIX)%$(PROG_SUFFIX): $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX) @$(MAKE_OBJDIR) ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(MKPROG) $< -Fe$@ -link \ $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) ifdef MT if test -f $@.manifest; then \ $(MT) -NOLOGO -MANIFEST $@.manifest -OUTPUTRESOURCE:$@\;1; \ rm -f $@.manifest; \ fi endif # MSVC with manifest tool else $(MKPROG) -o $@ $(CFLAGS) $< \ $(LDFLAGS) $(EXTRA_LIBS) $(EXTRA_SHARED_LIBS) $(OS_LIBS) endif WCCFLAGS1 := $(subst /,\\,$(CFLAGS)) WCCFLAGS2 := $(subst -I,-i=,$(WCCFLAGS1)) WCCFLAGS3 := $(subst -D,-d,$(WCCFLAGS2)) # Translate source filenames to absolute paths. This is required for # debuggers under Windows & OS/2 to find source files automatically ifeq (,$(filter-out OS2 AIX,$(OS_TARGET))) # OS/2 and AIX NEED_ABSOLUTE_PATH := 1 PWD := $(shell pwd) else # Windows ifeq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) NEED_ABSOLUTE_PATH := 1 ifdef .PYMAKE PWD := $(CURDIR) else PWD := $(shell pwd) ifeq (,$(findstring ;,$(PATH))) ifndef USE_MSYS PWD := $(subst \,/,$(shell cygpath -w $(PWD))) endif endif endif else # everything else PWD := $(shell pwd) endif endif # The quotes allow absolute paths to contain spaces. core_abspath = "$(if $(findstring :,$(1)),$(1),$(if $(filter /%,$(1)),$(1),$(PWD)/$(1)))" $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.c @$(MAKE_OBJDIR) ifdef USE_NT_C_SYNTAX $(CC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH $(CC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CC) -o $@ -c $(CFLAGS) $< endif endif $(PROG_PREFIX)%$(OBJ_SUFFIX): %.c ifdef USE_NT_C_SYNTAX $(CC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH $(CC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CC) -o $@ -c $(CFLAGS) $< endif endif ifneq (,$(filter-out _WIN%,$(NS_USE_GCC)_$(OS_TARGET))) $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.s @$(MAKE_OBJDIR) $(AS) -o $@ $(ASFLAGS) -c $< endif $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.asm @$(MAKE_OBJDIR) $(AS) -Fo$@ $(ASFLAGS) -c $< $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.S @$(MAKE_OBJDIR) $(AS) -o $@ $(ASFLAGS) -c $< $(OBJDIR)/$(PROG_PREFIX)%: %.cpp @$(MAKE_OBJDIR) ifdef USE_NT_C_SYNTAX $(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH $(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CCC) -o $@ -c $(CFLAGS) $< endif endif # # Please keep the next two rules in sync. # $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cc @$(MAKE_OBJDIR) $(CCC) -o $@ -c $(CFLAGS) $< $(OBJDIR)/$(PROG_PREFIX)%$(OBJ_SUFFIX): %.cpp @$(MAKE_OBJDIR) ifdef STRICT_CPLUSPLUS_SUFFIX echo "#line 1 \"$<\"" | cat - $< > $(OBJDIR)/t_$*.cc $(CCC) -o $@ -c $(CFLAGS) $(OBJDIR)/t_$*.cc rm -f $(OBJDIR)/t_$*.cc else ifdef USE_NT_C_SYNTAX $(CCC) -Fo$@ -c $(CFLAGS) $(call core_abspath,$<) else ifdef NEED_ABSOLUTE_PATH $(CCC) -o $@ -c $(CFLAGS) $(call core_abspath,$<) else $(CCC) -o $@ -c $(CFLAGS) $< endif endif endif #STRICT_CPLUSPLUS_SUFFIX %.i: %.cpp $(CCC) -C -E $(CFLAGS) $< > $@ %.i: %.c ifeq (,$(filter-out WIN%,$(OS_TARGET))) $(CC) -C /P $(CFLAGS) $< else $(CC) -C -E $(CFLAGS) $< > $@ endif ifneq (,$(filter-out WIN%,$(OS_TARGET))) %.i: %.s $(CC) -C -E $(CFLAGS) $< > $@ endif %: %.pl rm -f $@; cp $< $@; chmod +x $@ %: %.sh rm -f $@; cp $< $@; chmod +x $@ ################################################################################ # Bunch of things that extend the 'export' rule (in order): ################################################################################ $(JAVA_DESTPATH) $(JAVA_DESTPATH)/$(PACKAGE) $(JMCSRCDIR):: @if test ! -d $@; then \ echo Creating $@; \ rm -rf $@; \ $(NSINSTALL) -D $@; \ fi ################################################################################ ## IDL_GEN ifneq ($(IDL_GEN),) #export:: # $(IDL2JAVA) $(IDL_GEN) #all:: export #clobber:: # rm -f $(IDL_GEN:.idl=.class) # XXX wrong! endif ################################################################################ ### JSRCS -- for compiling java files ### ### NOTE: For backwards compatibility, if $(NETLIBDEPTH) is defined, ### replace $(CORE_DEPTH) with $(NETLIBDEPTH). ### ifneq ($(JSRCS),) ifneq ($(JAVAC),) ifdef NETLIBDEPTH CORE_DEPTH := $(NETLIBDEPTH) endif JAVA_EXPORT_SRCS=$(shell $(PERL) $(CORE_DEPTH)/coreconf/outofdate.pl $(PERLARG) -d $(JAVA_DESTPATH)/$(PACKAGE) $(JSRCS) $(PRIVATE_JSRCS)) export:: $(JAVA_DESTPATH) $(JAVA_DESTPATH)/$(PACKAGE) ifneq ($(JAVA_EXPORT_SRCS),) $(JAVAC) $(JAVA_EXPORT_SRCS) endif all:: export clobber:: rm -f $(SOURCE_XP_DIR)/classes/$(PACKAGE)/*.class endif endif # # JDIRS -- like JSRCS, except you can give a list of directories and it will # compile all the out-of-date java files in those directories. # # NOTE: recursing through these can speed things up, but they also cause # some builds to run out of memory # # NOTE: For backwards compatibility, if $(NETLIBDEPTH) is defined, # replace $(CORE_DEPTH) with $(NETLIBDEPTH). # ifdef JDIRS ifneq ($(JAVAC),) ifdef NETLIBDEPTH CORE_DEPTH := $(NETLIBDEPTH) endif # !!!!! THIS WILL CRASH SHMSDOS.EXE !!!!! # shmsdos does not support shell variables. It will crash when it tries # to parse the '=' character. A solution is to rewrite outofdate.pl so it # takes the Javac command as an argument and executes the command itself, # instead of returning a list of files. export:: $(JAVA_DESTPATH) $(JAVA_DESTPATH)/$(PACKAGE) @echo "!!! THIS COMMAND IS BROKEN ON WINDOWS--SEE rules.mk FOR DETAILS !!!" return -1 @for d in $(JDIRS); do \ if test -d $$d; then \ set $(EXIT_ON_ERROR); \ files=`echo $$d/*.java`; \ list=`$(PERL) $(CORE_DEPTH)/coreconf/outofdate.pl $(PERLARG) \ -d $(JAVA_DESTPATH)/$(PACKAGE) $$files`; \ if test "$${list}x" != "x"; then \ echo Building all java files in $$d; \ echo $(JAVAC) $$list; \ $(JAVAC) $$list; \ fi; \ set +e; \ else \ echo "Skipping non-directory $$d..."; \ fi; \ $(CLICK_STOPWATCH); \ done endif endif # # JDK_GEN -- for generating "old style" native methods # # Generate JDK Headers and Stubs into the '_gen' and '_stubs' directory # # NOTE: For backwards compatibility, if $(NETLIBDEPTH) is defined, # replace $(CORE_DEPTH) with $(NETLIBDEPTH). # ifneq ($(JDK_GEN),) ifneq ($(JAVAH),) ifdef NSBUILDROOT INCLUDES += -I$(JDK_GEN_DIR) -I$(SOURCE_XP_DIR) else INCLUDES += -I$(JDK_GEN_DIR) endif ifdef NETLIBDEPTH CORE_DEPTH := $(NETLIBDEPTH) endif JDK_PACKAGE_CLASSES := $(JDK_GEN) JDK_PATH_CLASSES := $(subst .,/,$(JDK_PACKAGE_CLASSES)) JDK_HEADER_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JDK_PATH_CLASSES)) JDK_STUB_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JDK_PATH_CLASSES)) JDK_HEADER_CFILES := $(patsubst %,$(JDK_GEN_DIR)/%.h,$(JDK_GEN)) JDK_STUB_CFILES := $(patsubst %,$(JDK_STUB_DIR)/%.c,$(JDK_GEN)) $(JDK_HEADER_CFILES): $(JDK_HEADER_CLASSFILES) $(JDK_STUB_CFILES): $(JDK_STUB_CLASSFILES) export:: @echo Generating/Updating JDK headers $(JAVAH) -d $(JDK_GEN_DIR) $(JDK_PACKAGE_CLASSES) @echo Generating/Updating JDK stubs $(JAVAH) -stubs -d $(JDK_STUB_DIR) $(JDK_PACKAGE_CLASSES) ifndef NO_MAC_JAVA_SHIT @if test ! -d $(CORE_DEPTH)/lib/mac/Java/; then \ echo "!!! You need to have a ns/lib/mac/Java directory checked out."; \ echo "!!! This allows us to automatically update generated files for the mac."; \ echo "!!! If you see any modified files there, please check them in."; \ fi @echo Generating/Updating JDK headers for the Mac $(JAVAH) -mac -d $(CORE_DEPTH)/lib/mac/Java/_gen $(JDK_PACKAGE_CLASSES) @echo Generating/Updating JDK stubs for the Mac $(JAVAH) -mac -stubs -d $(CORE_DEPTH)/lib/mac/Java/_stubs $(JDK_PACKAGE_CLASSES) endif endif endif # # JRI_GEN -- for generating "old style" JRI native methods # # Generate JRI Headers and Stubs into the 'jri' directory # # NOTE: For backwards compatibility, if $(NETLIBDEPTH) is defined, # replace $(CORE_DEPTH) with $(NETLIBDEPTH). # ifneq ($(JRI_GEN),) ifneq ($(JAVAH),) ifdef NSBUILDROOT INCLUDES += -I$(JRI_GEN_DIR) -I$(SOURCE_XP_DIR) else INCLUDES += -I$(JRI_GEN_DIR) endif ifdef NETLIBDEPTH CORE_DEPTH := $(NETLIBDEPTH) endif JRI_PACKAGE_CLASSES := $(JRI_GEN) JRI_PATH_CLASSES := $(subst .,/,$(JRI_PACKAGE_CLASSES)) JRI_HEADER_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JRI_PATH_CLASSES)) JRI_STUB_CLASSFILES := $(patsubst %,$(JAVA_DESTPATH)/%.class,$(JRI_PATH_CLASSES)) JRI_HEADER_CFILES := $(patsubst %,$(JRI_GEN_DIR)/%.h,$(JRI_GEN)) JRI_STUB_CFILES := $(patsubst %,$(JRI_GEN_DIR)/%.c,$(JRI_GEN)) $(JRI_HEADER_CFILES): $(JRI_HEADER_CLASSFILES) $(JRI_STUB_CFILES): $(JRI_STUB_CLASSFILES) export:: @echo Generating/Updating JRI headers $(JAVAH) -jri -d $(JRI_GEN_DIR) $(JRI_PACKAGE_CLASSES) @echo Generating/Updating JRI stubs $(JAVAH) -jri -stubs -d $(JRI_GEN_DIR) $(JRI_PACKAGE_CLASSES) ifndef NO_MAC_JAVA_SHIT @if test ! -d $(CORE_DEPTH)/lib/mac/Java/; then \ echo "!!! You need to have a ns/lib/mac/Java directory checked out."; \ echo "!!! This allows us to automatically update generated files for the mac."; \ echo "!!! If you see any modified files there, please check them in."; \ fi @echo Generating/Updating JRI headers for the Mac $(JAVAH) -jri -mac -d $(CORE_DEPTH)/lib/mac/Java/_jri $(JRI_PACKAGE_CLASSES) @echo Generating/Updating JRI stubs for the Mac $(JAVAH) -jri -mac -stubs -d $(CORE_DEPTH)/lib/mac/Java/_jri $(JRI_PACKAGE_CLASSES) endif endif endif # # JNI_GEN -- for generating JNI native methods # # Generate JNI Headers into the 'jni' directory # ifneq ($(JNI_GEN),) ifneq ($(JAVAH),) JNI_HEADERS := $(patsubst %,$(JNI_GEN_DIR)/%.h,$(JNI_GEN)) export:: @if test ! -d $(JNI_GEN_DIR); then \ echo $(JAVAH) -jni -d $(JNI_GEN_DIR) $(JNI_GEN); \ $(JAVAH) -jni -d $(JNI_GEN_DIR) $(JNI_GEN); \ else \ echo "Checking for out of date header files" ; \ $(PERL) $(CORE_DEPTH)/coreconf/jniregen.pl $(PERLARG) \ -d $(JAVA_DESTPATH) -j "$(JAVAH) -jni -d $(JNI_GEN_DIR)" $(JNI_GEN);\ fi endif endif # # JMC_EXPORT -- for declaring which java classes are to be exported for jmc # ifneq ($(JMC_EXPORT),) JMC_EXPORT_PATHS := $(subst .,/,$(JMC_EXPORT)) JMC_EXPORT_FILES := $(patsubst %,$(JAVA_DESTPATH)/$(PACKAGE)/%.class,$(JMC_EXPORT_PATHS)) # # We're doing NSINSTALL -t here (copy mode) because calling INSTALL will pick up # your NSDISTMODE and make links relative to the current directory. This is a # problem because the source isn't in the current directory: # export:: $(JMC_EXPORT_FILES) $(JMCSRCDIR) $(NSINSTALL) -t -m 444 $(JMC_EXPORT_FILES) $(JMCSRCDIR) endif # # JMC_GEN -- for generating java modules # # Provide default export & install rules when using JMC_GEN # ifneq ($(JMC_GEN),) ifneq ($(JMC),) INCLUDES += -I$(JMC_GEN_DIR) -I. JMC_HEADERS := $(patsubst %,$(JMC_GEN_DIR)/%.h,$(JMC_GEN)) JMC_STUBS := $(patsubst %,$(JMC_GEN_DIR)/%.c,$(JMC_GEN)) JMC_OBJS := $(patsubst %,$(OBJDIR)/%$(OBJ_SUFFIX),$(JMC_GEN)) $(JMC_GEN_DIR)/M%.h: $(JMCSRCDIR)/%.class $(JMC) -d $(JMC_GEN_DIR) -interface $(JMC_GEN_FLAGS) $(?F:.class=) $(JMC_GEN_DIR)/M%.c: $(JMCSRCDIR)/%.class $(JMC) -d $(JMC_GEN_DIR) -module $(JMC_GEN_FLAGS) $(?F:.class=) $(OBJDIR)/M%$(OBJ_SUFFIX): $(JMC_GEN_DIR)/M%.c $(JMC_GEN_DIR)/M%.h @$(MAKE_OBJDIR) $(CC) -o $@ -c $(CFLAGS) $< export:: $(JMC_HEADERS) $(JMC_STUBS) endif endif # # Copy each element of EXPORTS to $(SOURCE_XP_DIR)/public/$(MODULE)/ # PUBLIC_EXPORT_DIR = $(SOURCE_XP_DIR)/public/$(MODULE) ifneq ($(EXPORTS),) $(PUBLIC_EXPORT_DIR):: @if test ! -d $@; then \ echo Creating $@; \ $(NSINSTALL) -D $@; \ fi export:: $(PUBLIC_EXPORT_DIR) export:: $(EXPORTS) $(INSTALL) -m 444 $^ $(PUBLIC_EXPORT_DIR) export:: $(BUILT_SRCS) endif # Duplicate export rule for private exports, with different directories PRIVATE_EXPORT_DIR = $(SOURCE_XP_DIR)/private/$(MODULE) ifneq ($(PRIVATE_EXPORTS),) $(PRIVATE_EXPORT_DIR):: @if test ! -d $@; then \ echo Creating $@; \ $(NSINSTALL) -D $@; \ fi private_export:: $(PRIVATE_EXPORT_DIR) private_export:: $(PRIVATE_EXPORTS) $(INSTALL) -m 444 $^ $(PRIVATE_EXPORT_DIR) else private_export:: @echo There are no private exports.; endif ########################################################################## ### RULES FOR RUNNING REGRESSION SUITE TESTS ### REQUIRES 'REGRESSION_SPEC' TO BE SET TO THE NAME OF A REGRESSION SPECFILE ### AND RESULTS_SUBDIR TO BE SET TO SOMETHING LIKE SECURITY/PKCS5 ########################################################################## TESTS_DIR = $(RESULTS_DIR)/$(RESULTS_SUBDIR)/$(OS_TARGET)$(OS_RELEASE)$(CPU_TAG)$(COMPILER_TAG)$(IMPL_STRATEGY) ifneq ($(REGRESSION_SPEC),) ifneq ($(BUILD_OPT),) REGDATE = $(subst \ ,, $(shell $(PERL) $(CORE_DEPTH)/$(MODULE)/scripts/now)) endif tests:: $(REGRESSION_SPEC) cd $(PLATFORM); \ ../$(SOURCE_MD_DIR)/bin/regress$(PROG_SUFFIX) specfile=../$(REGRESSION_SPEC) progress $(EXTRA_REGRESS_OPTIONS); \ if test ! -d $(TESTS_DIR); then \ echo Creating $(TESTS_DIR); \ $(NSINSTALL) -D $(TESTS_DIR); \ fi ifneq ($(BUILD_OPT),) $(NSINSTALL) -m 664 $(PLATFORM)/$(REGDATE).sum $(TESTS_DIR); \ $(NSINSTALL) -m 664 $(PLATFORM)/$(REGDATE).htm $(TESTS_DIR); \ echo "Please now make sure your results files are copied to $(TESTS_DIR), "; \ echo "then run 'reporter specfile=$(RESULTS_DIR)/rptspec'" endif else tests:: @echo Error: you didn't specify REGRESSION_SPEC in your manifest.mn file!; endif # Duplicate export rule for releases, with different directories ifneq ($(EXPORTS),) $(SOURCE_RELEASE_XP_DIR)/include:: @if test ! -d $@; then \ echo Creating $@; \ $(NSINSTALL) -D $@; \ fi release_export:: $(SOURCE_RELEASE_XP_DIR)/include release_export:: $(EXPORTS) $(INSTALL) -m 444 $^ $(SOURCE_RELEASE_XP_DIR)/include endif ################################################################################ -include $(DEPENDENCIES) ifneq (,$(filter-out OS2 WIN%,$(OS_TARGET))) # Can't use sed because of its 4000-char line length limit, so resort to perl PERL_DEPENDENCIES_PROGRAM = \ open(MD, "< $(DEPENDENCIES)"); \ while () { \ if (m@ \.*/*$< @) { \ $$found = 1; \ last; \ } \ } \ if ($$found) { \ print "Removing stale dependency $< from $(DEPENDENCIES)\n"; \ seek(MD, 0, 0); \ $$tmpname = "$(OBJDIR)/fix.md" . $$$$; \ open(TMD, "> " . $$tmpname); \ while () { \ s@ \.*/*$< @ @; \ if (!print TMD "$$_") { \ unlink(($$tmpname)); \ exit(1); \ } \ } \ close(TMD); \ if (!rename($$tmpname, "$(DEPENDENCIES)")) { \ unlink(($$tmpname)); \ } \ } elsif ("$<" ne "$(DEPENDENCIES)") { \ print "$(MAKE): *** No rule to make target $<. Stop.\n"; \ exit(1); \ } .DEFAULT: @$(PERL) -e '$(PERL_DEPENDENCIES_PROGRAM)' endif ############################################################################# # X dependency system ############################################################################# ifdef MKDEPENDENCIES # For Windows, $(MKDEPENDENCIES) must be -included before including rules.mk $(MKDEPENDENCIES):: @$(MAKE_OBJDIR) touch $(MKDEPENDENCIES) chmod u+w $(MKDEPENDENCIES) #on NT, the preceding touch command creates a read-only file !?!?! #which is why we have to explicitly chmod it. $(MKDEPEND) -p$(OBJDIR_NAME)/ -o'$(OBJ_SUFFIX)' -f$(MKDEPENDENCIES) \ $(NOMD_CFLAGS) $(YOPT) $(CSRCS) $(CPPSRCS) $(ASFILES) $(MKDEPEND):: $(MKDEPEND_DIR)/*.c $(MKDEPEND_DIR)/*.h $(MAKE) -C $(MKDEPEND_DIR) ifdef OBJS depend:: $(MKDEPEND) $(MKDEPENDENCIES) else depend:: endif +$(LOOP_OVER_DIRS) dependclean:: rm -f $(MKDEPENDENCIES) +$(LOOP_OVER_DIRS) #-include $(NSINSTALL_DIR)/$(OBJDIR)/depend.mk else depend:: endif # # HACK ALERT # # The only purpose of this rule is to pass Mozilla's Tinderbox depend # builds (http://tinderbox.mozilla.org/showbuilds.cgi). Mozilla's # Tinderbox builds NSS continuously as part of the Mozilla client. # Because NSS's make depend is not implemented, whenever we change # an NSS header file, the depend build does not recompile the NSS # files that depend on the header. # # This rule makes all the objects depend on a dummy header file. # Check in a change to this dummy header file to force the depend # build to recompile everything. # # This rule should be removed when make depend is implemented. # DUMMY_DEPEND = $(CORE_DEPTH)/coreconf/coreconf.dep $(filter $(OBJDIR)/%$(OBJ_SUFFIX),$(OBJS)): $(OBJDIR)/%$(OBJ_SUFFIX): $(DUMMY_DEPEND) # END OF HACK ################################################################################ # Special gmake rules. ################################################################################ # # Re-define the list of default suffixes, so gmake won't have to churn through # hundreds of built-in suffix rules for stuff we don't need. # .SUFFIXES: .SUFFIXES: .out .a .ln .o .obj .c .cc .C .cpp .y .l .s .S .h .sh .i .pl .class .java .html .asm .dep # # Don't delete these files if we get killed. # .PRECIOUS: .java $(JDK_HEADERS) $(JDK_STUBS) $(JRI_HEADERS) $(JRI_STUBS) $(JMC_HEADERS) $(JMC_STUBS) $(JNI_HEADERS) # # Fake targets. Always run these rules, even if a file/directory with that # name already exists. # .PHONY: all all_platforms alltags boot clean clobber clobber_all export install libs program realclean release $(OBJDIR) jss-4.4.3/jss/coreconf/ruleset.mk000066400000000000000000000161151326145000000167250ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # # # Parameters to this makefile (set these in this file): # # # # a) # # TARGETS -- the target to create # # (defaults to $LIBRARY $PROGRAM) # # b) # # DIRS -- subdirectories for make to recurse on # # (the 'all' rule builds $TARGETS $DIRS) # # c) # # CSRCS, CPPSRCS -- .c and .cpp files to compile # # (used to define $OBJS) # # d) # # PROGRAM -- the target program name to create from $OBJS # # ($OBJDIR automatically prepended to it) # # e) # # LIBRARY -- the target library name to create from $OBJS # # ($OBJDIR automatically prepended to it) # # f) # # JSRCS -- java source files to compile into class files # # (if you don't specify this it will default # # to *.java) # # g) # # PACKAGE -- the package to put the .class files into # # (e.g. netscape/applet) # # (NOTE: the default definition for this may be # # overridden if "jdk.mk" is included) # # h) # # JMC_EXPORT -- java files to be exported for use by JMC_GEN # # (this is a list of Class names) # # i) # # JRI_GEN -- files to run through javah to generate headers # # and stubs # # (output goes into the _jri sub-dir) # # j) # # JMC_GEN -- files to run through jmc to generate headers # # and stubs # # (output goes into the _jmc sub-dir) # # k) # # JNI_GEN -- files to run through javah to generate headers # # (output goes into the _jni sub-dir) # # # ####################################################################### # # CPU_TAG is now defined in the $(TARGET).mk files # ifndef COMPILER_TAG ifneq ($(DEFAULT_COMPILER), $(notdir $(firstword $(CC)))) # # Temporary define for the Client; to be removed when binary release is used # ifdef MOZILLA_CLIENT COMPILER_TAG = else COMPILER_TAG = _$(notdir $(firstword $(CC))) endif else COMPILER_TAG = endif endif ifeq ($(MKPROG),) MKPROG = $(CC) endif # # This makefile contains rules for building the following kinds of # objects: # - (1) LIBRARY: a static (archival) library # - (2) SHARED_LIBRARY: a shared (dynamic link) library # - (3) IMPORT_LIBRARY: an import library, defined in $(OS_TARGET).mk # - (4) PROGRAM: an executable binary # # NOTE: The names of libraries can be generated by simply specifying # LIBRARY_NAME (and LIBRARY_VERSION in the case of non-static libraries). # LIBRARY and SHARED_LIBRARY may be defined differently in $(OS_TARGET).mk # ifdef LIBRARY_NAME ifndef LIBRARY LIBRARY = $(OBJDIR)/$(LIB_PREFIX)$(LIBRARY_NAME).$(LIB_SUFFIX) endif ifndef SHARED_LIBRARY SHARED_LIBRARY = $(OBJDIR)/$(DLL_PREFIX)$(LIBRARY_NAME)$(LIBRARY_VERSION)$(JDK_DEBUG_SUFFIX).$(DLL_SUFFIX) endif ifndef MAPFILE_SOURCE MAPFILE_SOURCE = $(LIBRARY_NAME).def endif endif # # Common rules used by lots of makefiles... # ifdef PROGRAM PROGRAM := $(addprefix $(OBJDIR)/, $(PROGRAM)$(JDK_DEBUG_SUFFIX)$(PROG_SUFFIX)) endif ifdef PROGRAMS PROGRAMS := $(addprefix $(OBJDIR)/, $(PROGRAMS:%=%$(JDK_DEBUG_SUFFIX)$(PROG_SUFFIX))) endif ifndef TARGETS TARGETS = $(LIBRARY) $(SHARED_LIBRARY) $(PROGRAM) endif ifndef OBJS SIMPLE_OBJS = $(JRI_STUB_CFILES) \ $(addsuffix $(OBJ_SUFFIX), $(JMC_GEN)) \ $(CSRCS:.c=$(OBJ_SUFFIX)) \ $(CPPSRCS:.cpp=$(OBJ_SUFFIX)) \ $(ASFILES:$(ASM_SUFFIX)=$(OBJ_SUFFIX)) \ $(BUILT_CSRCS:.c=$(OBJ_SUFFIX)) \ $(BUILT_CPPSRCS:.cpp=$(OBJ_SUFFIX)) \ $(BUILT_ASFILES:$(ASM_SUFFIX)=$(OBJ_SUFFIX)) OBJS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), $(SIMPLE_OBJS)) endif ifndef BUILT_SRCS BUILT_SRCS = $(addprefix $(OBJDIR)/$(PROG_PREFIX), \ $(BUILT_CSRCS) $(BUILT_CPPSRCS) $(BUILT_ASFILES)) endif ifeq (,$(filter-out WIN%,$(OS_TARGET))) MAKE_OBJDIR = $(INSTALL) -D $(OBJDIR) else define MAKE_OBJDIR if test ! -d $(@D); then rm -rf $(@D); $(NSINSTALL) -D $(@D); fi endef endif ifndef PACKAGE PACKAGE = . endif ifdef NSBUILDROOT JDK_GEN_DIR = $(SOURCE_XP_DIR)/_gen JMC_GEN_DIR = $(SOURCE_XP_DIR)/_jmc JNI_GEN_DIR = $(SOURCE_XP_DIR)/_jni JRI_GEN_DIR = $(SOURCE_XP_DIR)/_jri JDK_STUB_DIR = $(SOURCE_XP_DIR)/_stubs else JDK_GEN_DIR = _gen JMC_GEN_DIR = _jmc JNI_GEN_DIR = _jni JRI_GEN_DIR = _jri JDK_STUB_DIR = _stubs endif ALL_TRASH = $(TARGETS) $(OBJS) $(OBJDIR) LOGS TAGS $(GARBAGE) \ so_locations $(BUILT_SRCS) $(NOSUCHFILE) ifdef NS_USE_JDK ALL_TRASH += $(JDK_HEADER_CFILES) $(JDK_STUB_CFILES) \ $(JMC_HEADERS) $(JMC_STUBS) $(JMC_EXPORT_FILES) \ $(JNI_HEADERS) \ $(JRI_HEADER_CFILES) $(JRI_STUB_CFILES) \ $(JDK_GEN_DIR) $(JMC_GEN_DIR) $(JNI_GEN_DIR) \ $(JRI_GEN_DIR) $(JDK_STUB_DIR) ifdef JAVA_DESTPATH ALL_TRASH += $(wildcard $(JAVA_DESTPATH)/$(PACKAGE)/*.class) ifdef JDIRS ALL_TRASH += $(addprefix $(JAVA_DESTPATH)/,$(JDIRS)) endif else # !JAVA_DESTPATH ALL_TRASH += $(wildcard $(PACKAGE)/*.class) $(JDIRS) endif endif #NS_USE_JDK ifdef NSS_BUILD_CONTINUE_ON_ERROR # Try to build everything. I.e., don't exit on errors. EXIT_ON_ERROR = +e IGNORE_ERROR = - CLICK_STOPWATCH = date else EXIT_ON_ERROR = -e IGNORE_ERROR = CLICK_STOPWATCH = true endif ifdef REQUIRES MODULE_INCLUDES := $(addprefix -I$(SOURCE_XP_DIR)/public/, $(REQUIRES)) INCLUDES += $(MODULE_INCLUDES) ifeq ($(MODULE), sectools) PRIVATE_INCLUDES := $(addprefix -I$(SOURCE_XP_DIR)/private/, $(REQUIRES)) INCLUDES += $(PRIVATE_INCLUDES) endif endif ifdef SYSTEM_INCL_DIR YOPT = -Y$(SYSTEM_INCL_DIR) endif ifdef DIRS define SUBMAKE +@echo "cd $2; $(MAKE) $1" $(IGNORE_ERROR)@$(MAKE) -C $(2) $(1) @$(CLICK_STOPWATCH) endef LOOP_OVER_DIRS = $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir))) endif MK_RULESET = included jss-4.4.3/jss/coreconf/source.mk000066400000000000000000000107251326145000000165430ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master -specific source import/export directories # ####################################################################### # # master import/export directory prefix # ifndef SOURCE_PREFIX ifndef BUILD_TREE SOURCE_PREFIX = $(CORE_DEPTH)/../dist else SOURCE_PREFIX = $(BUILD_TREE)/dist endif endif # # cross-platform (xp) master import/export directory # ifndef SOURCE_XP_DIR SOURCE_XP_DIR = $(SOURCE_PREFIX) endif # # cross-platform (xp) import/export directories # SOURCE_CLASSES_DIR = $(SOURCE_XP_DIR)/classes SOURCE_CLASSES_DBG_DIR = $(SOURCE_XP_DIR)/classes_DBG SOURCE_XPHEADERS_DIR = $(SOURCE_XP_DIR)/public/$(MODULE) SOURCE_XPPRIVATE_DIR = $(SOURCE_XP_DIR)/private/$(MODULE) ifdef BUILD_OPT IMPORT_XPCLASS_DIR = $(SOURCE_CLASSES_DIR) else IMPORT_XPCLASS_DIR = $(SOURCE_CLASSES_DBG_DIR) endif # # machine-dependent (md) master import/export directory # ifndef SOURCE_MD_DIR SOURCE_MD_DIR = $(SOURCE_PREFIX)/$(PLATFORM) endif # # machine-dependent (md) import/export directories # #This is where we install built executables and (for Windows only) DLLs. ifndef SOURCE_BIN_DIR SOURCE_BIN_DIR = $(SOURCE_MD_DIR)/bin endif #This is where we install built libraries (.a, .so, .lib). ifndef SOURCE_LIB_DIR SOURCE_LIB_DIR = $(SOURCE_MD_DIR)/lib endif # This is where NSPR header files are found. ifndef SOURCE_MDHEADERS_DIR SOURCE_MDHEADERS_DIR = $(SOURCE_MD_DIR)/include endif ####################################################################### # Master -specific source release directories and files # ####################################################################### # # source-side master release directory prefix # NOTE: export control policy enforced for XP and MD files released to # the staging area # ifeq ($(POLICY), domestic) SOURCE_RELEASE_PREFIX = $(SOURCE_PREFIX)/release/domestic else ifeq ($(POLICY), export) SOURCE_RELEASE_PREFIX = $(SOURCE_PREFIX)/release/export else ifeq ($(POLICY), france) SOURCE_RELEASE_PREFIX = $(SOURCE_PREFIX)/release/france else #We shouldn't have to put another directory under here, but without it the perl #script for releasing doesn't find the directory. It thinks it doesn't exist. #So we're adding this no-policy directory so that the script for releasing works #in all casese when policy is not set. This doesn't affect where the final jar #files land, only where they are placed in the local tree when building the jar #files. When there is no policy, the jar files will still land in #/// like they used to. SOURCE_RELEASE_PREFIX = $(SOURCE_PREFIX)/release/no-policy endif endif endif # # cross-platform (xp) source-side master release directory # SOURCE_RELEASE_XP_DIR = $(SOURCE_RELEASE_PREFIX) # # cross-platform (xp) source-side release directories # SOURCE_RELEASE_CLASSES_DIR = classes SOURCE_RELEASE_CLASSES_DBG_DIR = classes_DBG SOURCE_RELEASE_XPHEADERS_DIR = include # # cross-platform (xp) JAR source-side release files # XPCLASS_JAR = xpclass.jar XPCLASS_DBG_JAR = xpclass_dbg.jar XPHEADER_JAR = xpheader.jar ifdef BUILD_OPT SOURCE_RELEASE_XP_CLASSES_DIR = $(SOURCE_RELEASE_CLASSES_DIR) IMPORT_XPCLASS_JAR = $(XPCLASS_JAR) else SOURCE_RELEASE_XP_CLASSES_DIR = $(SOURCE_RELEASE_CLASSES_DBG_DIR) IMPORT_XPCLASS_JAR = $(XPCLASS_DBG_JAR) endif # # machine-dependent (md) source-side master release directory # SOURCE_RELEASE_MD_DIR = $(PLATFORM) # # machine-dependent (md) source-side release directories # SOURCE_RELEASE_BIN_DIR = $(PLATFORM)/bin SOURCE_RELEASE_LIB_DIR = $(PLATFORM)/lib SOURCE_RELEASE_MDHEADERS_DIR = $(PLATFORM)/include SOURCE_RELEASE_SPEC_DIR = $(SOURCE_RELEASE_MD_DIR) # # machine-dependent (md) JAR/tar source-side release files # MDBINARY_JAR = mdbinary.jar MDHEADER_JAR = mdheader.jar # Where to put the results ifneq ($(RESULTS_DIR),) RESULTS_DIR = $(RELEASE_TREE)/sectools/results endif MK_SOURCE = included jss-4.4.3/jss/coreconf/suffix.mk000066400000000000000000000024341326145000000165450ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master "Core Components" suffixes # ####################################################################### # # Object suffixes (OS2 and WIN% override this) # ifndef OBJ_SUFFIX OBJ_SUFFIX = .o endif # # Assembler source suffixes (OS2 and WIN% override this) # ifndef ASM_SUFFIX ASM_SUFFIX = .s endif # # Library suffixes # STATIC_LIB_EXTENSION = ifndef DYNAMIC_LIB_EXTENSION DYNAMIC_LIB_EXTENSION = endif ifndef STATIC_LIB_SUFFIX STATIC_LIB_SUFFIX = .$(LIB_SUFFIX) endif ifndef DYNAMIC_LIB_SUFFIX DYNAMIC_LIB_SUFFIX = .$(DLL_SUFFIX) endif # WIN% overridese this ifndef IMPORT_LIB_SUFFIX IMPORT_LIB_SUFFIX = endif ifndef STATIC_LIB_SUFFIX_FOR_LINKING STATIC_LIB_SUFFIX_FOR_LINKING = $(STATIC_LIB_SUFFIX) endif # WIN% overridese this ifndef DYNAMIC_LIB_SUFFIX_FOR_LINKING DYNAMIC_LIB_SUFFIX_FOR_LINKING = $(DYNAMIC_LIB_SUFFIX) endif # # Program suffixes (OS2 and WIN% override this) # ifndef PROG_SUFFIX PROG_SUFFIX = endif MK_SUFFIX = included jss-4.4.3/jss/coreconf/tree.mk000066400000000000000000000024211326145000000161740ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Master "Core Components" file system "release" prefixes # ####################################################################### # Windows platforms override this. See WIN32.mk. ifndef RELEASE_TREE ifdef BUILD_SHIP ifdef USE_SHIPS RELEASE_TREE = $(BUILD_SHIP) else RELEASE_TREE = /share/builds/components endif else RELEASE_TREE = /share/builds/components endif endif # # NOTE: export control policy enforced for XP and MD files # released to the binary release tree # ifeq ($(POLICY), domestic) RELEASE_XP_DIR = domestic RELEASE_MD_DIR = domestic/$(PLATFORM) else ifeq ($(POLICY), export) RELEASE_XP_DIR = export RELEASE_MD_DIR = export/$(PLATFORM) else ifeq ($(POLICY), france) RELEASE_XP_DIR = france RELEASE_MD_DIR = france/$(PLATFORM) else RELEASE_XP_DIR = RELEASE_MD_DIR = $(PLATFORM) endif endif endif REPORTER_TREE = $(subst \,\\,$(RELEASE_TREE)) IMPORT_XP_DIR = IMPORT_MD_DIR = $(PLATFORM) MK_TREE = included jss-4.4.3/jss/coreconf/version.mk000066400000000000000000000034461326145000000167320ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Build master "Core Components" release version directory name # ####################################################################### # # Always set CURRENT_VERSION_SYMLINK to the symbolic link. # CURRENT_VERSION_SYMLINK = current # # For the sake of backwards compatibility (*sigh*) ... # ifndef VERSION ifdef BUILD_NUM VERSION = $(BUILD_NUM) endif endif ifndef RELEASE_VERSION ifdef BUILD_NUM RELEASE_VERSION = $(BUILD_NUM) endif endif # # If VERSION has still NOT been set on the command line, # as an environment variable, by the individual Makefile, or # by the -specific "version.mk" file, set VERSION equal # to $(CURRENT_VERSION_SYMLINK). ifndef VERSION VERSION = $(CURRENT_VERSION_SYMLINK) endif # If RELEASE_VERSION has still NOT been set on the command line, # as an environment variable, by the individual Makefile, or # by the -specific "version.mk" file, automatically # generate the next available version number via a perl script. # ifndef RELEASE_VERSION RELEASE_VERSION = endif # # Set -specific versions for compiliation and linkage. # ifndef JAVA_VERSION JAVA_VERSION = $(CURRENT_VERSION_SYMLINK) endif ifndef NETLIB_VERSION NETLIB_VERSION = $(CURRENT_VERSION_SYMLINK) endif ifndef NSPR_VERSION NSPR_VERSION = $(CURRENT_VERSION_SYMLINK) endif ifndef SECTOOLS_VERSION SECTOOLS_VERSION = $(CURRENT_VERSION_SYMLINK) endif ifndef SECURITY_VERSION SECURITY_VERSION = $(CURRENT_VERSION_SYMLINK) endif MK_VERSION = included jss-4.4.3/jss/coreconf/version.pl000066400000000000000000000023511326145000000167300ustar00rootroot00000000000000#!/usr/sbin/perl # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Compose lowercase alphabet @alphabet = ( "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" ); # Compute year $year = (localtime)[5] + 1900; # Compute month $month = (localtime)[4] + 1; # Compute day $day = (localtime)[3]; # Compute base build number $version = sprintf( "%d%02d%02d", $year, $month, $day ); $directory = sprintf( "%s\/%s\/%d%02d%02d", $ARGV[0], $ARGV[1], $year, $month, $day ); # Print out the name of the first version directory which does not exist #if( ! -e $directory ) #{ print $version; #} #else #{ # # Loop through combinations # foreach $ch1 (@alphabet) # { # foreach $ch2 (@alphabet) # { # $version = sprintf( "%d%02d%02d%s%s", $year, $month, $day, $ch1, $ch2 ); # $directory = sprintf( "%s\/%s\/%d%02d%02d%s%s", $ARGV[0], $ARGV[1], $year, $month, $day, $ch1, $ch2 ); # if( ! -e $directory ) # { # print STDOUT $version; # exit; # } # } # } #} jss-4.4.3/jss/jss.html000066400000000000000000000060261326145000000146000ustar00rootroot00000000000000 Netscape Security Services for Java

Netscape Security Services for Java

Netscape Security Services for Java (JSS) is an interface allowing Java applications to use the Secure Sockets Layer protocol. The interface is implemented with the FIPS-validated Netscape Security Services library. It consists of a system-dependent dynamic library (libjss.so on UNIX, jss.dll on Windows) and a ZIP file (jss.zip) containing system-independent Java classes. These classes are compatible with JDK 1.1 or later using the native thread implementation (not green threads).

Building Applications with JSS

To construct Java applications that use JSS, you must:
  • Call the JSS classes from your application.
  • When compiling your application, put jss.zip in your CLASSPATH.
  • When running your application, put libjss.so in your LD_LIBRARY_PATH (on UNIX) or jss.dll in your PATH (on Windows), and put jss.zip in your CLASSPATH.

Programming with JSS

Before the SSL classes can be used, NSSInit.initialize must be called to open the security databases and initialize the random number generator. NSSInit.setPasswordCallback may be called to change the password callback; the default is to prompt for passwords on the command line.

The files in the examples directory illustrate the use of JSS in an application:

SSLClient.java
An example of an SSL client application.
SSLServer.java
An example of an SSL server application. To run, it requires certificate and key databases that contain a certificate called "SSLServer". The sample cert7.db and key3.db files, also in the examples directory, can be used for this purpose. When SSLServer is run, it will ask for a password for the "Internal Key Storage Token", which is the key database. The password for the example key3.db file is "netscape".
These classes are in the org.mozilla.jss.ssl package. The .class files must be put in the subdirectory org/mozilla/jss/ssl of a CLASSPATH entry in order to be located by the Java virtual machine.

Javadoc for the JSS Classes

jss-4.4.3/jss/lib/000077500000000000000000000000001326145000000136555ustar00rootroot00000000000000jss-4.4.3/jss/lib/Makefile000066400000000000000000000036361326145000000153250ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/rules.mk ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### include rules.mk jss-4.4.3/jss/lib/config.mk000066400000000000000000000045101326145000000154530ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. LIBRARY = SHARED_LIBRARY_LIBS=yes SHARED_LIBRARY_DIRS = \ ../org/mozilla/jss/crypto \ ../org/mozilla/jss/SecretDecoderRing \ ../org/mozilla/jss \ ../org/mozilla/jss/pkcs11 \ ../org/mozilla/jss/asn1 \ ../org/mozilla/jss/ssl \ ../org/mozilla/jss/util \ ../org/mozilla/jss/provider/java/security \ $(NULL) NSPR_LIB_NAMES = plc4 plds4 nspr4 NSS_LIB_NAMES = smime3 ssl3 nss3 ifdef USE_UTIL_DIRECTLY NSS_LIB_NAMES += nssutil3 endif ifeq ($(OS_ARCH),WINNT) SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).lib DLLFLAGS += -DEF:jss.def RES = $(OBJDIR)/jss.res RESNAME = jss.rc EXTRA_SHARED_LIBS += \ $(addprefix $(NSS_LIB_DIR)/, $(addsuffix .$(LIB_SUFFIX), $(NSS_LIB_NAMES))) \ $(addprefix $(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX), $(addsuffix .$(LIB_SUFFIX), $(NSPR_LIB_NAMES))) \ $(JAVA_LIBS) \ $(DLLSYSTEM) \ $(NULL) else ifeq ($(OS_ARCH),Darwin) DLL_SUFFIX = jnilib endif EXTRA_SHARED_LIBS += \ -L$(NSS_LIB_DIR) \ $(addprefix -l, $(NSS_LIB_NAMES)) \ -L$(NSPR_LIB_DIR) \ $(addprefix -l, $(NSPR_LIB_NAMES)) \ $(JAVA_LIBS) \ $(NULL) endif # Include "funky" link path to pick up ALL native libraries for OSF/1. ifeq ($(OS_ARCH), OSF1) JAVA_LIBS += -L$(JAVA_HOME)/$(JAVA_LIBDIR).no endif ifeq ($(OS_ARCH),Linux) MAPFILE = $(OBJDIR)/jssmap.linux ALL_TRASH += $(MAPFILE) MKSHLIB += -Wl,--version-script,$(MAPFILE) endif ifeq ($(OS_ARCH),SunOS) MAPFILE = $(OBJDIR)/jssmap.sun ALL_TRASH += $(MAPFILE) MKSHLIB += -M $(MAPFILE) #ifndef USE_64 #ifeq ($(CPU_ARCH),sparc) # The -R '$ORIGIN' linker option instructs libnss3.so to search for its # dependencies (libfreebl_*.so) in the same directory where it resides. #MKSHLIB += -R '$$ORIGIN' #endif #endif endif ifeq ($(OS_ARCH),AIX) MAPFILE = $(OBJDIR)/jssmap.aix ALL_TRASH += $(MAPFILE) EXPORT_RULES = -bexport:$(MAPFILE) endif ifeq ($(OS_ARCH),HP-UX) MAPFILE = $(OBJDIR)/jssmap.hp ALL_TRASH += $(MAPFILE) MKSHLIB += -c $(MAPFILE) endif ifeq ($(OS_ARCH), OSF1) MAPFILE = $(OBJDIR)/jssmap.osf ALL_TRASH += $(MAPFILE) MKSHLIB += -hidden -input $(MAPFILE) endif jss-4.4.3/jss/lib/jss.def000066400000000000000000000366601326145000000151470ustar00rootroot00000000000000LIBRARY jss4 ;- ;+# ;+# This Source Code Form is subject to the terms of the Mozilla Public ;+# License, v. 2.0. If a copy of the MPL was not distributed with this ;+# file, You can obtain one at http://mozilla.org/MPL/2.0/. ;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS ;+# 1. For all unix platforms, the string ";-" means "remove this line" ;+# 2. For all unix platforms, the string " DATA " will be removed from any ;+# line on which it occurs. ;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX. ;+# On AIX, lines containing ";+" will be removed. ;+# 4. For all unix platforms, the string ";;" will have the ";;" removed. ;+# 5. For all unix platforms, after the above processing has taken place, ;+# all characters after the first ";" on the line will be removed. ;+# And for AIX, the first ";" will also be removed. ;+# This file is passed directly to windows. Since ';' is a comment, all UNIX ;+# directives are hidden behind ";", ";+", and ";-" ;+JSS_3.0 { # JSS 3.0 release ;+ global: LIBRARY jss4 ;- EXPORTS ;- Java_org_mozilla_jss_crypto_EncryptionAlgorithm_getIVLength; Java_org_mozilla_jss_crypto_PQGParams_generateNative__I; Java_org_mozilla_jss_crypto_PQGParams_generateNative__II; Java_org_mozilla_jss_crypto_PQGParams_paramsAreValidNative; Java_org_mozilla_jss_DatabaseCloser_closeDatabases; Java_org_mozilla_jss_CryptoManager_FIPSEnabled; Java_org_mozilla_jss_CryptoManager_buildCertificateChainNative; Java_org_mozilla_jss_CryptoManager_enableFIPS; Java_org_mozilla_jss_CryptoManager_exportCertsToPKCS7; Java_org_mozilla_jss_CryptoManager_findCertByIssuerAndSerialNumberNative; Java_org_mozilla_jss_CryptoManager_findCertByNicknameNative; Java_org_mozilla_jss_CryptoManager_findCertsByNicknameNative; Java_org_mozilla_jss_CryptoManager_findPrivKeyByCertNative; Java_org_mozilla_jss_CryptoManager_getCACerts; Java_org_mozilla_jss_CryptoManager_getPermCerts; Java_org_mozilla_jss_CryptoManager_importCRLNative; Java_org_mozilla_jss_CryptoManager_importCertPackageNative; Java_org_mozilla_jss_CryptoManager_importCertToPermNative; Java_org_mozilla_jss_CryptoManager_initializeAllNative; Java_org_mozilla_jss_CryptoManager_putModulesInVector; Java_org_mozilla_jss_CryptoManager_setNativePasswordCallback; Java_org_mozilla_jss_pkcs11_CertProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_CipherContextProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Module_getLibraryName; Java_org_mozilla_jss_pkcs11_PK11Module_getName; Java_org_mozilla_jss_pkcs11_PK11Module_putTokensInVector; Java_org_mozilla_jss_pkcs11_ModuleProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Cert_getEncoded; Java_org_mozilla_jss_pkcs11_PK11Cert_getIssuerDNString; Java_org_mozilla_jss_pkcs11_PK11Cert_getNickname; Java_org_mozilla_jss_pkcs11_PK11Cert_getOwningToken; Java_org_mozilla_jss_pkcs11_PK11Cert_getPublicKey; Java_org_mozilla_jss_pkcs11_PK11Cert_getSerialNumberByteArray; Java_org_mozilla_jss_pkcs11_PK11Cert_getSubjectDNString; Java_org_mozilla_jss_pkcs11_PK11Cert_getTrust; Java_org_mozilla_jss_pkcs11_PK11Cert_getUniqueID; Java_org_mozilla_jss_pkcs11_PK11Cert_getVersion; Java_org_mozilla_jss_pkcs11_PK11Cert_setTrust; Java_org_mozilla_jss_pkcs11_PK11Cipher_finalizeContext; Java_org_mozilla_jss_pkcs11_PK11Cipher_initContext; Java_org_mozilla_jss_pkcs11_PK11Cipher_updateContext; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapPrivWithSym; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithPriv; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithSym; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapPrivWithSym; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithPub; Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithSym; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_digest; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initDigest; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initHMAC; Java_org_mozilla_jss_pkcs11_PK11MessageDigest_update; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getKeyType; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getOwningToken; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getStrength; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getUniqueID; Java_org_mozilla_jss_pkcs11_PK11PrivKey_verifyKeyIsOnToken; Java_org_mozilla_jss_pkcs11_PK11PubKey_DSAFromRaw; Java_org_mozilla_jss_pkcs11_PK11PubKey_RSAFromRaw; Java_org_mozilla_jss_pkcs11_PK11PubKey_getEncoded; Java_org_mozilla_jss_pkcs11_PK11PubKey_getKeyType; Java_org_mozilla_jss_pkcs11_PK11PubKey_verifyKeyIsOnToken; Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyData; Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyType; Java_org_mozilla_jss_pkcs11_PK11SymKey_getOwningToken; Java_org_mozilla_jss_pkcs11_PK11SymKey_getStrength; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPair; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPair; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateNormal; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE_1IV; Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_nativeClone; Java_org_mozilla_jss_pkcs11_PrivateKeyProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PublicKeyProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_SymKeyProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Token_PWInitable; Java_org_mozilla_jss_pkcs11_PK11Token_SSOPasswordIsCorrect; Java_org_mozilla_jss_pkcs11_PK11Token_changePassword; Java_org_mozilla_jss_pkcs11_PK11Token_doesAlgorithm; Java_org_mozilla_jss_pkcs11_PK11Token_generatePK10; Java_org_mozilla_jss_pkcs11_PK11Token_getLoginMode; Java_org_mozilla_jss_pkcs11_PK11Token_getLoginTimeoutMinutes; Java_org_mozilla_jss_pkcs11_PK11Token_getName; Java_org_mozilla_jss_pkcs11_PK11Token_initPassword; Java_org_mozilla_jss_pkcs11_PK11Token_isLoggedIn; Java_org_mozilla_jss_pkcs11_PK11Token_isPresent; Java_org_mozilla_jss_pkcs11_PK11Token_isWritable; Java_org_mozilla_jss_pkcs11_PK11Token_logout; Java_org_mozilla_jss_pkcs11_PK11Token_nativeLogin; Java_org_mozilla_jss_pkcs11_PK11Token_passwordIsInitialized; Java_org_mozilla_jss_pkcs11_PK11Token_setLoginMode; Java_org_mozilla_jss_pkcs11_PK11Token_setLoginTimeoutMinutes; Java_org_mozilla_jss_pkcs11_PK11Token_userPasswordIsCorrect; Java_org_mozilla_jss_pkcs11_TokenProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawSignNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawVerifyNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineSignNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineUpdateNative; Java_org_mozilla_jss_pkcs11_PK11Signature_engineVerifyNative; Java_org_mozilla_jss_pkcs11_PK11Signature_initSigContext; Java_org_mozilla_jss_pkcs11_PK11Signature_initVfyContext; Java_org_mozilla_jss_pkcs11_PK11Store_deleteCert; Java_org_mozilla_jss_pkcs11_PK11Store_deletePrivateKey; Java_org_mozilla_jss_pkcs11_PK11Store_importPrivateKey; Java_org_mozilla_jss_pkcs11_PK11Store_putCertsInVector; Java_org_mozilla_jss_pkcs11_PK11Store_putKeysInVector; Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector; Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector; Java_org_mozilla_jss_pkcs11_SigContextProxy_releaseNativeResources; Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getModulusByteArray; Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getPublicExponentByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getGByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getPByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getQByteArray; Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getYByteArray; Java_org_mozilla_jss_pkcs11_PK11SecureRandom_nextBytes; Java_org_mozilla_jss_pkcs11_PK11SecureRandom_setSeed; Java_org_mozilla_jss_ssl_SSLServerSocket_clearSessionCache; Java_org_mozilla_jss_ssl_SSLServerSocket_configServerSessionIDCache; Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCertNickname; Java_org_mozilla_jss_ssl_SSLServerSocket_socketAccept; Java_org_mozilla_jss_ssl_SSLServerSocket_socketListen; Java_org_mozilla_jss_ssl_SSLSocket_forceHandshake; Java_org_mozilla_jss_ssl_SSLSocket_getKeepAlive; Java_org_mozilla_jss_ssl_SSLSocket_getLocalAddressNative; Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressByteArrayNative; Java_org_mozilla_jss_ssl_SSLSocket_getPort; Java_org_mozilla_jss_ssl_SSLSocket_getReceiveBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_getSendBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_getSoLinger; Java_org_mozilla_jss_ssl_SSLSocket_getStatus; Java_org_mozilla_jss_ssl_SSLSocket_getTcpNoDelay; Java_org_mozilla_jss_ssl_SSLSocket_invalidateSession; Java_org_mozilla_jss_ssl_SSLSocket_redoHandshake; Java_org_mozilla_jss_ssl_SSLSocket_resetHandshakeNative; Java_org_mozilla_jss_ssl_SSLSocket_setCipherPolicyNative; Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreference; Java_org_mozilla_jss_ssl_SSLSocket_setKeepAlive; Java_org_mozilla_jss_ssl_SSLSocket_setReceiveBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOption; Java_org_mozilla_jss_ssl_SSLSocket_setSendBufferSize; Java_org_mozilla_jss_ssl_SSLSocket_setSoLinger; Java_org_mozilla_jss_ssl_SSLSocket_setTcpNoDelay; Java_org_mozilla_jss_ssl_SSLSocket_shutdownNative; Java_org_mozilla_jss_ssl_SSLSocket_socketAvailable; Java_org_mozilla_jss_ssl_SSLSocket_socketConnect; Java_org_mozilla_jss_ssl_SSLSocket_socketRead; Java_org_mozilla_jss_ssl_SSLSocket_socketWrite; Java_org_mozilla_jss_ssl_SocketBase_getLocalPortNative; Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressNative; Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressByteArrayNative; Java_org_mozilla_jss_ssl_SocketBase_setClientCertNicknameNative; Java_org_mozilla_jss_ssl_SocketBase_requestClientAuthNoExpiryCheckNative; Java_org_mozilla_jss_ssl_SocketBase_setSSLOption; Java_org_mozilla_jss_ssl_SocketBase_socketBind; Java_org_mozilla_jss_ssl_SocketBase_socketClose; Java_org_mozilla_jss_ssl_SocketBase_socketCreate; Java_org_mozilla_jss_util_Debug_setNativeLevel; Java_org_mozilla_jss_util_Password_readPasswordFromConsole; ;+# ;+# Data objects (NONE) ;+# ;+# ;+# commands (NONE) ;+# ;+# ;+ local: ;+ *; ;+}; ;+JSS_3.1 { # JSS 3.1 release ;+ global: Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymPlaintext; Java_org_mozilla_jss_pkcs11_PK11Store_getEncryptedPrivateKeyInfo; ;+ local: ;+ *; ;+}; ;+JSS_3.1.1 { # JSS 3.1.1 release ;+ global: Java_org_mozilla_jss_ssl_SSLServerSocket_setReuseAddress; Java_org_mozilla_jss_ssl_SSLServerSocket_getReuseAddress; ;+ local: ;+ *; ;+}; ;+JSS_3.2 { # JSS 3.2 release ;+ global: Java_org_mozilla_jss_crypto_SecretDecoderRing_encrypt; Java_org_mozilla_jss_crypto_SecretDecoderRing_decrypt; Java_org_mozilla_jss_pkcs11_PK11PrivKey_fromPrivateKeyInfo; Java_org_mozilla_jss_pkcs11_PK11PubKey_fromRawNative; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getRawAliases; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineDeleteEntry; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getDERCert; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertNickname; Java_org_mozilla_jss_pkcs11_PK11PubKey_fromSPKI; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKey; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineIsCertificateEntry; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineSetKeyEntryNative; Java_org_mozilla_jss_CryptoManager_initializeAllNative2; Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressNative; Java_org_mozilla_jss_pkcs11_PK11PrivKey_getDSAParamsNative; Java_org_mozilla_jss_CryptoManager_verifyCertNowNative; Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCert; Java_org_mozilla_jss_ssl_SocketBase_setClientCert; Java_org_mozilla_jss_CryptoManager_verifyCertTempNative; Java_org_mozilla_jss_ssl_SocketProxy_releaseNativeResources; ;+ local: ;+ *; ;+}; ;+JSS_3.3 { # JSS 3.3 release ;+ global: Java_org_mozilla_jss_ssl_SSLSocket_getImplementedCipherSuites; Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreferenceDefault; Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreferenceDefault; Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreference; Java_org_mozilla_jss_CryptoManager_configureOCSPNative; Java_org_mozilla_jss_pkcs11_PK11SymKey_getLength; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertObject; Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_deleteKeyNative; ;+ local: ;+ *; ;+}; ;+JSS_3.4 { # JSS 3.4 release ;+ global: Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits; ;+ local: ;+ *; ;+}; ;+JSS_3.5 { # JSS 3.5 release ;+ global: Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateUniqueNamedKeyNative; Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupUniqueNamedKeyNative; ;+ local: ;+ *; ;+}; ;+JSS_4.1 { # JSS 4.1 release ;+ global: Java_org_mozilla_jss_ssl_SSLSocket_abortReadWrite; Java_org_mozilla_jss_ssl_SSLServerSocket_abortAccept; ;+ local: ;+ *; ;+}; ;+JSS_4.2 { # JSS 4.2 release ;+ global: Java_org_mozilla_jss_ssl_SocketBase_getSSLOption; Java_org_mozilla_jss_ssl_SSLSocket_getSSLDefaultOption; Java_org_mozilla_jss_pkcs11_PK11Store_deleteCertOnly; ;+ local: ;+ *; ;+}; ;+JSS_4.2.3 { # JSS 4.2.3 release ;+ global: Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getCurveByteArray; Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getWByteArray; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPair; ;+ local: ;+ *; ;+}; ;+JSS_4.2.5 { # JSS 4.2.5 release ;+ global: Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOptionMode; Java_org_mozilla_jss_ssl_SocketBase_setSSLOptionMode; Java_org_mozilla_jss_ssl_SSLSocket_isFipsCipherSuiteNative; ;+ local: ;+ *; ;+}; ;+JSS_4.3 { # JSS 4.3 release ;+ global: Java_org_mozilla_jss_pkcs11_PK11Token_needsLogin; ;+ local: ;+ *; ;+}; ;+JSS_4.2.6 { # JSS 4.2.6 release ;+ global: Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags; Java_org_mozilla_jss_CryptoManager_OCSPCacheSettingsNative; Java_org_mozilla_jss_CryptoManager_setOCSPTimeoutNative; Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative; Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2; Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative; Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid; Java_org_mozilla_jss_ssl_SocketBase_setSSLVersionRange; Java_org_mozilla_jss_ssl_SSLSocket_setSSLVersionRangeDefault; Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey; Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative; ;+ local: ;+ *; ;+}; ;+JSS_4.3.1 { # JSS 4.3.1 release ;+ global: Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags; Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags; Java_org_mozilla_jss_CryptoManager_OCSPCacheSettingsNative; Java_org_mozilla_jss_CryptoManager_setOCSPTimeoutNative; Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey; Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative; ;+ local: ;+ *; ;+}; ;+JSS_4.4.1 { # JSS 4.4.1 release ;+ global: Java_org_mozilla_jss_pkcs11_PK11Store_importEncryptedPrivateKeyInfo; ;+ local: ;+ *; ;+}; jss-4.4.3/jss/lib/jss.rc000066400000000000000000000035001326145000000150000ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "jssver.h" #include #define MY_LIBNAME "jss" #define MY_FILEDESCRIPTION "JSS Library" #define STRINGIZE(x) #x #define STRINGIZE2(x) STRINGIZE(x) #define JSS_VMAJOR_STR STRINGIZE2(JSS_VMAJOR) #ifdef _DEBUG #define MY_DEBUG_STR " (debug)" #define MY_FILEFLAGS_1 VS_FF_DEBUG #else #define MY_DEBUG_STR "" #define MY_FILEFLAGS_1 0x0L #endif #if JSS_BETA #define MY_FILEFLAGS_2 MY_FILEFLAGS_1|VS_FF_PRERELEASE #else #define MY_FILEFLAGS_2 MY_FILEFLAGS_1 #endif #ifdef WINNT #define MY_FILEOS VOS_NT_WINDOWS32 #else #define MY_FILEOS VOS__WINDOWS32 #endif #define MY_INTERNAL_NAME MY_LIBNAME JSS_VMAJOR_STR ///////////////////////////////////////////////////////////////////////////// // // Version-information resource // VS_VERSION_INFO VERSIONINFO FILEVERSION JSS_VMAJOR,JSS_VMINOR,JSS_VPATCH,0 PRODUCTVERSION JSS_VMAJOR,JSS_VMINOR,JSS_VPATCH,0 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS MY_FILEFLAGS_2 FILEOS MY_FILEOS FILETYPE VFT_DLL FILESUBTYPE 0x0L // not used BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904B0" // Lang=US English, CharSet=Unicode BEGIN VALUE "CompanyName", "Mozilla Foundation\0" VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0" VALUE "FileVersion", JSS_VERSION "\0" VALUE "InternalName", MY_INTERNAL_NAME "\0" VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0" VALUE "ProductName", "Network Security Services for Java\0" VALUE "ProductVersion", JSS_VERSION "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END jss-4.4.3/jss/lib/manifest.mn000066400000000000000000000022571326145000000160250ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. #/********************************************************************/ #/* The VERSION Strings should be updated in the following */ #/* files everytime a new release of JSS is generated: */ #/* */ #/* lib/manifest.mn */ #/* org/mozilla/jss/CryptoManager.c */ #/* org/mozilla/jss/CryptoManager.java */ #/* org/mozilla/jss/JSSProvider.java */ #/* org/mozilla/jss/util/jssver.h */ #/* */ #/********************************************************************/ CORE_DEPTH = .. MODULE = jss NS_USE_JDK = 1 LIBRARY_NAME = jss #/* LIBRARY_VERSION=JSS_VMAJOR so you only update when */ #/* you update the JSS_VMAJOR */ LIBRARY_VERSION = 4 jss-4.4.3/jss/lib/rules.mk000066400000000000000000000037711326145000000153500ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. release_md:: release_sanitize release_sanitize:: -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(DLL_PREFIX)jsscrypto$(DYNAMIC_LIB_EXTENSION)$(DYNAMIC_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(DLL_PREFIX)jssmanage$(DYNAMIC_LIB_EXTENSION)$(DYNAMIC_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(DLL_PREFIX)jsspkcs11$(DYNAMIC_LIB_EXTENSION)$(DYNAMIC_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(DLL_PREFIX)jssasn1$(DYNAMIC_LIB_EXTENSION)$(DYNAMIC_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(DLL_PREFIX)jsspolicy$(DYNAMIC_LIB_EXTENSION)$(DYNAMIC_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(DLL_PREFIX)jssssl$(DYNAMIC_LIB_EXTENSION)$(DYNAMIC_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(DLL_PREFIX)jssutil$(DYNAMIC_LIB_EXTENSION)$(DYNAMIC_LIB_SUFFIX) ifeq ($(OS_ARCH),WINNT) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(IMPORT_LIB_PREFIX)jsscrypto$(IMPORT_LIB_EXTENSION)$(IMPORT_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(IMPORT_LIB_PREFIX)jssmanage$(IMPORT_LIB_EXTENSION)$(IMPORT_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(IMPORT_LIB_PREFIX)jsspkcs11$(IMPORT_LIB_EXTENSION)$(IMPORT_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(IMPORT_LIB_PREFIX)jssasn1$(IMPORT_LIB_EXTENSION)$(IMPORT_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(IMPORT_LIB_PREFIX)jsspolicy$(IMPORT_LIB_EXTENSION)$(IMPORT_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(IMPORT_LIB_PREFIX)jssssl$(IMPORT_LIB_EXTENSION)$(IMPORT_LIB_SUFFIX) -rm $(SOURCE_RELEASE_PREFIX)/$(SOURCE_RELEASE_LIB_DIR)/$(IMPORT_LIB_PREFIX)jssutil$(IMPORT_LIB_EXTENSION)$(IMPORT_LIB_SUFFIX) endif jss-4.4.3/jss/manifest.mn000066400000000000000000000021331326145000000152500ustar00rootroot00000000000000# # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = . MODULE = jss #/********************************************************************/ #/* The VERSION Strings should be updated in the following */ #/* files everytime a new release of JSS is generated: */ #/* */ #/* lib/manifest.mn */ #/* org/mozilla/jss/CryptoManager.c */ #/* org/mozilla/jss/CryptoManager.java */ #/* org/mozilla/jss/JSSProvider.java */ #/* org/mozilla/jss/util/jssver.h */ #/* */ #/********************************************************************/ DIRS = coreconf \ org \ lib \ $(NULL) RELEASE = jss jss-4.4.3/jss/org/000077500000000000000000000000001326145000000136765ustar00rootroot00000000000000jss-4.4.3/jss/org/Makefile000066400000000000000000000034631326145000000153440ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/manifest.mn000066400000000000000000000004161326145000000160410ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = .. MODULE = jss DIRS = mozilla \ $(NULL) jss-4.4.3/jss/org/mozilla/000077500000000000000000000000001326145000000153455ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/Makefile000066400000000000000000000034631326145000000170130ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/000077500000000000000000000000001326145000000161445ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/CRLImportException.java000066400000000000000000000007001326145000000224760ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss; /** * Thrown if a CRL cannot be imported */ public class CRLImportException extends java.lang.Exception { public CRLImportException() {} public CRLImportException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/CertDatabaseException.java000066400000000000000000000010261326145000000232070ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss; /** * This exception is thrown if the certificate database does not exist, * or if an error occurs while opening it. */ public class CertDatabaseException extends java.lang.Exception { public CertDatabaseException() {} public CertDatabaseException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/CryptoManager.c000066400000000000000000001001361326145000000210640ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_CryptoManager.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #if defined(AIX) || defined(HPUX) #include #endif /** These externs are only here to ** keep certain compilers from optimizing the ** version info away. */ #include "util/jssver.h" extern const char __jss_base_rcsid[]; extern const char __jss_base_sccsid[]; const char * jss_rcsid() { return __jss_base_rcsid; } const char * jss_sccsid() { return __jss_base_sccsid; } /********************************************************************/ /* The VERSION Strings should be updated in the following */ /* files everytime a new release of JSS is generated: */ /* */ /* lib/manifest.mn */ /* org/mozilla/jss/CryptoManager.c */ /* org/mozilla/jss/CryptoManager.java */ /* org/mozilla/jss/JSSProvider.java */ /* org/mozilla/jss/util/jssver.h */ /* */ /********************************************************************/ /* JSS_VERSION from mozilla/security/jss/org/mozilla/jss/util/jssver.h */ static const char* VARIABLE_MAY_NOT_BE_USED DLL_JSS_VERSION = "JSS_VERSION = " JSS_VERSION; /* NSS_VERSION from mozilla/security/nss/lib/nss/nss.h */ static const char* VARIABLE_MAY_NOT_BE_USED DLL_NSS_VERSION = "NSS_VERSION = " NSS_VERSION; /* NSPR_version from mozilla/nsprpub/pr/include/prinit.h */ static const char* VARIABLE_MAY_NOT_BE_USED DLL_NSPR_VERSION = "NSPR_VERSION = " PR_VERSION; static jobject makePWCBInfo(JNIEnv *env, PK11SlotInfo *slot); static char* getPWFromCallback(PK11SlotInfo *slot, PRBool retry, void *arg); /************************************************************* * AIX and HP signal handling madness * * In order for the JVM, kernel, and NSPR to work together, we setup * a signal handler for SIGCHLD that does nothing. This is only done * on AIX and HP. *************************************************************/ #if defined(AIX) || defined(HPUX) static PRStatus handleSigChild(JNIEnv *env) { struct sigaction action; sigset_t signalset; int result; sigemptyset(&signalset); action.sa_handler = SIG_DFL; action.sa_mask = signalset; action.sa_flags = 0; result = sigaction( SIGCHLD, &action, NULL ); if( result != 0 ) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "Failed to set SIGCHLD handler"); return PR_FAILURE; } return PR_SUCCESS; } #endif int ConfigureOCSP( JNIEnv *env, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname ) { char *ocspResponderURL_string=NULL; char *ocspResponderCertNickname_string=NULL; SECStatus status; int result = SECSuccess; CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); /* if caller specified default responder, get the * strings associated with these args */ if (ocspResponderURL) { ocspResponderURL_string = (char*) (*env)->GetStringUTFChars(env, ocspResponderURL, NULL); if (ocspResponderURL_string == NULL) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "OCSP invalid URL"); result = SECFailure; goto loser; } } if (ocspResponderCertNickname) { ocspResponderCertNickname_string = (char*) (*env)->GetStringUTFChars(env, ocspResponderCertNickname, NULL); if (ocspResponderCertNickname_string == NULL) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "OCSP invalid nickname"); result = SECFailure; goto loser; } } /* first disable OCSP - we'll enable it later */ CERT_DisableOCSPChecking(certdb); /* if they set the default responder, then set it up * and enable it */ if (ocspResponderURL) { /* if ocspResponderURL is set they must specify the ocspResponderCertNickname */ if (ocspResponderCertNickname == NULL ) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "if OCSP responderURL is set, the Responder Cert nickname must be set"); result = SECFailure; goto loser; } else { CERTCertificate *cert; /* if the nickname is set */ cert = CERT_FindCertByNickname(certdb, ocspResponderCertNickname_string); if (cert == NULL) { /* * look for the cert on an external token. */ cert = PK11_FindCertFromNickname(ocspResponderCertNickname_string, NULL); } if (cert == NULL) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "Unable to find the OCSP Responder Certificate nickname."); result = SECFailure; goto loser; } CERT_DestroyCertificate(cert); } status = CERT_SetOCSPDefaultResponder( certdb, ocspResponderURL_string, ocspResponderCertNickname_string ); if (status == SECFailure) { /* deal with error */ JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "OCSP Could not set responder"); result = SECFailure; goto loser; } CERT_EnableOCSPDefaultResponder(certdb); } else { /* if no defaultresponder is set, disable it */ CERT_DisableOCSPDefaultResponder(certdb); } /* enable OCSP checking if requested */ if (ocspCheckingEnabled) { CERT_EnableOCSPChecking(certdb); } loser: if (ocspResponderURL_string) { (*env)->ReleaseStringUTFChars(env, ocspResponderURL, ocspResponderURL_string); } if (ocspResponderCertNickname_string) { (*env)->ReleaseStringUTFChars(env, ocspResponderCertNickname, ocspResponderCertNickname_string); } return result; } /********************************************************************** * This is the PasswordCallback object that will be used to login * to tokens implicitly. */ static jobject globalPasswordCallback = NULL; /********************************************************************** * The Java virtual machine can be used to retrieve the JNI environment * pointer from callback functions. */ JavaVM * JSS_javaVM; JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_initializeAllNative (JNIEnv *env, jclass clazz, jstring configDir, jstring certPrefix, jstring keyPrefix, jstring secmodName, jboolean readOnly, jstring manuString, jstring libraryString, jstring tokString, jstring keyTokString, jstring slotString, jstring keySlotString, jstring fipsString, jstring fipsKeyString, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname, jboolean initializeJavaOnly, jboolean PKIXVerify, jboolean noCertDB, jboolean noModDB, jboolean forceOpen, jboolean noRootInit, jboolean optimizeSpace, jboolean PK11ThreadSafe, jboolean PK11Reload, jboolean noPK11Finalize, jboolean cooperate) { Java_org_mozilla_jss_CryptoManager_initializeAllNative2( env, clazz, configDir, certPrefix, keyPrefix, secmodName, readOnly, manuString, libraryString, tokString, keyTokString, slotString, keySlotString, fipsString, fipsKeyString, ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname, JNI_FALSE, /*initializeJavaOnly*/ PKIXVerify, noCertDB, noModDB, forceOpen, noRootInit, optimizeSpace, PK11ThreadSafe, PK11Reload, noPK11Finalize, cooperate); } JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_initializeAllNative2 (JNIEnv *env, jclass clazz, jstring configDir, jstring certPrefix, jstring keyPrefix, jstring secmodName, jboolean readOnly, jstring manuString, jstring libraryString, jstring tokString, jstring keyTokString, jstring slotString, jstring keySlotString, jstring fipsString, jstring fipsKeyString, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname, jboolean initializeJavaOnly, jboolean PKIXVerify, jboolean noCertDB, jboolean noModDB, jboolean forceOpen, jboolean noRootInit, jboolean optimizeSpace, jboolean PK11ThreadSafe, jboolean PK11Reload, jboolean noPK11Finalize, jboolean cooperate) { SECStatus rv = SECFailure; char *szConfigDir = NULL; char *szCertPrefix = NULL; char *szKeyPrefix = NULL; char *szSecmodName = NULL; char *manuChars=NULL; char *libraryChars=NULL; char *tokChars=NULL; char *keyTokChars=NULL; char *slotChars=NULL; char *keySlotChars=NULL; char *fipsChars=NULL; char *fipsKeyChars=NULL; PRUint32 initFlags; /* This is thread-safe because initialize is synchronized */ static PRBool initialized=PR_FALSE; if( configDir == NULL || manuString == NULL || libraryString == NULL || tokString == NULL || keyTokString == NULL || slotString == NULL || keySlotString == NULL || fipsString == NULL || fipsKeyString == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } /* Make sure initialize() completes only once */ if(initialized) { JSS_throw(env, ALREADY_INITIALIZED_EXCEPTION); goto finish; } /* * Save the JavaVM pointer so we can retrieve the JNI environment * later. This only works if there is only one Java VM. */ if( (*env)->GetJavaVM(env, &JSS_javaVM) != 0 ) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to to access Java virtual machine"); PR_ASSERT(PR_FALSE); goto finish; } /* * Initialize the errcode translation table. */ JSS_initErrcodeTranslationTable(); /* * The rest of the initialization (the NSS stuff) is skipped if * the initializeJavaOnly flag is set. */ if( initializeJavaOnly) { initialized = PR_TRUE; goto finish; } /* * Set the PKCS #11 strings */ manuChars = (char*) (*env)->GetStringUTFChars(env, manuString, NULL); libraryChars = (char*) (*env)->GetStringUTFChars(env, libraryString, NULL); tokChars = (char*) (*env)->GetStringUTFChars(env, tokString, NULL); keyTokChars = (char*) (*env)->GetStringUTFChars(env, keyTokString, NULL); slotChars = (char*) (*env)->GetStringUTFChars(env, slotString, NULL); keySlotChars = (char*) (*env)->GetStringUTFChars(env, keySlotString, NULL); fipsChars = (char*) (*env)->GetStringUTFChars(env, fipsString, NULL); fipsKeyChars = (char*) (*env)->GetStringUTFChars(env, fipsKeyString, NULL); if( (*env)->ExceptionOccurred(env) ) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT( strlen(manuChars) == 33 ); PR_ASSERT( strlen(libraryChars) == 33 ); PR_ASSERT( strlen(tokChars) == 33 ); PR_ASSERT( strlen(keyTokChars) == 33 ); PR_ASSERT( strlen(slotChars) == 65 ); PR_ASSERT( strlen(keySlotChars) == 65 ); PR_ASSERT( strlen(fipsChars) == 65 ); PR_ASSERT( strlen(fipsKeyChars) == 65 ); PK11_ConfigurePKCS11( manuChars, libraryChars, tokChars, keyTokChars, slotChars, keySlotChars, fipsChars, fipsKeyChars, 0, /* minimum pin length */ PR_FALSE /* password required */ ); szConfigDir = (char*) (*env)->GetStringUTFChars(env, configDir, NULL); if( certPrefix != NULL || keyPrefix != NULL || secmodName != NULL || noCertDB || noModDB || forceOpen || noRootInit || optimizeSpace || PK11ThreadSafe || PK11Reload || noPK11Finalize || cooperate) { /* * Set up arguments to NSS_Initialize */ if( certPrefix != NULL ) { szCertPrefix = (char*) (*env)->GetStringUTFChars(env, certPrefix, NULL); } if ( keyPrefix != NULL ) { szKeyPrefix = (char*) (*env)->GetStringUTFChars(env, keyPrefix, NULL); } if ( secmodName != NULL ) { szSecmodName = (char*) (*env)->GetStringUTFChars(env, secmodName, NULL); } initFlags = 0; if( readOnly ) { initFlags |= NSS_INIT_READONLY; } if( noCertDB ) { initFlags |= NSS_INIT_NOCERTDB; } if( noModDB ) { initFlags |= NSS_INIT_NOMODDB; } if( forceOpen ) { initFlags |= NSS_INIT_FORCEOPEN; } if( noRootInit ) { initFlags |= NSS_INIT_NOROOTINIT; } if( optimizeSpace ) { initFlags |= NSS_INIT_OPTIMIZESPACE; } if( PK11ThreadSafe ) { initFlags |= NSS_INIT_PK11THREADSAFE; } if( PK11Reload ) { initFlags |= NSS_INIT_PK11RELOAD; } if( noPK11Finalize ) { initFlags |= NSS_INIT_NOPK11FINALIZE; } if( cooperate ) { initFlags |= NSS_INIT_COOPERATE; } /* * Initialize NSS. */ rv = NSS_Initialize(szConfigDir, szCertPrefix, szKeyPrefix, szSecmodName, initFlags); } else { if( readOnly ) { rv = NSS_Init(szConfigDir); } else { rv = NSS_InitReadWrite(szConfigDir); } } if( rv != SECSuccess ) { JSS_throwMsg(env, SECURITY_EXCEPTION, "Unable to initialize security library"); goto finish; } /* * Set default password callback. This is the only place this * should ever be called if you are using Ninja. */ PK11_SetPasswordFunc(getPWFromCallback); /* * Setup NSS to call the specified OCSP responder */ rv = ConfigureOCSP( env, ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname ); if (rv != SECSuccess) { goto finish; } /* * Set up policy. We're always domestic now. Thanks to the US Government! */ if( NSS_SetDomesticPolicy() != SECSuccess ) { JSS_throwMsg(env, SECURITY_EXCEPTION, "Unable to set security policy"); goto finish; } if ( PKIXVerify ) { CERT_SetUsePKIXForValidation(PR_TRUE); } initialized = PR_TRUE; finish: /* LET'S BE CAREFUL. Unbraced if statements ahead. */ if(szConfigDir) (*env)->ReleaseStringUTFChars(env, configDir, szConfigDir); if(szCertPrefix) (*env)->ReleaseStringUTFChars(env, certPrefix, szCertPrefix); if(szKeyPrefix) (*env)->ReleaseStringUTFChars(env, keyPrefix, szKeyPrefix); if(szSecmodName) (*env)->ReleaseStringUTFChars(env, secmodName, szSecmodName); if(manuChars) (*env)->ReleaseStringUTFChars(env, manuString, manuChars); if(libraryChars) (*env)->ReleaseStringUTFChars(env, libraryString, libraryChars); if(tokChars) (*env)->ReleaseStringUTFChars(env, tokString, tokChars); if(keyTokChars) (*env)->ReleaseStringUTFChars(env, keyTokString, keyTokChars); if(slotChars) (*env)->ReleaseStringUTFChars(env, slotString, slotChars); if(keySlotChars) (*env)->ReleaseStringUTFChars(env, keySlotString, keySlotChars); if(fipsChars) (*env)->ReleaseStringUTFChars(env, fipsString, fipsChars); if(fipsKeyChars) (*env)->ReleaseStringUTFChars(env, fipsKeyString, fipsKeyChars); return; } /********************************************************************** * * JSS_setPasswordCallback * * Sets the global PasswordCallback object, which will be used to * login to tokens implicitly if necessary. * */ void JSS_setPasswordCallback(JNIEnv *env, jobject callback) { PR_ASSERT(env!=NULL && callback!=NULL); /* Free the previously-registered password callback */ if( globalPasswordCallback != NULL ) { (*env)->DeleteGlobalRef(env, globalPasswordCallback); globalPasswordCallback = NULL; } /* Store the new password callback */ globalPasswordCallback = (*env)->NewGlobalRef(env, callback); if(globalPasswordCallback == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); } } /********************************************************************** * * CryptoManager.setNativePasswordCallback * * Sets the global PasswordCallback object, which will be used to * login to tokens implicitly if necessary. * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_setNativePasswordCallback (JNIEnv *env, jclass clazz, jobject callback) { JSS_setPasswordCallback(env, callback); } /******************************************************************** * * g e t P W F r o m C a l l b a c k * * Extracts a password from a password callback and returns * it to PKCS #11. * * INPUTS * slot * The PK11SlotInfo* for the slot we are logging into. * retry * PR_TRUE if this is the first time we are trying to login, * PR_FALSE if we tried before and our password was wrong. * arg * This can contain a Java PasswordCallback object reference, * or NULL to use the default password callback. * RETURNS * The password as extracted from the callback, or NULL if the * callback gives up. */ static char* getPWFromCallback(PK11SlotInfo *slot, PRBool retry, void *arg) { jobject pwcbInfo; jobject pwObject; jbyteArray pwArray=NULL; char* pwchars; char* returnchars=NULL; jclass callbackClass; jclass passwordClass; jmethodID getPWMethod; jmethodID getByteCopyMethod; jmethodID clearMethod; jthrowable exception; jobject callback; JNIEnv *env; PR_ASSERT(slot!=NULL); if(slot==NULL) { return NULL; } /* Get the callback from the arg, or use the default */ PR_ASSERT(sizeof(void*) == sizeof(jobject)); callback = (jobject)arg; if(callback == NULL) { callback = globalPasswordCallback; if(callback == NULL) { /* No global password callback set, no way to get a password */ return NULL; } } /* Get the JNI environment */ if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto finish; } PR_ASSERT(env != NULL); /***************************************** * Construct the JSS_PasswordCallbackInfo *****************************************/ pwcbInfo = makePWCBInfo(env, slot); if(pwcbInfo==NULL) { goto finish; } /***************************************** * Get the callback class and methods *****************************************/ callbackClass = (*env)->GetObjectClass(env, callback); if(callbackClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find password " "callback class"); PR_ASSERT(PR_FALSE); } if(retry) { getPWMethod = (*env)->GetMethodID( env, callbackClass, PW_CALLBACK_GET_PW_AGAIN_NAME, PW_CALLBACK_GET_PW_AGAIN_SIG); } else { getPWMethod = (*env)->GetMethodID( env, callbackClass, PW_CALLBACK_GET_PW_FIRST_NAME, PW_CALLBACK_GET_PW_FIRST_SIG); } if(getPWMethod == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find password callback accessor method"); ASSERT_OUTOFMEM(env); goto finish; } /***************************************** * Get the password from the callback *****************************************/ pwObject = (*env)->CallObjectMethod( env, callback, getPWMethod, pwcbInfo); if( (*env)->ExceptionOccurred(env) != NULL) { goto finish; } if( pwObject == NULL ) { JSS_throw(env, GIVE_UP_EXCEPTION); goto finish; } /***************************************** * Get Password class and methods *****************************************/ passwordClass = (*env)->GetObjectClass(env, pwObject); if(passwordClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password class"); ASSERT_OUTOFMEM(env); goto finish; } getByteCopyMethod = (*env)->GetMethodID( env, passwordClass, PW_GET_BYTE_COPY_NAME, PW_GET_BYTE_COPY_SIG); clearMethod = (*env)->GetMethodID( env, passwordClass, PW_CLEAR_NAME, PW_CLEAR_SIG); if(getByteCopyMethod==NULL || clearMethod==NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password manipulation methods from native " "implementation"); ASSERT_OUTOFMEM(env); goto finish; } /************************************************ * Get the bytes from the password, then clear it ***********************************************/ pwArray = (*env)->CallObjectMethod( env, pwObject, getByteCopyMethod); (*env)->CallVoidMethod(env, pwObject, clearMethod); exception = (*env)->ExceptionOccurred(env); if(exception == NULL) { PR_ASSERT(pwArray != NULL); /************************************************************* * Copy the characters out of the byte array, * then erase it *************************************************************/ pwchars = (char*) (*env)->GetByteArrayElements(env, pwArray, NULL); PR_ASSERT(pwchars!=NULL); returnchars = PL_strdup(pwchars); JSS_wipeCharArray(pwchars); (*env)->ReleaseByteArrayElements(env, pwArray, (jbyte*)pwchars, 0); } else { returnchars = NULL; } finish: #ifdef DEBUG if( (exception=(*env)->ExceptionOccurred(env)) != NULL) { jclass giveupClass; jmethodID printStackTrace; jclass excepClass; (*env)->ExceptionClear(env); giveupClass = (*env)->FindClass(env, GIVE_UP_EXCEPTION); PR_ASSERT(giveupClass != NULL); if( ! (*env)->IsInstanceOf(env, exception, giveupClass) ) { excepClass = (*env)->GetObjectClass(env, exception); printStackTrace = (*env)->GetMethodID(env, excepClass, "printStackTrace", "()V"); (*env)->CallVoidMethod(env, exception, printStackTrace); PR_ASSERT( PR_FALSE ); } PR_ASSERT(returnchars==NULL); } #else if( ((*env)->ExceptionOccurred(env)) != NULL) { (*env)->ExceptionClear(env); } #endif return returnchars; } /********************************************************************** * * m a k e P W C B I n f o * * Creates a Java PasswordCallbackInfo structure from a PKCS #11 token. * Returns this object, or NULL if an exception was thrown. */ static jobject makePWCBInfo(JNIEnv *env, PK11SlotInfo *slot) { jclass infoClass; jmethodID constructor; jstring name; jobject pwcbInfo=NULL; PR_ASSERT(env!=NULL && slot!=NULL); /***************************************** * Turn the token name into a Java String *****************************************/ name = (*env)->NewStringUTF(env, PK11_GetTokenName(slot)); if(name == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /***************************************** * Look up the class and constructor *****************************************/ infoClass = (*env)->FindClass(env, TOKEN_CBINFO_CLASS_NAME); if(infoClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to find TokenCallbackInfo " "class"); ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, infoClass, TOKEN_CBINFO_CONSTRUCTOR_NAME, TOKEN_CBINFO_CONSTRUCTOR_SIG); if(constructor == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to find " "TokenCallbackInfo constructor"); ASSERT_OUTOFMEM(env); goto finish; } /***************************************** * Create the CallbackInfo object *****************************************/ pwcbInfo = (*env)->NewObject(env, infoClass, constructor, name); if(pwcbInfo == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to create TokenCallbackInfo"); ASSERT_OUTOFMEM(env); } finish: return pwcbInfo; } /********************************************************************** * CryptoManager.putModulesInVector * * Wraps all PKCS #11 modules in PK11Module Java objects, then puts * these into a Vector. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_putModulesInVector (JNIEnv *env, jobject this, jobject vector) { SECMODListLock *listLock=NULL; SECMODModuleList *list; SECMODModule *modp=NULL; jclass vectorClass; jmethodID addElement; jobject module; PR_ASSERT(env!=NULL && this!=NULL && vector!=NULL); /*************************************************** * Get JNI ids ***************************************************/ vectorClass = (*env)->GetObjectClass(env, vector); if(vectorClass == NULL) goto finish; addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement==NULL) goto finish; /*************************************************** * Lock the list ***************************************************/ listLock = SECMOD_GetDefaultModuleListLock(); PR_ASSERT(listLock!=NULL); SECMOD_GetReadLock(listLock); /*************************************************** * Loop over the modules, adding each one to the vector ***************************************************/ for( list = SECMOD_GetDefaultModuleList(); list != NULL; list=list->next) { PR_ASSERT(list->module != NULL); /** Make a PK11Module **/ modp = SECMOD_ReferenceModule(list->module); module = JSS_PK11_wrapPK11Module(env, &modp); PR_ASSERT(modp==NULL); if(module == NULL) { goto finish; } /** Stick the PK11Module in the Vector **/ (*env)->CallVoidMethod(env, vector, addElement, module); } finish: /*** Unlock the list ***/ if(listLock != NULL) { SECMOD_ReleaseReadLock(listLock); } /*** Free this module if it wasn't properly Java-ized ***/ if(modp!=NULL) { SECMOD_DestroyModule(modp); } return; } /********************************************************************** * CryptoManager.enableFIPS * * Enables or disables FIPS mode. * INPUTS * fips * true means turn on FIPS mode, false means turn it off. * RETURNS * true if a switch happened, false if the library was already * in the requested mode. * THROWS * java.security.GeneralSecurityException if an error occurred with * the PKCS #11 library. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_enableFIPS (JNIEnv *env, jclass clazz, jboolean fips) { char *name=NULL; jboolean switched = JNI_FALSE; SECStatus status = SECSuccess; if( ((fips==JNI_TRUE) && !PK11_IsFIPS()) || ((fips==JNI_FALSE) && PK11_IsFIPS()) ) { name = PL_strdup(SECMOD_GetInternalModule()->commonName); status = SECMOD_DeleteInternalModule(name); PR_Free(name); switched = JNI_TRUE; } if(status != SECSuccess) { JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION, "Failed to toggle FIPS mode"); } return switched; } /*********************************************************************** * CryptoManager.FIPSEnabled * * Returns true if FIPS mode is currently on, false if it ain't. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_FIPSEnabled(JNIEnv *env, jobject this) { if( PK11_IsFIPS() ) { return JNI_TRUE; } else { return JNI_FALSE; } } /*********************************************************************** * DatabaseCloser.closeDatabases * * Closes the cert and key database, rendering the security library * unusable. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_DatabaseCloser_closeDatabases (JNIEnv *env, jobject this) { NSS_Shutdown(); } /********************************************************************** * configureOCSPNative * * Allows configuration of the OCSP responder during runtime. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_configureOCSPNative( JNIEnv *env, jobject this, jboolean ocspCheckingEnabled, jstring ocspResponderURL, jstring ocspResponderCertNickname ) { SECStatus rv = SECFailure; rv = ConfigureOCSP(env,ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname); if (rv != SECSuccess) { JSS_throwMsgPrErr(env, GENERAL_SECURITY_EXCEPTION, "Failed to configure OCSP"); } } /********************************************************************** * OCSPCacheSettingsNative * * Allows configuration of the OCSP responder cache during runtime. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_OCSPCacheSettingsNative( JNIEnv *env, jobject this, jint ocsp_cache_size, jint ocsp_min_cache_entry_duration, jint ocsp_max_cache_entry_duration) { SECStatus rv = SECFailure; rv = CERT_OCSPCacheSettings( ocsp_cache_size, ocsp_min_cache_entry_duration, ocsp_max_cache_entry_duration); if (rv != SECSuccess) { JSS_throwMsgPrErr(env, GENERAL_SECURITY_EXCEPTION, "Failed to set OCSP cache: error "+ PORT_GetError()); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_setOCSPTimeoutNative( JNIEnv *env, jobject this, jint ocsp_timeout ) { SECStatus rv = SECFailure; rv = CERT_SetOCSPTimeout(ocsp_timeout); if (rv != SECSuccess) { JSS_throwMsgPrErr(env, GENERAL_SECURITY_EXCEPTION, "Failed to set OCSP timeout: error "+ PORT_GetError()); } } jss-4.4.3/jss/org/mozilla/jss/CryptoManager.java000066400000000000000000002132551326145000000215720ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import org.mozilla.jss.asn1.*; import java.security.cert.CertificateException; import java.security.GeneralSecurityException; import org.mozilla.jss.pkcs11.PK11Cert; import java.util.*; import org.mozilla.jss.pkcs11.KeyType; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.pkcs11.PK11Module; import org.mozilla.jss.pkcs11.PK11SecureRandom; import java.security.cert.CertificateEncodingException; import org.mozilla.jss.CRLImportException; import org.mozilla.jss.provider.java.security.JSSMessageDigestSpi; /** * This class is the starting poing for the crypto package. * Use it to initialize the subsystem and to lookup certs, keys, and tokens. * Initialization is done with static methods, and must be done before * an instance can be created. All other operations are done with instance * methods. * @version $Revision$ $Date$ */ public final class CryptoManager implements TokenSupplier { /** * note: this is obsolete in NSS * CertUsage options for validation */ public final static class CertUsage { private int usage; private String name; static private ArrayList list = new ArrayList(); private CertUsage() {}; private CertUsage(int usage, String name) { this.usage = usage; this.name = name; this.list.add(this); } public int getUsage() { return usage; } static public Iterator getCertUsages() { return list.iterator(); } public String toString() { return name; } // certUsage, these must be kept in sync with nss/lib/certdb/certt.h public static final CertUsage SSLClient = new CertUsage(0, "SSLClient"); public static final CertUsage SSLServer = new CertUsage(1, "SSLServer"); public static final CertUsage SSLServerWithStepUp = new CertUsage(2, "SSLServerWithStepUp"); public static final CertUsage SSLCA = new CertUsage(3, "SSLCA"); public static final CertUsage EmailSigner = new CertUsage(4, "EmailSigner"); public static final CertUsage EmailRecipient = new CertUsage(5, "EmailRecipient"); public static final CertUsage ObjectSigner = new CertUsage(6, "ObjectSigner"); public static final CertUsage UserCertImport = new CertUsage(7, "UserCertImport"); public static final CertUsage VerifyCA = new CertUsage(8, "VerifyCA"); public static final CertUsage ProtectedObjectSigner = new CertUsage(9, "ProtectedObjectSigner"); public static final CertUsage StatusResponder = new CertUsage(10, "StatusResponder"); public static final CertUsage AnyCA = new CertUsage(11, "AnyCA"); } /** * CertificateUsage options for validation */ public final static class CertificateUsage { private int usage; private String name; // certificateUsage, these must be kept in sync with nss/lib/certdb/certt.h private static final int certificateUsageCheckAllUsages = 0x0000; private static final int certificateUsageSSLClient = 0x0001; private static final int certificateUsageSSLServer = 0x0002; private static final int certificateUsageSSLServerWithStepUp = 0x0004; private static final int certificateUsageSSLCA = 0x0008; private static final int certificateUsageEmailSigner = 0x0010; private static final int certificateUsageEmailRecipient = 0x0020; private static final int certificateUsageObjectSigner = 0x0040; private static final int certificateUsageUserCertImport = 0x0080; private static final int certificateUsageVerifyCA = 0x0100; private static final int certificateUsageProtectedObjectSigner = 0x0200; private static final int certificateUsageStatusResponder = 0x0400; private static final int certificateUsageAnyCA = 0x0800; static private ArrayList list = new ArrayList(); private CertificateUsage() {}; private CertificateUsage(int usage, String name) { this.usage = usage; this.name = name; this.list.add(this); } public int getUsage() { return usage; } static public Iterator getCertificateUsages() { return list.iterator(); } public String toString() { return name; } public static final CertificateUsage CheckAllUsages = new CertificateUsage(certificateUsageCheckAllUsages, "CheckAllUsages"); public static final CertificateUsage SSLClient = new CertificateUsage(certificateUsageSSLClient, "SSLClient"); public static final CertificateUsage SSLServer = new CertificateUsage(certificateUsageSSLServer, "SSLServer"); public static final CertificateUsage SSLServerWithStepUp = new CertificateUsage(certificateUsageSSLServerWithStepUp, "SSLServerWithStepUp"); public static final CertificateUsage SSLCA = new CertificateUsage(certificateUsageSSLCA, "SSLCA"); public static final CertificateUsage EmailSigner = new CertificateUsage(certificateUsageEmailSigner, "EmailSigner"); public static final CertificateUsage EmailRecipient = new CertificateUsage(certificateUsageEmailRecipient, "EmailRecipient"); public static final CertificateUsage ObjectSigner = new CertificateUsage(certificateUsageObjectSigner, "ObjectSigner"); public static final CertificateUsage UserCertImport = new CertificateUsage(certificateUsageUserCertImport, "UserCertImport"); public static final CertificateUsage VerifyCA = new CertificateUsage(certificateUsageVerifyCA, "VerifyCA"); public static final CertificateUsage ProtectedObjectSigner = new CertificateUsage(certificateUsageProtectedObjectSigner, "ProtectedObjectSigner"); public static final CertificateUsage StatusResponder = new CertificateUsage(certificateUsageStatusResponder, "StatusResponder"); public static final CertificateUsage AnyCA = new CertificateUsage(certificateUsageAnyCA, "AnyCA"); /* The folllowing usages cannot be verified: certUsageAnyCA certUsageProtectedObjectSigner certUsageUserCertImport certUsageVerifyCA */ public static final int basicCertificateUsages = /*0x0b80;*/ certificateUsageUserCertImport | certificateUsageVerifyCA | certificateUsageProtectedObjectSigner | certificateUsageAnyCA ; } public final static class NotInitializedException extends Exception {} public final static class NicknameConflictException extends Exception {} public final static class UserCertConflictException extends Exception {} public final static class InvalidLengthException extends Exception {} /** * The various options that can be used to initialize CryptoManager. */ public final static class InitializationValues { protected InitializationValues() { Assert.notReached("Default constructor"); } ///////////////////////////////////////////////////////////// // Constants ///////////////////////////////////////////////////////////// /** * Token names must be this length exactly. */ public final int TOKEN_LENGTH = 33; /** * Slot names must be this length exactly. */ public final int SLOT_LENGTH = 65; /** * ManufacturerID must be this length exactly. */ public final int MANUFACTURER_LENGTH = 33; /** * Library description must be this length exactly. */ public final int LIBRARY_LENGTH = 33; /** * This class enumerates the possible modes for FIPS compliance. */ public static final class FIPSMode { private FIPSMode() {} /** * Enable FIPS mode. */ public static final FIPSMode ENABLED = new FIPSMode(); /** * Disable FIPS mode. */ public static final FIPSMode DISABLED = new FIPSMode(); /** * Leave FIPS mode unchanged. All servers except Admin * Server should use this, because only Admin Server should * be altering FIPS mode. */ public static final FIPSMode UNCHANGED = new FIPSMode(); } public InitializationValues(String configDir) { this.configDir = configDir; } public InitializationValues(String configDir, String certPrefix, String keyPrefix, String secmodName) { this.configDir = configDir; this.certPrefix = certPrefix; this.keyPrefix = keyPrefix; this.secmodName = secmodName; } public String configDir = null; public String certPrefix = null; public String keyPrefix = null; public String secmodName = null; /** * The password callback to be used by JSS whenever a password * is needed. May be NULL, in which the library will immediately fail * to get a password if it tries to login automatically while * performing * a cryptographic operation. It will still work if the token * has been manually logged in with CryptoToken.login. *

The default is a ConsolePasswordCallback. */ public PasswordCallback passwordCallback = new ConsolePasswordCallback(); /** * The FIPS mode of the security library. Servers should * use FIPSMode.UNCHANGED, since only * Admin Server is supposed to alter this value. *

The default is FIPSMode.UNCHANGED. */ public FIPSMode fipsMode = FIPSMode.UNCHANGED; /** * To open the databases in read-only mode, set this flag to * true. The default is false, meaning * the databases are opened in read-write mode. */ public boolean readOnly = false; //////////////////////////////////////////////////////////////////// // Manufacturer ID //////////////////////////////////////////////////////////////////// /** * Returns the Manufacturer ID of the internal PKCS #11 module. *

The default is "mozilla.org ". */ public String getManufacturerID() { return manufacturerID; } /** * Sets the Manufacturer ID of the internal PKCS #11 module. * This value must be exactly MANUFACTURER_LENGTH * characters long. * @exception InvalidLengthException If s.length() is not * exactly MANUFACTURER_LENGTH. */ public void setManufacturerID(String s) throws InvalidLengthException { if( s.length() != MANUFACTURER_LENGTH ) { throw new InvalidLengthException(); } manufacturerID = s; } private String manufacturerID = "mozilla.org "; //////////////////////////////////////////////////////////////////// // Library Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 module. *

The default is "Internal Crypto Services ". */ public String getLibraryDescription() { return libraryDescription; } /** * Sets the description of the internal PKCS #11 module. * This value must be exactly LIBRARY_LENGTH * characters long. * @exception InvalidLengthException If s.length() is * not exactly LIBRARY_LENGTH. */ public void setLibraryDescription(String s) throws InvalidLengthException { if( s.length() != LIBRARY_LENGTH ) { throw new InvalidLengthException(); } libraryDescription = s; } private String libraryDescription = "Internal Crypto Services "; //////////////////////////////////////////////////////////////////// // Internal Token Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 token. *

The default is "Internal Crypto Services Token ". */ public String getInternalTokenDescription() { return internalTokenDescription; } /** * Sets the description of the internal PKCS #11 token. * This value must be exactly TOKEN_LENGTH characters long. * @exception InvalidLengthException If s.length() is * not exactly TOKEN_LENGTH. */ public void setInternalTokenDescription(String s) throws InvalidLengthException { if(s.length() != TOKEN_LENGTH) { throw new InvalidLengthException(); } internalTokenDescription = s; } private String internalTokenDescription = "NSS Generic Crypto Services "; //////////////////////////////////////////////////////////////////// // Internal Key Storage Token Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 key storage token. *

The default is "Internal Key Storage Token ". */ public String getInternalKeyStorageTokenDescription() { return internalKeyStorageTokenDescription; } /** * Sets the description of the internal PKCS #11 key storage token. * This value must be exactly TOKEN_LENGTH characters long. * @exception InvalidLengthException If s.length() is * not exactly TOKEN_LENGTH. */ public void setInternalKeyStorageTokenDescription(String s) throws InvalidLengthException { if(s.length() != TOKEN_LENGTH) { throw new InvalidLengthException(); } internalKeyStorageTokenDescription = s; } private String internalKeyStorageTokenDescription = "Internal Key Storage Token "; //////////////////////////////////////////////////////////////////// // Internal Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 slot. *

The default is "NSS Internal Cryptographic Services ". */ public String getInternalSlotDescription() { return internalSlotDescription; } /** * Sets the description of the internal PKCS #11 slot. * This value must be exactly SLOT_LENGTH characters * long. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setInternalSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } internalSlotDescription = s; } private String internalSlotDescription = "NSS Internal Cryptographic Services "; //////////////////////////////////////////////////////////////////// // Internal Key Storage Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 key storage slot. *

The default is "NSS Internal Private Key and Certificate Storage ". */ public String getInternalKeyStorageSlotDescription() { return internalKeyStorageSlotDescription; } /** * Sets the description of the internal PKCS #11 key storage slot. * This value must be exactly SLOT_LENGTH characters * long. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setInternalKeyStorageSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } internalKeyStorageSlotDescription = s; } private String internalKeyStorageSlotDescription = "NSS User Private Key and Certificate Services "; //////////////////////////////////////////////////////////////////// // FIPS Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 FIPS slot. *

The default is * "NSS FIPS 140-2 User Private Key Services". */ public String getFIPSSlotDescription() { return FIPSSlotDescription; } /** * Sets the description of the internal PKCS #11 FIPS slot. * This value must be exactly SLOT_LENGTH characters * long. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setFIPSSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } FIPSSlotDescription = s; } private String FIPSSlotDescription = "NSS FIPS 140-2 User Private Key Services "; //////////////////////////////////////////////////////////////////// // FIPS Key Storage Slot Description //////////////////////////////////////////////////////////////////// /** * Returns the description of the internal PKCS #11 FIPS * Key Storage slot. *

The default is * "NSS FIPS 140-2 User Private Key Services". */ public String getFIPSKeyStorageSlotDescription() { return FIPSKeyStorageSlotDescription; } /** * Sets the description of the internal PKCS #11 FIPS Key Storage slot. * This value must be exactly SLOT_LENGTH characters * long. * @exception InvalidLengthException If s.length() is * not exactly SLOT_LENGTH. */ public void setFIPSKeyStorageSlotDescription(String s) throws InvalidLengthException { if(s.length() != SLOT_LENGTH) { throw new InvalidLengthException(); } FIPSKeyStorageSlotDescription = s; } private String FIPSKeyStorageSlotDescription = "NSS FIPS 140-2 User Private Key Services "; /** * To have NSS check the OCSP responder for when verifying * certificates, set this flags to true. It is false by * default. */ public boolean ocspCheckingEnabled = false; /** * Specify the location and cert of the responder. * If OCSP checking is enabled *and* this variable is * set to some URL, all OCSP checking will be done via * this URL. * * If this variable is null, the OCSP responder URL will * be obtained from the AIA extension in the certificate * being queried. * * If this is set, you must also set ocspResponderCertNickname * */ public String ocspResponderURL = null; /** * The nickname of the cert to trust (expected) to * sign the OCSP responses. * Only checked when the OCSPResponder value is set. */ public String ocspResponderCertNickname = null; /** * Install the JSS crypto provider. Default is true. */ public boolean installJSSProvider = true; /** * Remove the Sun crypto provider. Default is false. */ public boolean removeSunProvider = false; /** * If true, none of the underlying NSS components will * be initialized. Only the Java portions of JSS will be * initialized. This should only be used if NSS has been initialized * elsewhere. * *

Specifically, the following components will not be * configured by CryptoManager.initialize if this flag is set: *

    *
  • The NSS databases. *
  • OCSP checking. *
  • The NSS password callback. *
  • The internal PKCS #11 software token's identifier labels: * slot, token, module, and manufacturer. *
  • The minimum PIN length for the software token. *
  • The frequency with which the user must login to the software * token. *
  • The cipher strength policy (export/domestic). *
* *

The default is false. */ public boolean initializeJavaOnly = false; /** * Enable PKIX verify rather than the old cert library, * to verify certificates. Default is false. */ public boolean PKIXVerify = false; /** * Don't open the cert DB and key DB's, just * initialize the volatile certdb. Default is false. */ public boolean noCertDB = false; /** * Don't open the security module DB, * just initialize the PKCS #11 module. * Default is false. */ public boolean noModDB = false; /** * Continue to force initializations even if the * databases cannot be opened. * Default is false. */ public boolean forceOpen = false; /** * Don't try to look for the root certs module * automatically. * Default is false. */ public boolean noRootInit = false; /** * Use smaller tables and caches. * Default is false. */ public boolean optimizeSpace = false; /** * only load PKCS#11 modules that are * thread-safe, ie. that support locking - either OS * locking or NSS-provided locks . If a PKCS#11 * module isn't thread-safe, don't serialize its * calls; just don't load it instead. This is necessary * if another piece of code is using the same PKCS#11 * modules that NSS is accessing without going through * NSS, for example the Java SunPKCS11 provider. * Default is false. */ public boolean PK11ThreadSafe = false; /** * Init PK11Reload to ignore the CKR_CRYPTOKI_ALREADY_INITIALIZED * error when loading PKCS#11 modules. This is necessary * if another piece of code is using the same PKCS#11 * modules that NSS is accessing without going through * NSS, for example Java SunPKCS11 provider. * default is false. */ public boolean PK11Reload = false; /** * never call C_Finalize on any * PKCS#11 module. This may be necessary in order to * ensure continuous operation and proper shutdown * sequence if another piece of code is using the same * PKCS#11 modules that NSS is accessing without going * through NSS, for example Java SunPKCS11 provider. * The following limitation applies when this is set : * SECMOD_WaitForAnyTokenEvent will not use * C_WaitForSlotEvent, in order to prevent the need for * C_Finalize. This call will be emulated instead. * Default is false. */ public boolean noPK11Finalize = false; /** * Sets 4 recommended options for applications that * use both NSS and the Java SunPKCS11 provider. * Default is false. */ public boolean cooperate = false; } //////////////////////////////////////////////////// // Module and Token Management //////////////////////////////////////////////////// /** * Retrieves the internal cryptographic services token. This is the * token built into NSS that performs bulk * cryptographic operations. *

In FIPS mode, the internal cryptographic services token is the * same as the internal key storage token. * * @return The internal cryptographic services token. */ public synchronized CryptoToken getInternalCryptoToken() { return internalCryptoToken; } /** * Retrieves the internal key storage token. This is the token * provided by NSS to store private keys. * The keys stored in this token are stored in an encrypted key database. *

In FIPS mode, the internal key storage token is the same as * the internal cryptographic services token. * * @return The internal key storage token. */ public synchronized CryptoToken getInternalKeyStorageToken() { return internalKeyStorageToken; } /** * Looks up the CryptoToken with the given name. Searches all * loaded cryptographic modules for the token. * * @param name The name of the token. * @exception org.mozilla.jss.NoSuchTokenException If no token * is found with the given name. */ public synchronized CryptoToken getTokenByName(String name) throws NoSuchTokenException { Enumeration tokens = getAllTokens(); CryptoToken token; while(tokens.hasMoreElements()) { token = (CryptoToken) tokens.nextElement(); try { if( name.equals(token.getName()) ) { return token; } } catch( TokenException e ) { Assert._assert(false, "Got a token exception"); } } throw new NoSuchTokenException(); } /** * Retrieves all tokens that support the given algorithm. * */ public synchronized Enumeration getTokensSupportingAlgorithm(Algorithm alg) { Enumeration tokens = getAllTokens(); Vector goodTokens = new Vector(); CryptoToken tok; while(tokens.hasMoreElements()) { tok = (CryptoToken) tokens.nextElement(); if( tok.doesAlgorithm(alg) ) { goodTokens.addElement(tok); } } return goodTokens.elements(); } /** * Retrieves all tokens. This is an enumeration of all tokens on all * modules. * * @return All tokens accessible from JSS. Each item of the enumeration * is a CryptoToken * @see org.mozilla.jss.crypto.CryptoToken */ public synchronized Enumeration getAllTokens() { Enumeration modules = getModules(); Enumeration tokens; Vector allTokens = new Vector(); while(modules.hasMoreElements()) { tokens = ((PK11Module)modules.nextElement()).getTokens(); while(tokens.hasMoreElements()) { allTokens.addElement( tokens.nextElement() ); } } return allTokens.elements(); } /** * Retrieves all tokens except those built into NSS. * This excludes the internal token and the internal * key storage token (which are one and the same in FIPS mode). * * @return All tokens accessible from JSS, except for the built-in * internal tokens. */ public synchronized Enumeration getExternalTokens() { Enumeration modules = getModules(); Enumeration tokens; PK11Token token; Vector allTokens = new Vector(); while(modules.hasMoreElements()) { tokens = ((PK11Module)modules.nextElement()).getTokens(); while(tokens.hasMoreElements()) { token = (PK11Token) tokens.nextElement(); if( ! token.isInternalCryptoToken() && ! token.isInternalKeyStorageToken() ) { allTokens.addElement( token ); } } } return allTokens.elements(); } /** * Retrieves all installed cryptographic modules. * * @return An enumeration of all installed PKCS #11 modules. Each * item in the enumeration is a PK11Module. * @see org.mozilla.jss.pkcs11.PK11Module */ public synchronized Enumeration getModules() { return moduleVector.elements(); } // Need to reload modules after adding new one //public native addModule(String name, String libraryName); /** * The list of modules. This should be initialized by the constructor * and updated whenever 1) a new module is added, 2) a module is deleted, * or 3) FIPS mode is switched. */ private Vector moduleVector; /** * Re-creates the Vector of modules that is stored by CryptoManager. * This entails going into native code to enumerate all modules, * wrap each one in a PK11Module, and storing the PK11Module in the vector. */ private synchronized void reloadModules() { moduleVector = new Vector(); putModulesInVector(moduleVector); // Get the internal tokens Enumeration tokens = getAllTokens(); internalCryptoToken = null; internalKeyStorageToken = null; while(tokens.hasMoreElements()) { PK11Token token = (PK11Token) tokens.nextElement(); if( token.isInternalCryptoToken() ) { Assert._assert(internalCryptoToken == null); internalCryptoToken = token; } if( token.isInternalKeyStorageToken() ) { Assert._assert(internalKeyStorageToken == null); internalKeyStorageToken = token; } } Assert._assert(internalKeyStorageToken != null); Assert._assert(internalCryptoToken != null); } /** * The internal cryptographic services token. */ private CryptoToken internalCryptoToken; /** * The internal key storage token. */ private CryptoToken internalKeyStorageToken; /** * Native code to traverse all PKCS #11 modules, wrap each one in * a PK11Module, and insert each PK11Module into the given vector. */ private native void putModulesInVector(Vector vector); /////////////////////////////////////////////////////////////////////// // Constructor and Accessors /////////////////////////////////////////////////////////////////////// /** * Constructor, for internal use only. */ protected CryptoManager() { TokenSupplierManager.setTokenSupplier(this); reloadModules(); } /** * Retrieve the single instance of CryptoManager. * This cannot be called before initialization. * * @see #initialize(CryptoManager.InitializationValues) * @exception NotInitializedException If * initialize(InitializationValues has not yet been * called. */ public synchronized static CryptoManager getInstance() throws NotInitializedException { if(instance==null) { throw new NotInitializedException(); } return instance; } /** * The singleton instance, and a static initializer to create it. */ private static CryptoManager instance=null; /////////////////////////////////////////////////////////////////////// // FIPS management /////////////////////////////////////////////////////////////////////// /** * Enables or disables FIPS-140-2 compliant mode. If this returns true, * you must reloadModules(). This should only be called once in a program, * at the beginning, because it invalidates tokens and modules. * * @param fips true to turn FIPS compliant mode on, false to turn it off. */ private static native boolean enableFIPS(boolean fips) throws GeneralSecurityException; /** * Determines whether FIPS-140-2 compliance is active. * * @return true if the security library is in FIPS-140-2 compliant mode. */ public synchronized native boolean FIPSEnabled(); /////////////////////////////////////////////////////////////////////// // Password Callback management /////////////////////////////////////////////////////////////////////// /** * This function sets the global password callback. It is * not thread-safe to change this. *

The callback may be NULL, in which case password callbacks will * fail gracefully. */ public synchronized void setPasswordCallback(PasswordCallback pwcb) { passwordCallback = pwcb; setNativePasswordCallback( pwcb ); } private native void setNativePasswordCallback(PasswordCallback cb); /** * Returns the currently registered password callback. */ public synchronized PasswordCallback getPasswordCallback() { return passwordCallback; } private PasswordCallback passwordCallback; //////////////////////////////////////////////////// // Initialization //////////////////////////////////////////////////// /** * Initialize the security subsystem. Opens the databases, loads all * PKCS #11 modules, initializes the internal random number generator. * The initialize methods that take arguments should be * called only once, otherwise they will throw * an exception. It is OK to call them after calling * initialize(). * * @param configDir The directory containing the security databases. * @exception org.mozilla.jss.KeyDatabaseException Unable to open * the key database, or it was currupted. * @exception org.mozilla.jss.CertDatabaseException Unable * to open the certificate database, or it was currupted. **/ public static synchronized void initialize( String configDir ) throws KeyDatabaseException, CertDatabaseException, AlreadyInitializedException, GeneralSecurityException { initialize( new InitializationValues(configDir) ); } /** * Initialize the security subsystem. Opens the databases, loads all * PKCS #11 modules, initializes the internal random number generator. * The initialize methods that take arguments should be * called only once, otherwise they will throw * an exception. It is OK to call them after calling * initialize(). * * @param values The options with which to initialize CryptoManager. * @exception org.mozilla.jss.KeyDatabaseException Unable to open * the key database, or it was corrupted. * @exception org.mozilla.jss.CertDatabaseException Unable * to open the certificate database, or it was currupted. **/ public static synchronized void initialize( InitializationValues values ) throws KeyDatabaseException, CertDatabaseException, AlreadyInitializedException, GeneralSecurityException { if(instance != null) { throw new AlreadyInitializedException(); } loadNativeLibraries(); if (values.ocspResponderURL != null) { if (values.ocspResponderCertNickname == null) { throw new GeneralSecurityException( "Must set ocspResponderCertNickname"); } } initializeAllNative2(values.configDir, values.certPrefix, values.keyPrefix, values.secmodName, values.readOnly, values.getManufacturerID(), values.getLibraryDescription(), values.getInternalTokenDescription(), values.getInternalKeyStorageTokenDescription(), values.getInternalSlotDescription(), values.getInternalKeyStorageSlotDescription(), values.getFIPSSlotDescription(), values.getFIPSKeyStorageSlotDescription(), values.ocspCheckingEnabled, values.ocspResponderURL, values.ocspResponderCertNickname, values.initializeJavaOnly, values.PKIXVerify, values.noCertDB, values.noModDB, values.forceOpen, values.noRootInit, values.optimizeSpace, values.PK11ThreadSafe, values.PK11Reload, values.noPK11Finalize, values.cooperate ); instance = new CryptoManager(); instance.setPasswordCallback(values.passwordCallback); if( values.fipsMode != InitializationValues.FIPSMode.UNCHANGED) { if( enableFIPS(values.fipsMode == InitializationValues.FIPSMode.ENABLED) ) { instance.reloadModules(); } } // Force class load before we install the provider. Otherwise we get // an infinite loop as the Security manager tries to instantiate the // digest to verify its own JAR file. JSSMessageDigestSpi mds = new JSSMessageDigestSpi.SHA1(); // Force the KeyType class to load before we can install JSS as a // provider. JSS's signature provider accesses KeyType. KeyType kt = KeyType.getKeyTypeFromAlgorithm( SignatureAlgorithm.RSASignatureWithSHA1Digest); if( values.installJSSProvider ) { int position = java.security.Security.insertProviderAt( new JSSProvider(), 1); // This returns -1 if the provider was already installed, in which // case it is not installed again. Is this // an error? I don't think so, although it might be confusing // if the provider is not in the position they expected. // However, this will only happen if they are installing the // provider themselves, so presumably they know what they're // doing. } if( values.removeSunProvider ) { java.security.Security.removeProvider("SUN"); } } private static native void initializeAllNative2(String configDir, String certPrefix, String keyPrefix, String secmodName, boolean readOnly, String manufacturerID, String libraryDescription, String internalTokenDescription, String internalKeyStorageTokenDescription, String internalSlotDescription, String internalKeyStorageSlotDescription, String fipsSlotDescription, String fipsKeyStorageSlotDescription, boolean ocspCheckingEnabled, String ocspResponderURL, String ocspResponderCertNickname, boolean initializeJavaOnly, boolean PKIXVerify, boolean noCertDB, boolean noModDB, boolean forceOpen, boolean noRootInit, boolean optimizeSpace, boolean PK11ThreadSafe, boolean PK11Reload, boolean noPK11Finalize, boolean cooperate) throws KeyDatabaseException, CertDatabaseException, AlreadyInitializedException; ///////////////////////////////////////////////////////////// // Cert Lookup ///////////////////////////////////////////////////////////// /** * Retrieves all CA certificates in the trust database. This * is a fairly expensive operation in that it involves traversing * the entire certificate database. * @return An array of all CA certificates stored permanently * in the trust database. */ public native X509Certificate[] getCACerts(); /** * Retrieves all certificates in the trust database. This * is a fairly expensive operation in that it involves traversing * the entire certificate database. * @return An array of all certificates stored permanently * in the trust database. */ public native X509Certificate[] getPermCerts(); /** * Imports a chain of certificates. The leaf certificate may be a * a user certificate, that is, a certificate that belongs to the * current user and whose private key is available for use. * If the leaf certificate is a user certificate, it is stored * on the token * that contains the corresponding private key, and is assigned the * given nickname. * * @param certPackage An encoded certificate or certificate chain. * Acceptable * encodings are binary PKCS #7 SignedData objects and * DER-encoded certificates, which may or may not be wrapped * in a Base-64 encoding package surrounded by * "-----BEGIN CERTIFICATE-----" and * "-----END CERTIFICATE-----". * @param nickname The nickname for the user certificate. It must * be unique. It is ignored if there is no user certificate. * @return The leaf certificate from the chain. * @exception CertificateEncodingException If the package encoding * was not recognized. * @exception NicknameConflictException If the leaf certificate * is a user certificate, and another certificate already has the * given nickname. * @exception UserCertConflictException If the leaf certificate * is a user certificate, but it has already been imported. * @exception NoSuchItemOnTokenException If the leaf certificate is * a user certificate, but the matching private key cannot be found. * @exception TokenException If an error occurs importing a leaf * certificate into a token. */ public X509Certificate importCertPackage(byte[] certPackage, String nickname ) throws CertificateEncodingException, NicknameConflictException, UserCertConflictException, NoSuchItemOnTokenException, TokenException { return importCertPackageNative(certPackage, nickname, false, false); } /** * Imports a chain of certificates. The leaf of the chain is a CA * certificate AND a user certificate (this would only be called by * a CA installing its own certificate). * * @param certPackage An encoded certificate or certificate chain. * Acceptable * encodings are binary PKCS #7 SignedData objects and * DER-encoded certificates, which may or may not be wrapped * in a Base-64 encoding package surrounded by * "-----BEGIN CERTIFICATE-----" and * "-----END CERTIFICATE-----". * @param nickname The nickname for the user certificate. It must * be unique. * @return The leaf certificate from the chain. * @exception CertificateEncodingException If the package encoding * was not recognized. * @exception NicknameConflictException If the leaf certificate * another certificate already has the given nickname. * @exception UserCertConflictException If the leaf certificate * has already been imported. * @exception NoSuchItemOnTokenException If the the private key matching * the leaf certificate cannot be found. * @exception TokenException If an error occurs importing the leaf * certificate into a token. */ public X509Certificate importUserCACertPackage(byte[] certPackage, String nickname) throws CertificateEncodingException, NicknameConflictException, UserCertConflictException, NoSuchItemOnTokenException, TokenException { return importCertPackageNative(certPackage, nickname, false, true); } /** * Imports a chain of certificates, none of which is a user certificate. * * @param certPackage An encoded certificate or certificate chain. * Acceptable * encodings are binary PKCS #7 SignedData objects and * DER-encoded certificates, which may or may not be wrapped * in a Base-64 encoding package surrounded by * "-----BEGIN CERTIFICATE-----" and * "-----END CERTIFICATE-----". * @return The leaf certificate from the chain. * @exception CertificateEncodingException If the package encoding * was not recognized. * @exception TokenException If an error occurs importing a leaf * certificate into a token. */ public X509Certificate importCACertPackage(byte[] certPackage) throws CertificateEncodingException, TokenException { try { return importCertPackageNative(certPackage, null, true, false); } catch(NicknameConflictException e) { Assert.notReached("importing CA certs caused nickname conflict"); Debug.trace(Debug.ERROR, "importing CA certs caused nickname conflict"); } catch(UserCertConflictException e) { Assert.notReached("importing CA certs caused user cert conflict"); Debug.trace(Debug.ERROR, "importing CA certs caused user cert conflict"); } catch(NoSuchItemOnTokenException e) { Assert.notReached("importing CA certs caused NoSuchItemOnToken"+ "Exception"); Debug.trace(Debug.ERROR, "importing CA certs caused NoSuchItemOnTokenException"); } return null; } /** * Imports a single certificate into the permanent certificate * database. * * @param cert the certificate you want to add * @param nickname the nickname you want to refer to the certificate as * (must not be null) */ public InternalCertificate importCertToPerm(X509Certificate cert, String nickname) throws TokenException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } else { return importCertToPermNative(cert,nickname); } } private native InternalCertificate importCertToPermNative(X509Certificate cert, String nickname) throws TokenException; /** * @param noUser true if we know that none of the certs are user certs. * In this case, no attempt will be made to find a matching private * key for the leaf certificate. */ private native X509Certificate importCertPackageNative(byte[] certPackage, String nickname, boolean noUser, boolean leafIsCA) throws CertificateEncodingException, NicknameConflictException, UserCertConflictException, NoSuchItemOnTokenException, TokenException; /*============ CRL importing stuff ********************************/ private static int TYPE_KRL = 0; private static int TYPE_CRL = 1; /** * Imports a CRL, and stores it into the cert7.db * Validate CRL then import it to the dbase. If there is already a CRL with the * same CA in the dbase, it will be replaced if derCRL is more up to date. * * @param crl the DER-encoded CRL. * @param url the URL where this CRL can be retrieved from (for future updates). * [ note that CRLs are not retrieved automatically ]. Can be null * @exception CRLImportException If the package encoding * was not recognized. */ public void importCRL(byte[] crl,String url) throws CRLImportException, TokenException { importCRLNative(crl,url,TYPE_CRL); } /** * Imports a CRL, and stores it into the cert7.db * * @param the DER-encoded CRL. */ private native void importCRLNative(byte[] crl, String url, int rl_type) throws CRLImportException, TokenException; /*============ Cert Exporting stuff ********************************/ /** * Exports one or more certificates into a PKCS #7 certificate container. * This is just a SignedData object whose certificates * field contains the given certificates but whose content field * is empty. * * @param certs One or more certificates that should be exported into * the PKCS #7 object. The leaf certificate should be the first * in the chain. The output of buildCertificateChain * would be appropriate here. * @exception CertificateEncodingException If the array is empty, * or an error occurred encoding the certificates. * @return A byte array containing a PKCS #7 SignedData object. * @see #buildCertificateChain */ public native byte[] exportCertsToPKCS7(X509Certificate[] certs) throws CertificateEncodingException; /** * Looks up a certificate given its nickname. * * @param nickname The nickname of the certificate to look for. * @return The certificate matching this nickname, if one is found. * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.X509Certificate findCertByNickname(String nickname) throws ObjectNotFoundException, TokenException { Assert._assert(nickname!=null); return findCertByNicknameNative(nickname); } /** * Returns all certificates with the given nickname. * * @param nickname The nickname of the certificate to look for. * @return The certificates matching this nickname. The array may be empty * if no matching certs were found. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.X509Certificate[] findCertsByNickname(String nickname) throws TokenException { Assert._assert(nickname!=null); return findCertsByNicknameNative(nickname); } /** * Looks up a certificate by issuer and serial number. The internal * database and all PKCS #11 modules are searched. * * @param derIssuer The DER encoding of the certificate issuer name. * The issuer name has ASN.1 type Name, which is defined in * X.501. * @param serialNumber The certificate serial number. * @exception ObjectNotFoundException If the certificate is not found * in the internal certificate database or on any PKCS #11 token. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.X509Certificate findCertByIssuerAndSerialNumber(byte[] derIssuer, INTEGER serialNumber) throws ObjectNotFoundException, TokenException { try { ANY sn = (ANY) ASN1Util.decode(ANY.getTemplate(), ASN1Util.encode(serialNumber) ); return findCertByIssuerAndSerialNumberNative(derIssuer, sn.getContents() ); } catch( InvalidBERException e ) { Assert.notReached("Invalid BER encoding of INTEGER"); return null; } } /** * @param serialNumber The contents octets of a DER-encoding of the * certificate serial number. */ private native org.mozilla.jss.crypto.X509Certificate findCertByIssuerAndSerialNumberNative(byte[] derIssuer, byte[] serialNumber) throws ObjectNotFoundException, TokenException; protected native org.mozilla.jss.crypto.X509Certificate findCertByNicknameNative(String nickname) throws ObjectNotFoundException, TokenException; protected native org.mozilla.jss.crypto.X509Certificate[] findCertsByNicknameNative(String nickname) throws TokenException; ///////////////////////////////////////////////////////////// // build cert chains ///////////////////////////////////////////////////////////// /** * Given a certificate, constructs its certificate chain. It may * or may not chain up to a trusted root. * @param leaf The certificate that is the starting point of the chain. * @return An array of certificates, starting at the leaf and ending * with the highest certificate on the chain that was found. * @throws CertificateException If the certificate is not recognized * by the underlying provider. */ public org.mozilla.jss.crypto.X509Certificate[] buildCertificateChain(org.mozilla.jss.crypto.X509Certificate leaf) throws java.security.cert.CertificateException, TokenException { if( ! (leaf instanceof PK11Cert) ) { throw new CertificateException( "Certificate is not a PKCS #11 certificate"); } return buildCertificateChainNative((PK11Cert)leaf); } native org.mozilla.jss.crypto.X509Certificate[] buildCertificateChainNative(PK11Cert leaf) throws CertificateException, TokenException; ///////////////////////////////////////////////////////////// // lookup private keys ///////////////////////////////////////////////////////////// /** * Looks up the PrivateKey matching the given certificate. * * @exception ObjectNotFoundException If no private key can be * found matching the given certificate. * @exception TokenException If an error occurs in the security library. */ public org.mozilla.jss.crypto.PrivateKey findPrivKeyByCert(org.mozilla.jss.crypto.X509Certificate cert) throws ObjectNotFoundException, TokenException { Assert._assert(cert!=null); if(! (cert instanceof org.mozilla.jss.pkcs11.PK11Cert)) { Assert.notReached("non-pkcs11 cert passed to PK11Finder"); throw new ObjectNotFoundException(); } return findPrivKeyByCertNative(cert); } protected native org.mozilla.jss.crypto.PrivateKey findPrivKeyByCertNative(org.mozilla.jss.crypto.X509Certificate cert) throws ObjectNotFoundException, TokenException; ///////////////////////////////////////////////////////////// // Provide Pseudo-Random Number Generation ///////////////////////////////////////////////////////////// /** * Retrieves a FIPS-140-2 validated random number generator. * * @return A JSS SecureRandom implemented with FIPS-validated NSS. */ public org.mozilla.jss.crypto.JSSSecureRandom createPseudoRandomNumberGenerator() { return new PK11SecureRandom(); } /** * Retrieves a FIPS-140-2 validated random number generator. * * @return A JSS SecureRandom implemented with FIPS-validated NSS. */ public org.mozilla.jss.crypto.JSSSecureRandom getSecureRNG() { return new PK11SecureRandom(); } /********************************************************************/ /* The VERSION Strings should be updated in the following */ /* files everytime a new release of JSS is generated: */ /* */ /* lib/manifest.mn */ /* org/mozilla/jss/CryptoManager.c */ /* org/mozilla/jss/CryptoManager.java */ /* org/mozilla/jss/JSSProvider.java */ /* org/mozilla/jss/util/jssver.h */ /* */ /********************************************************************/ public static final String JAR_JSS_VERSION = "JSS_VERSION = JSS_4_4_0_RTM"; public static final String JAR_JDK_VERSION = "JDK_VERSION = N/A"; public static final String JAR_NSS_VERSION = "NSS_VERSION = N/A"; public static final String JAR_DBM_VERSION = "DBM_VERSION = N/A"; public static final String JAR_NSPR_VERSION = "NSPR_VERSION = N/A"; /** * Loads the JSS dynamic library if necessary. *

This method is idempotent. */ synchronized static void loadNativeLibraries() { if( ! mNativeLibrariesLoaded ) { try { // 64 bit rhel/fedora System.load( "/usr/lib64/jss/libjss4.so" ); Debug.trace(Debug.VERBOSE, "64-bit jss library loaded"); mNativeLibrariesLoaded = true; } catch( UnsatisfiedLinkError e ) { try { // 32 bit rhel/fedora System.load( "/usr/lib/jss/libjss4.so" ); Debug.trace(Debug.VERBOSE, "32-bit jss library loaded"); mNativeLibrariesLoaded = true; } catch( UnsatisfiedLinkError f ) { try {// possibly other platforms System.loadLibrary( "jss4" ); Debug.trace(Debug.VERBOSE, "jss library loaded"); mNativeLibrariesLoaded = true; } catch( UnsatisfiedLinkError g ) { Debug.trace(Debug.VERBOSE, "jss library load failed"); } } } } } static private boolean mNativeLibrariesLoaded = false; // Hashtable is synchronized. private Hashtable perThreadTokenTable = new Hashtable(); /** * Sets the default token for the current thread. This token will * be used when JSS is called through the JCA interface, which has * no means of specifying which token to use. * *

If no token is set, the InternalKeyStorageToken will be used. Setting * this thread's token to null will also cause the * InternalKeyStorageToken to be used. * * @param token The token to use for crypto operations. Specifying * null will cause the InternalKeyStorageToken to be used. */ public void setThreadToken(CryptoToken token) { if( token != null ) { perThreadTokenTable.put(Thread.currentThread(), token); } else { perThreadTokenTable.remove(Thread.currentThread()); } } /** * Returns the default token for the current thread. This token will * be used when JSS is called through the JCA interface, which has * no means of specifying which token to use. * *

If no token is set, the InternalKeyStorageToken will be used. Setting * this thread's token to null will also cause the * InternalKeyStorageToken to be used. * * @return The default token for this thread. If it has not been specified, * it will be the InternalKeyStorageToken. */ public CryptoToken getThreadToken() { CryptoToken tok = (CryptoToken) perThreadTokenTable.get(Thread.currentThread()); if( tok == null ) { tok = getInternalKeyStorageToken(); } return tok; } ///////////////////////////////////////////////////////////// // isCertValid ///////////////////////////////////////////////////////////// /** * Verify a certificate that exists in the given cert database, * check if is valid and that we trust the issuer. Verify time * against Now. * @param nickname The nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @return currCertificateUsage which contains current usage bit map as defined in CertificateUsage * * @exception InvalidNicknameException If the nickname is null * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. */ public int isCertValid(String nickname, boolean checkSig) throws ObjectNotFoundException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } int currCertificateUsage = 0x0000; // initialize it to 0 currCertificateUsage = verifyCertificateNowCUNative(nickname, checkSig); return currCertificateUsage; } private native int verifyCertificateNowCUNative(String nickname, boolean checkSig) throws ObjectNotFoundException; ///////////////////////////////////////////////////////////// // isCertValid ///////////////////////////////////////////////////////////// /** * Verify a certificate that exists in the given cert database, * check if is valid and that we trust the issuer. Verify time * against Now. * @param nickname The nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certificateUsage see certificateUsage defined to verify Certificate; to retrieve current certificate usage, call the isCertValid() above * @return true for success; false otherwise * * @exception InvalidNicknameException If the nickname is null * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @deprecated Use verifyCertificate() instead */ public boolean isCertValid(String nickname, boolean checkSig, CertificateUsage certificateUsage) throws ObjectNotFoundException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } // 0 certificate usage will get current usage // should call isCertValid() call above that returns certificate usage if ((certificateUsage == null) || (certificateUsage == CertificateUsage.CheckAllUsages)){ int currCertificateUsage = 0x0000; currCertificateUsage = verifyCertificateNowCUNative(nickname, checkSig); if (currCertificateUsage == CertificateUsage.basicCertificateUsages){ // cert is good for nothing return false; } else return true; } else { return verifyCertificateNowNative(nickname, checkSig, certificateUsage.getUsage()); } } /** * Verify a certificate that exists in the given cert database, * check if it's valid and that we trust the issuer. Verify time * against now. * @param nickname nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certificateUsage see certificate usage defined to verify certificate * * @exception InvalidNicknameException If the nickname is null. * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @exception CertificateException If certificate is invalid. */ public void verifyCertificate(String nickname, boolean checkSig, CertificateUsage certificateUsage) throws ObjectNotFoundException, InvalidNicknameException, CertificateException { int usage = certificateUsage == null ? 0 : certificateUsage.getUsage(); verifyCertificateNowNative2(nickname, checkSig, usage); } private native boolean verifyCertificateNowNative(String nickname, boolean checkSig, int certificateUsage) throws ObjectNotFoundException; private native void verifyCertificateNowNative2( String nickname, boolean checkSig, int certificateUsage) throws ObjectNotFoundException, InvalidNicknameException, CertificateException; /** * note: this method calls obsolete function in NSS * * Verify a certificate that exists in the given cert database, * check if is valid and that we trust the issuer. Verify time * against Now. * @param nickname The nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certUsage see exposed certUsage defines to verify Certificate * @return true for success; false otherwise * * @exception InvalidNicknameException If the nickname is null * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. */ public boolean isCertValid(String nickname, boolean checkSig, CertUsage certUsage) throws ObjectNotFoundException, InvalidNicknameException { if (nickname==null) { throw new InvalidNicknameException("Nickname must be non-null"); } return verifyCertNowNative(nickname, checkSig, certUsage.getUsage()); } /* * Obsolete in NSS */ private native boolean verifyCertNowNative(String nickname, boolean checkSig, int cUsage) throws ObjectNotFoundException; ///////////////////////////////////////////////////////////// // isCertValid ///////////////////////////////////////////////////////////// /** * Verify a certificate in memory. Check if * valid and that we trust the issuer. Verify time * against Now. * @param certPackage certificate in memory * @param checkSig verify the signature of the certificate * @param certUsage see exposed certUsage defines to verify Certificate * @return true for success; false otherwise * * @exception TokenException unable to insert temporary certificate * into database. * @exception CertificateEncodingException If the package encoding * was not recognized. */ public boolean isCertValid(byte[] certPackage, boolean checkSig, CertUsage certUsage) throws TokenException, CertificateEncodingException { return verifyCertTempNative(certPackage , checkSig, certUsage.getUsage()); } private native boolean verifyCertTempNative(byte[] certPackage, boolean checkSig, int cUsage) throws TokenException, CertificateEncodingException; /////////////////////////////////////////////////////////////////////// // OCSP management /////////////////////////////////////////////////////////////////////// /** * Enables OCSP, note when you Initialize JSS for the first time, for * backwards compatibility, the initialize will enable OCSP if you * previously set values.ocspCheckingEnabled and * values.ocspResponderURL/values.ocspResponderCertNickname * configureOCSP will allow changing of the the OCSPResponder at runtime. * * @param ocspChecking true or false to enable/disable OCSP * * @param ocspResponderURL - url of the OCSP responder * * @param ocspResponderCertNickname - the nickname of the OCSP * signer certificate or the CA certificate found in the cert DB */ public void configureOCSP( boolean ocspCheckingEnabled, String ocspResponderURL, String ocspResponderCertNickname ) throws GeneralSecurityException { configureOCSPNative(ocspCheckingEnabled, ocspResponderURL, ocspResponderCertNickname ); } private native void configureOCSPNative( boolean ocspCheckingEnabled, String ocspResponderURL, String ocspResponderCertNickname ) throws GeneralSecurityException; /** * change OCSP cache settings * * @param ocsp_cache_size max cache entries * * @param ocsp_min_cache_entry_duration minimum seconds to next fetch attempt * * @param ocsp_max_cache_entry_duration maximum seconds to next fetch attempt */ public void OCSPCacheSettings( int ocsp_cache_size, int ocsp_min_cache_entry_duration, int ocsp_max_cache_entry_duration) throws GeneralSecurityException { OCSPCacheSettingsNative(ocsp_cache_size, ocsp_min_cache_entry_duration, ocsp_max_cache_entry_duration); } private native void OCSPCacheSettingsNative( int ocsp_cache_size, int ocsp_min_cache_entry_duration, int ocsp_max_cache_entry_duration) throws GeneralSecurityException; /** * set OCSP timeout value * * @param ocspTimeout OCSP timeout in seconds */ public void setOCSPTimeout( int ocsp_timeout ) throws GeneralSecurityException { setOCSPTimeoutNative( ocsp_timeout); } private native void setOCSPTimeoutNative( int ocsp_timeout ) throws GeneralSecurityException; } jss-4.4.3/jss/org/mozilla/jss/DatabaseCloser.java000066400000000000000000000030231326145000000216610ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss; /** * A class for closing databases. Since closing the databases is * very dangerous and breaks the JSS model, it may only be done from * special applications. This class should be subclasses by * authorized subclasses. It cannot be instantiated itself. */ public abstract class DatabaseCloser { private static final String authorizedClosers[] = { "org.mozilla.certsetup.apps.CertSetup$DatabaseCloser", "org.mozilla.jss.CloseDBs" }; /** * Creates a new DatabaseCloser. This should only be called * from an authorized subclass. This class cannot itself be * instantiated. * * @throws Exception If the instantiation is not a valid subclass. */ public DatabaseCloser() throws Exception { Class clazz = this.getClass(); String name = clazz.getName(); boolean approved = false; for(int i=0; i < authorizedClosers.length; i++) { if( name.equals( authorizedClosers[i] ) ) { approved = true; break; } } if(!approved) { throw new Exception(); } } /** * Closes the certificate and key databases. This is extremely * dangerous. */ protected native void closeDatabases(); } jss-4.4.3/jss/org/mozilla/jss/JSSProvider.java000066400000000000000000000311561326145000000211670ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss; public final class JSSProvider extends java.security.Provider { /********************************************************************/ /* The VERSION Strings should be updated in the following */ /* files everytime a new release of JSS is generated: */ /* */ /* lib/manifest.mn */ /* org/mozilla/jss/CryptoManager.c */ /* org/mozilla/jss/CryptoManager.java */ /* org/mozilla/jss/JSSProvider.java */ /* org/mozilla/jss/util/jssver.h */ /* */ /********************************************************************/ /* QUESTION: When do we change MINOR and PATCH to 4 and 0? */ private static int JSS_MAJOR_VERSION = 4; private static int JSS_MINOR_VERSION = 4; private static int JSS_PATCH_VERSION = 0; private static double JSS_VERSION = JSS_MAJOR_VERSION + (JSS_MINOR_VERSION * 100 + JSS_PATCH_VERSION)/10000.0; public JSSProvider() { super("Mozilla-JSS", JSS_VERSION, "Provides Signature, Message Digesting, and RNG"); ///////////////////////////////////////////////////////////// // Signature ///////////////////////////////////////////////////////////// put("Signature.SHA1withDSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$DSA"); put("Alg.Alias.Signature.DSA", "SHA1withDSA"); put("Alg.Alias.Signature.DSS", "SHA1withDSA"); put("Alg.Alias.Signature.SHA/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.SHA-1/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.SHA1/DSA", "SHA1withDSA"); put("Alg.Alias.Signature.DSAWithSHA1", "SHA1withDSA"); put("Alg.Alias.Signature.SHAwithDSA", "SHA1withDSA"); put("Signature.MD5/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$MD5RSA"); put("Alg.Alias.Signature.MD5withRSA", "MD5/RSA"); put("Signature.MD2/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$MD2RSA"); put("Signature.SHA-1/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA1RSA"); put("Alg.Alias.Signature.SHA1/RSA", "SHA-1/RSA"); put("Alg.Alias.Signature.SHA1withRSA", "SHA-1/RSA"); put("Signature.SHA-256/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA256RSA"); put("Alg.Alias.Signature.SHA256/RSA", "SHA-256/RSA"); put("Alg.Alias.Signature.SHA256withRSA", "SHA-256/RSA"); put("Signature.SHA-384/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA384RSA"); put("Alg.Alias.Signature.SHA384/RSA", "SHA-384/RSA"); put("Alg.Alias.Signature.SHA384withRSA", "SHA-384/RSA"); put("Signature.SHA-512/RSA", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA512RSA"); put("Alg.Alias.Signature.SHA512/RSA", "SHA-512/RSA"); put("Alg.Alias.Signature.SHA512withRSA", "SHA-512/RSA"); // ECC put("Signature.SHA1withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA1EC"); put("Alg.Alias.Signature.EC", "SHA1withEC"); put("Alg.Alias.Signature.ECC", "SHA1withEC"); put("Alg.Alias.Signature.ECDSA", "SHA1withEC"); put("Alg.Alias.Signature.SHA/EC", "SHA1withEC"); put("Alg.Alias.Signature.SHA1/EC", "SHA1withEC"); put("Alg.Alias.Signature.SHA-1/EC", "SHA1withEC"); put("Alg.Alias.Signature.SHA/ECDSA", "SHA1withEC"); put("Alg.Alias.Signature.SHA1/ECDSA", "SHA1withEC"); put("Alg.Alias.Signature.SHA1withECDSA", "SHA1withEC"); //JCE Standard Name put("Signature.SHA256withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA256EC"); put("Alg.Alias.Signature.SHA256/EC", "SHA256withEC"); put("Alg.Alias.Signature.SHA-256/EC", "SHA256withEC"); put("Alg.Alias.Signature.SHA256withECDSA", "SHA256withEC"); //JCE Standard Name put("Signature.SHA384withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA384EC"); put("Alg.Alias.Signature.SHA384/EC", "SHA384withEC"); put("Alg.Alias.Signature.SHA-384/EC", "SHA384withEC"); put("Alg.Alias.Signature.SHA384withECDSA", "SHA384withEC"); //JCE Standard Name put("Signature.SHA512withEC", "org.mozilla.jss.provider.java.security.JSSSignatureSpi$SHA512EC"); put("Alg.Alias.Signature.SHA512/EC", "SHA512withEC"); put("Alg.Alias.Signature.SHA-512/EC", "SHA512withEC"); put("Alg.Alias.Signature.SHA512withECDSA", "SHA512withEC"); //JCE Standard Name ///////////////////////////////////////////////////////////// // Message Digesting ///////////////////////////////////////////////////////////// put("MessageDigest.SHA-1", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA1"); put("MessageDigest.MD2", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$MD2"); put("MessageDigest.MD5", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$MD5"); put("MessageDigest.SHA-256", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA256"); put("MessageDigest.SHA-384", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA384"); put("MessageDigest.SHA-512", "org.mozilla.jss.provider.java.security.JSSMessageDigestSpi$SHA512"); put("Alg.Alias.MessageDigest.SHA1", "SHA-1"); put("Alg.Alias.MessageDigest.SHA", "SHA-1"); put("Alg.Alias.MessageDigest.SHA256", "SHA-256"); put("Alg.Alias.MessageDigest.SHA384", "SHA-384"); put("Alg.Alias.MessageDigest.SHA512", "SHA-512"); ///////////////////////////////////////////////////////////// // SecureRandom ///////////////////////////////////////////////////////////// put("SecureRandom.pkcs11prng", "org.mozilla.jss.provider.java.security.JSSSecureRandomSpi"); ///////////////////////////////////////////////////////////// // KeyPairGenerator ///////////////////////////////////////////////////////////// put("KeyPairGenerator.RSA", "org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$RSA"); put("KeyPairGenerator.DSA", "org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$DSA"); put("KeyPairGenerator.EC", "org.mozilla.jss.provider.java.security.JSSKeyPairGeneratorSpi$EC"); ///////////////////////////////////////////////////////////// // KeyFactory ///////////////////////////////////////////////////////////// put("KeyFactory.RSA", "org.mozilla.jss.provider.java.security.KeyFactorySpi1_2"); put("KeyFactory.DSA", "org.mozilla.jss.provider.java.security.KeyFactorySpi1_2"); put("KeyFactory.EC", "org.mozilla.jss.provider.java.security.KeyFactorySpi1_2"); ///////////////////////////////////////////////////////////// // AlgorithmParameters ///////////////////////////////////////////////////////////// put("AlgorithmParameters.IvAlgorithmParameters", "org.mozilla.jss.provider.java.security.IvAlgorithmParameters"); put("AlgorithmParameters.RC2AlgorithmParameters", "org.mozilla.jss.provider.java.security.RC2AlgorithmParameters"); ///////////////////////////////////////////////////////////// // Cipher ///////////////////////////////////////////////////////////// put("Cipher.DES", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$DES"); put("Cipher.DESede", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$DESede"); put("Alg.Alias.Cipher.DES3", "DESede"); put("Cipher.AES", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$AES"); put("Cipher.RC4", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RC4"); put("Cipher.RSA", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RSA"); put("Cipher.RC2", "org.mozilla.jss.provider.javax.crypto.JSSCipherSpi$RC2"); ///////////////////////////////////////////////////////////// // KeyGenerator ///////////////////////////////////////////////////////////// put("KeyGenerator.DES", "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$DES"); put("KeyGenerator.DESede", "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$DESede"); put("Alg.Alias.KeyGenerator.DES3", "DESede"); put("KeyGenerator.AES", "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$AES"); put("KeyGenerator.RC4", "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$RC4"); put("KeyGenerator.RC2", "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$RC2"); put("KeyGenerator.HmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$HmacSHA1"); put("KeyGenerator.PBAHmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSKeyGeneratorSpi$PBAHmacSHA1"); ///////////////////////////////////////////////////////////// // SecretKeyFactory ///////////////////////////////////////////////////////////// put("SecretKeyFactory.DES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$DES"); put("SecretKeyFactory.DESede", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$DESede"); put("Alg.Alias.SecretKeyFactory.DES3", "DESede"); put("SecretKeyFactory.AES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$AES"); put("SecretKeyFactory.RC4", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$RC4"); put("SecretKeyFactory.RC2", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$RC2"); put("SecretKeyFactory.HmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$HmacSHA1"); put("SecretKeyFactory.PBAHmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBAHmacSHA1"); put("SecretKeyFactory.PBEWithMD5AndDES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_MD5_DES_CBC"); put("SecretKeyFactory.PBEWithSHA1AndDES", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_DES_CBC"); put("SecretKeyFactory.PBEWithSHA1AndDESede", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_DES3_CBC"); put("Alg.Alias.SecretKeyFactory.PBEWithSHA1AndDES3", "PBEWithSHA1AndDESede"); put("SecretKeyFactory.PBEWithSHA1And128RC4", "org.mozilla.jss.provider.javax.crypto.JSSSecretKeyFactorySpi$PBE_SHA1_RC4_128"); ///////////////////////////////////////////////////////////// // MAC ///////////////////////////////////////////////////////////// put("Mac.HmacSHA1", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA1"); put("Alg.Alias.Mac.Hmac-SHA1", "HmacSHA1"); put("Mac.HmacSHA256", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA256"); put("Alg.Alias.Mac.Hmac-SHA256", "HmacSHA256"); put("Mac.HmacSHA384", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA384"); put("Alg.Alias.Mac.Hmac-SHA384", "HmacSHA384"); put("Mac.HmacSHA512", "org.mozilla.jss.provider.javax.crypto.JSSMacSpi$HmacSHA512"); put("Alg.Alias.Mac.Hmac-SHA512", "HmacSHA512"); } public String toString() { String mozillaProviderVersion = JSS_MAJOR_VERSION + "." + JSS_MINOR_VERSION; if ( JSS_PATCH_VERSION != 0 ) { mozillaProviderVersion = mozillaProviderVersion + "." + JSS_PATCH_VERSION; } return "Mozilla-JSS version " + mozillaProviderVersion; } } jss-4.4.3/jss/org/mozilla/jss/KeyDatabaseException.java000066400000000000000000000010131326145000000230360ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss; /** * This exception is thrown if the key database does not exist, or if * an error occurs while opening it. */ public class KeyDatabaseException extends java.lang.Exception { public KeyDatabaseException() {} public KeyDatabaseException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/Makefile000066400000000000000000000035251326145000000176110ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### include rules.mk jss-4.4.3/jss/org/mozilla/jss/NoSuchTokenException.java000066400000000000000000000007061326145000000230710ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss; /** * Thrown if a token cannot be found. */ public class NoSuchTokenException extends java.lang.Exception { public NoSuchTokenException() {} public NoSuchTokenException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/PK11Finder.c000066400000000000000000001601511326145000000201200ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_CryptoManager.h" #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include /* * This is a semi-private NSS function, exposed only for JSS. */ SECStatus CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage); /* * This is a private function, used only by JSS in this file. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage); /***************************************************************** * * CryptoManager. f i n d C e r t B y N i c k n a m e N a t i v e * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_findCertByNicknameNative (JNIEnv *env, jobject this, jstring nickname) { char *nick=NULL; jobject certObject=NULL; CERTCertificate *cert=NULL; PK11SlotInfo *slot=NULL; PR_ASSERT(env!=NULL && this!=NULL && nickname!=NULL); nick = (char*) (*env)->GetStringUTFChars(env, nickname, NULL); PR_ASSERT(nick!=NULL); cert = JSS_PK11_findCertAndSlotFromNickname(nick, NULL, &slot); if(cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nick); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } certObject = JSS_PK11_wrapCertAndSlot(env, &cert, &slot); finish: if(nick != NULL) { (*env)->ReleaseStringUTFChars(env, nickname, nick); } if(cert != NULL) { CERT_DestroyCertificate(cert); } if(slot != NULL) { PK11_FreeSlot(slot); } return certObject; } /***************************************************************** * * CryptoManager. f i n d C e r t s B y N i c k n a m e N a t i v e * */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_findCertsByNicknameNative (JNIEnv *env, jobject this, jstring nickname) { CERTCertList *list =NULL; PK11SlotInfo *slot =NULL; jobjectArray certArray=NULL; CERTCertListNode *node; const char *nickChars=NULL; jboolean charsAreCopied; jclass certClass; int count; int i; /* convert the nickname string */ nickChars = (*env)->GetStringUTFChars(env, nickname, &charsAreCopied); if( nickChars == NULL ) { goto finish; } /* get the list of certs with the given nickname */ list = JSS_PK11_findCertsAndSlotFromNickname( (char*)nickChars, NULL /*wincx*/, &slot); if( list == NULL ) { count = 0; } else { /* Since this structure changed in NSS_2_7_RTM (the reference */ /* to "count" was removed from the "list" structure) we must */ /* now count up the number of nodes manually! */ for( node = CERT_LIST_HEAD(list), count=0; ! CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node), count++ ); } PR_ASSERT(count >= 0); /* create the cert array */ certClass = (*env)->FindClass(env, X509_CERT_CLASS); if( certClass == NULL ) { goto finish; } certArray = (*env)->NewObjectArray(env, count, certClass, NULL); if( certArray == NULL ) { /* exception was thrown */ goto finish; } if( list == NULL ) { goto finish; } /* traverse the list, placing each cert into the array */ for( node = CERT_LIST_HEAD(list), i=0; ! CERT_LIST_END(node, list); node = CERT_LIST_NEXT(node), i++ ) { CERTCertificate *cert; PK11SlotInfo *slotCopy; jobject certObj; /* Create a Java certificate object from the current CERTCertificate */ cert = CERT_DupCertificate(node->cert); slotCopy = PK11_ReferenceSlot(slot); certObj = JSS_PK11_wrapCertAndSlot(env, &cert, &slotCopy); if( certObj == NULL ) { goto finish; } /* put the Java certificate into the next element in the array */ (*env)->SetObjectArrayElement(env, certArray, i, certObj); if( (*env)->ExceptionOccurred(env) ) { goto finish; } } /* sanity check */ PR_ASSERT( i == count ); finish: if(list) { CERT_DestroyCertList(list); } if(slot) { PK11_FreeSlot(slot); } if( nickChars && charsAreCopied ) { (*env)->ReleaseStringUTFChars(env, nickname, nickChars); } return certArray; } /***************************************************************** * * CryptoManager.findCertByIssuerAndSerialNumberNative * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_findCertByIssuerAndSerialNumberNative (JNIEnv *env, jobject this, jbyteArray issuerBA, jbyteArray serialNumBA) { jobject certObject=NULL; CERTCertificate *cert=NULL; SECItem *issuer=NULL, *serialNum=NULL; CERTIssuerAndSN issuerAndSN; PK11SlotInfo *slot=NULL; PR_ASSERT(env!=NULL && this!=NULL); /* validate args */ if( issuerBA == NULL || serialNumBA == NULL ) { JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, "NULL parameter passed to CryptoManager.findCertByIssuer" "AndSerialNumberNative"); goto finish; } /* convert byte arrays to SECItems */ issuer = JSS_ByteArrayToSECItem(env, issuerBA); if( issuer == NULL ) { goto finish; } serialNum = JSS_ByteArrayToSECItem(env, serialNumBA); if( serialNum == NULL ) { goto finish; } issuerAndSN.derIssuer = *issuer; issuerAndSN.serialNumber = *serialNum; /* lookup with PKCS #11 first, then use cert database */ cert = PK11_FindCertByIssuerAndSN(&slot, &issuerAndSN, NULL /*wincx*/); if( cert == NULL ) { JSS_nativeThrow(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } certObject = JSS_PK11_wrapCertAndSlot(env, &cert, &slot); finish: if(slot) { PK11_FreeSlot(slot); } if(cert != NULL) { CERT_DestroyCertificate(cert); } if(issuer) { SECITEM_FreeItem(issuer, PR_TRUE /*freeit*/); } if(serialNum) { SECITEM_FreeItem(serialNum, PR_TRUE /*freeit*/); } return certObject; } /***************************************************************** * * CryptoManager. f i n d P r i v K e y B y C e r t N a t i v e * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_findPrivKeyByCertNative (JNIEnv *env, jobject this, jobject Cert) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread=NULL; CERTCertificate *cert; PK11SlotInfo *slot; SECKEYPrivateKey *privKey=NULL; jobject Key = NULL; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT( pThread != NULL); PR_ASSERT( env!=NULL && this!=NULL && Cert!=NULL); if( JSS_PK11_getCertPtr(env, Cert, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if(cert==NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } if( JSS_PK11_getCertSlotPtr(env, Cert, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if(slot==NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL); if(privKey == NULL) { JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION); goto finish; } Key = JSS_PK11_wrapPrivKey(env, &privKey); finish: if(privKey != NULL) { SECKEY_DestroyPrivateKey(privKey); } PR_DetachThread(); return Key; } /*********************************************************************** * Node in linked list of certificates */ typedef struct JSScertNode { struct JSScertNode *next; CERTCertificate *cert; } JSScertNode; /*********************************************************************** * * c e r t _ c h a i n _ f r o m _ c e r t * * Builds a certificate chain from a certificate. Returns a Java array * of PK11Certs. * * INPUTS: * env * The JNI environment. Must not be NULL. * handle * The certificate database in which to search for the certificate * chain. This should usually be the default cert db. Must not * be NULL. * leaf * A CERTCertificate that is the leaf of the cert chain. Must not * be NULL. * RETURNS: * NULL if an exception was thrown, or * A Java array of PK11Cert objects which constitute the chain of * certificates. The chains starts with the one passed in and * continues until either a self-signed root is found or the next * certificate in the chain cannot be found. At least one cert will * be in the chain: the leaf certificate passed in. */ static jobjectArray cert_chain_from_cert(JNIEnv *env, CERTCertDBHandle *handle, CERTCertificate *leaf) { CERTCertificate *c; int i, len = 0; JSScertNode *head=NULL, *tail, *node; jobjectArray certArray = NULL; jclass certClass; PR_ASSERT(env!=NULL && handle!=NULL && leaf!=NULL); head = tail = (JSScertNode*) PR_CALLOC( sizeof(JSScertNode) ); if (head == NULL) goto no_memory; /* put primary cert first in the linked list */ head->cert = c = CERT_DupCertificate(leaf); head->next = NULL; PR_ASSERT(c != NULL); /* CERT_DupCertificate really can't return NULL */ len++; /* * add certs until we come to a self-signed one */ while(SECITEM_CompareItem(&c->derIssuer, &c->derSubject) != SECEqual) { c = CERT_FindCertByName(handle, &tail->cert->derIssuer); if (c == NULL) break; tail->next = (JSScertNode*) PR_CALLOC( sizeof(JSScertNode) ); tail = tail->next; if (tail == NULL) goto no_memory; tail->cert = c; len++; } /* * Turn the cert chain into a Java array of certificates */ certClass = (*env)->FindClass(env, CERT_CLASS_NAME); if(certClass==NULL) { ASSERT_OUTOFMEM(env); goto finish; } certArray = (*env)->NewObjectArray(env, len, certClass, (jobject)NULL); if(certArray==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* convert linked list to array, freeing the linked list as we go */ for( i=0; head != NULL; ++i ) { jobject certObj; node = head; PR_ASSERT(i < len); PR_ASSERT(node->cert != NULL); /* Convert C cert to Java cert */ certObj = JSS_PK11_wrapCert(env, &node->cert); PR_ASSERT( node->cert == NULL ); if(certObj == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); goto finish; } /* Insert Java cert into array */ (*env)->SetObjectArrayElement(env, certArray, i, certObj); if( (*env)->ExceptionOccurred(env) ) { goto finish; } /* Free this list element */ head = head->next; PR_Free(node); } goto finish; no_memory: JSS_throw(env, OUT_OF_MEMORY_ERROR); finish: /* Free the linked list of certs if it hasn't been deleted already */ while(head != NULL) { node = head; head = head->next; if (node->cert != NULL) { CERT_DestroyCertificate(node->cert); } PR_Free(node); } return certArray; } /***************************************************************** * * CryptoManager. b u i l d C e r t i f i c a t e C h a i n N a t i v e * * INPUTS: * env * The JNI environment. Must not be NULL. * this * The PK11Finder object. Must not be NULL. * leafCert * A PK11Cert object from which a cert chain will be built. * Must not be NULL. * RETURNS: * NULL if an exception occurred, or * An array of PK11Certs, the cert chain, with the leaf at the bottom. * There will always be at least one element in the array (the leaf). */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_buildCertificateChainNative (JNIEnv *env, jobject this, jobject leafCert) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread=NULL; CERTCertificate *leaf; jobjectArray chainArray=NULL; CERTCertDBHandle *certdb; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); PR_ASSERT(env!=NULL && this!=NULL && leafCert!=NULL); if( JSS_PK11_getCertPtr(env, leafCert, &leaf) != PR_SUCCESS) { JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Could not extract pointer from PK11Cert"); goto finish; } PR_ASSERT(leaf!=NULL); certdb = CERT_GetDefaultCertDB(); if(certdb == NULL) { PR_ASSERT(PR_FALSE); JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "No default certificate database has been registered"); goto finish; } /* Get the cert chain */ chainArray = cert_chain_from_cert(env, certdb, leaf); if(chainArray == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } finish: PR_DetachThread(); return chainArray; } /*********************************************************************** * DERCertCollection */ typedef struct { SECItem *derCerts; int numCerts; } DERCertCollection; /*********************************************************************** * c o l l e c t _ c e r t s * * Copies certs into a new array. * * 'arg' is a pointer to a DERCertCollection structure, which will be filled in. * 'certs' is an array of pointers to SECItems. */ static SECStatus collect_der_certs(void *arg, SECItem **certs, int numcerts) { int itemsCopied=0; SECItem *certCopies; /* array of SECItem */ SECStatus rv; PR_ASSERT(arg!=NULL); certCopies = PR_MALLOC( sizeof(SECItem) * numcerts); ((DERCertCollection*)arg)->derCerts = certCopies; ((DERCertCollection*)arg)->numCerts = numcerts; if(certCopies == NULL) { return SECFailure; } for(itemsCopied=0; itemsCopied < numcerts; itemsCopied++) { rv=SECITEM_CopyItem(NULL, &certCopies[itemsCopied], certs[itemsCopied]); if( rv == SECFailure ) { goto loser; } } PR_ASSERT(itemsCopied == numcerts); return SECSuccess; loser: for(; itemsCopied >= 0; itemsCopied--) { SECITEM_FreeItem( &certCopies[itemsCopied], PR_FALSE /*freeit*/); } PR_Free( certCopies ); ((DERCertCollection*)arg)->derCerts = NULL; ((DERCertCollection*)arg)->numCerts = 0; return SECFailure; } /*********************************************************************** * CryptoManager.importCertToPerm * - add the certificate to the permanent database * * throws TOKEN_EXCEPTION */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_CryptoManager_importCertToPermNative (JNIEnv *env, jobject this, jobject cert, jstring nickString) { SECStatus rv; CERTCertificate *oldCert; jobject result=NULL; char *nickname=NULL; CERTCertificate **certArray = NULL; SECItem *derCertArray[1]; PK11SlotInfo *slot; /* first, get the NSS cert pointer from the 'cert' object */ if ( JSS_PK11_getCertPtr(env, cert, &oldCert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(oldCert != NULL); if (nickString != NULL) { nickname = (char*) (*env)->GetStringUTFChars(env, nickString, NULL); } /* Then, add to permanent database */ derCertArray[0] = &oldCert->derCert; rv = CERT_ImportCerts(CERT_GetDefaultCertDB(), -1 /* usage */, 1, derCertArray, &certArray, PR_TRUE /*keepCerts*/, PR_FALSE /*caOnly*/, nickname); if( rv != SECSuccess || certArray == NULL || certArray[0] == NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to insert certificate" " into permanent database"); goto finish; } slot = PK11_GetInternalKeySlot(); /* the permanent database token */ result = JSS_PK11_wrapCertAndSlot(env, &certArray[0], &slot); finish: /* this checks for NULL */ CERT_DestroyCertArray(certArray, 1); if (nickname != NULL) { (*env)->ReleaseStringUTFChars(env, nickString, nickname); } return result; } static unsigned char* data_start(unsigned char *buf, int length, unsigned int *data_length, PRBool includeTag) { unsigned char tag; int used_length= 0; tag = buf[used_length++]; /* blow out when we come to the end */ if (tag == 0) { return NULL; } *data_length = buf[used_length++]; if (*data_length&0x80) { int len_count = *data_length & 0x7f; *data_length = 0; while (len_count-- > 0) { *data_length = (*data_length << 8) | buf[used_length++]; } } if (*data_length > (length-used_length) ) { *data_length = length-used_length; return NULL; } if (includeTag) *data_length += used_length; return (buf + (includeTag ? 0 : used_length)); } static PRStatus getCertFields(SECItem *derCert, SECItem *issuer, SECItem *serial, SECItem *subject) { unsigned char *buf; unsigned int buf_length; unsigned char *date; unsigned int datelen; unsigned char *cert = derCert->data; unsigned int cert_length = derCert->len; /* get past the signature wrap */ buf = data_start(cert,cert_length,&buf_length,PR_FALSE); if (buf == NULL) return PR_FAILURE; /* get into the raw cert data */ buf = data_start(buf,buf_length,&buf_length,PR_FALSE); if (buf == NULL) return PR_FAILURE; /* skip past any optional version number */ if ((buf[0] & 0xa0) == 0xa0) { date = data_start(buf,buf_length,&datelen,PR_FALSE); if (date == NULL) return PR_FAILURE; buf_length -= (date-buf) + datelen; buf = date + datelen; } /* serial number */ serial->data = data_start(buf,buf_length,&serial->len,PR_FALSE); if (serial->data == NULL) return PR_FAILURE; buf_length -= (serial->data-buf) + serial->len; buf = serial->data + serial->len; /* skip the OID */ date = data_start(buf,buf_length,&datelen,PR_FALSE); if (date == NULL) return PR_FAILURE; buf_length -= (date-buf) + datelen; buf = date + datelen; /* issuer */ issuer->data = data_start(buf,buf_length,&issuer->len,PR_TRUE); if (issuer->data == NULL) return PR_FAILURE; buf_length -= (issuer->data-buf) + issuer->len; buf = issuer->data + issuer->len; /* skip the date */ date = data_start(buf,buf_length,&datelen,PR_FALSE); if (date == NULL) return PR_FAILURE; buf_length -= (date-buf) + datelen; buf = date + datelen; /*subject */ subject->data=data_start(buf,buf_length,&subject->len,PR_TRUE); if (subject->data == NULL) return PR_FAILURE; buf_length -= (subject->data-buf) + subject->len; buf = subject->data +subject->len; /*subject */ return PR_SUCCESS; } /** * Returns * -1 if operation error. * 0 if no leaf found. * 1 if leaf is found */ static int find_child_cert( CERTCertDBHandle *certdb, SECItem *derCerts, int numCerts, int *linked, int cur_link, int *leaf_link ) { int i; int status = 0; SECItem parentIssuer, parentSerial, parentSubject; PRStatus decodeStatus; decodeStatus = getCertFields(&derCerts[cur_link], &parentIssuer, &parentSerial, &parentSubject); if( decodeStatus != PR_SUCCESS ) { status = -1; goto finish; } for (i=0; iGetByteArrayElements(env, packageArray, NULL); if(packageBytes == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } packageLen = (*env)->GetArrayLength(env, packageArray); /*************************************************** * Decode package with NSS function ***************************************************/ status = CERT_DecodeCertPackage((char*) packageBytes, (int) packageLen, collect_der_certs, (void*) &collection); if( status != SECSuccess || collection.numCerts < 1 ) { if( (*env)->ExceptionOccurred(env) == NULL) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Security library failed to decode certificate package"); } goto finish; } derCerts = collection.derCerts; numCerts = collection.numCerts; /*************************************************** * convert nickname to char* ***************************************************/ if(nickString == NULL) { nickChars = NULL; } else { nickChars = (char*) (*env)->GetStringUTFChars(env, nickString, NULL); } /*************************************************** * user cert can be anywhere in the cert chain. loop and find it. * The point is to find the user cert with keys on the db, then * treat the other certs in the chain as CA certs to import. * The real order of the cert chain shouldn't matter, and shouldn't * be assumed, and the real location of this user cert in the chain, * if present, shouldn't be assumed either. ***************************************************/ if (numCerts > 1) { for (certi=0; certi= 1 ) { if (certi == 0) { status = CERT_ImportCAChainTrusted(derCerts+userCertFound, numCerts-userCertFound, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } } else if (certi == numCerts) { status = CERT_ImportCAChainTrusted(derCerts, numCerts-userCertFound, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } } else { status = CERT_ImportCAChainTrusted(derCerts, certi, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } status = CERT_ImportCAChainTrusted(derCerts+certi+1, numCerts-certi-1, certUsageUserCertImport); if(status != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "CERT_ImportCAChainTrusted returned an error"); goto finish; } } } /*************************************************** * Now lookup the leaf cert and make it into a Java object. ***************************************************/ if(slot) { PK11_FreeSlot(slot); } leafCert = PK11_FindCertByIssuerAndSN(&slot, &issuerAndSN, NULL); if( leafCert == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find certificate that was just imported"); goto finish; } leafObject = JSS_PK11_wrapCertAndSlot(env, &leafCert, &slot); finish: if(slot!=NULL) { PK11_FreeSlot(slot); } if(derCerts != NULL) { for(i=0; i < numCerts; i++) { SECITEM_FreeItem(&derCerts[i], PR_FALSE /*freeit*/); } PR_Free(derCerts); } if(packageBytes != NULL) { (*env)->ReleaseByteArrayElements(env, packageArray, packageBytes, JNI_ABORT); /* don't copy back */ } if(leafCert != NULL) { CERT_DestroyCertificate(leafCert); } return leafObject; } /********************************************************************** * PKCS #7 Encoding data structures */ typedef struct BufferNodeStr { char *data; unsigned long len; struct BufferNodeStr *next; } BufferNode; typedef struct { BufferNode *head; BufferNode *tail; unsigned long totalLen; } EncoderCallbackInfo; /********************************************************************** * c r e a t e E n c o d e r C a l l b a c k I n f o * * Constructor for EncoderCallbackInfo structure. * Returns NULL if it runs out of memory, otherwise a new EncoderCallbackInfo. */ static EncoderCallbackInfo* createEncoderCallbackInfo() { EncoderCallbackInfo *info; info = PR_Malloc( sizeof(EncoderCallbackInfo) ); if( info == NULL ) { return NULL; } info->head = info->tail = NULL; info->totalLen = 0; return info; } /*********************************************************************** * d e s t r o y E n c o d e r C a l l b a c k I n f o * * Destructor for EncoderCallbackInfo structure. */ static void destroyEncoderCallbackInfo(EncoderCallbackInfo *info) { BufferNode *node; PR_ASSERT(info != NULL); while(info->head != NULL) { node = info->head; info->head = info->head->next; if(node->data) { PR_Free(node->data); } PR_Free(node); } PR_Free(info); } /*********************************************************************** * e n c o d e r O u t p u t C a l l b a c k * * Called by the PKCS #7 encoder whenever output is available. * Appends the output to a linked list. */ static void encoderOutputCallback( void *arg, const char *buf, unsigned long len) { BufferNode *node; EncoderCallbackInfo *info; /*************************************************** * validate arguments ***************************************************/ PR_ASSERT(arg!=NULL); info = (EncoderCallbackInfo*) arg; if(len == 0) { return; } PR_ASSERT(buf != NULL); /*************************************************** * Create a new node to store this information ***************************************************/ node = PR_NEW( BufferNode ); if( node == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } node->len = len; node->data = PR_Malloc( len ); if( node->data == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } memcpy( node->data, buf, len ); node->next = NULL; /*************************************************** * Stick the new node onto the end of the list ***************************************************/ if( info->head == NULL ) { PR_ASSERT(info->tail == NULL); info->head = info->tail = node; } else { PR_ASSERT(info->tail != NULL); info->tail->next = node; info->tail = node; } node = NULL; info->totalLen += len; finish: if(node != NULL) { if( node->data != NULL) { PR_Free(node->data); } PR_Free(node); } return; } /*********************************************************************** * CryptoManager.exportCertsToPKCS7 */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_CryptoManager_exportCertsToPKCS7 (JNIEnv *env, jobject this, jobjectArray certArray) { int i, certcount; SEC_PKCS7ContentInfo *cinfo=NULL; CERTCertificate *cert; jclass certClass; jbyteArray pkcs7ByteArray=NULL; jbyte *pkcs7Bytes=NULL; EncoderCallbackInfo *info=NULL; SECStatus status; /************************************************** * Validate arguments **************************************************/ PR_ASSERT(env!=NULL && this!=NULL); if(certArray == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } certcount = (*env)->GetArrayLength(env, certArray); if(certcount < 1) { JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "At least one certificate must be passed to exportCertsToPKCS7"); goto finish; } /* * JNI ID lookup */ certClass = (*env)->FindClass(env, CERT_CLASS_NAME); if(certClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /*************************************************** * Add each cert to the PKCS #7 context. Create the context * for the first cert. ***************************************************/ for(i=0; i < certcount; i++) { jobject certObject; certObject = (*env)->GetObjectArrayElement(env, certArray, i); if( (*env)->ExceptionOccurred(env) != NULL) { goto finish; } PR_ASSERT( certObject != NULL ); /* * Make sure this is a PK11Cert */ if( ! (*env)->IsInstanceOf(env, certObject, certClass) ) { JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "Certificate was not a PK11 Certificate"); goto finish; } /* * Convert it to a CERTCertificate */ if( JSS_PK11_getCertPtr(env, certObject, &cert) != PR_SUCCESS) { JSS_trace(env, JSS_TRACE_ERROR, "Unable to convert Java certificate to CERTCertificate"); goto finish; } PR_ASSERT(cert != NULL); if( i == 0 ) { /* * First certificate: create a new PKCS #7 cert-only context */ PR_ASSERT(cinfo == NULL); cinfo = SEC_PKCS7CreateCertsOnly(cert, PR_FALSE, /* don't include chain */ NULL /* cert db */ ); if(cinfo == NULL) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Failed to create PKCS #7 encoding context"); goto finish; } } else { /* * All remaining certificates: add cert to context */ PR_ASSERT(cinfo != NULL); if( SEC_PKCS7AddCertificate(cinfo, cert) != SECSuccess ) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Failed to add certificate to PKCS #7 encoding context"); goto finish; } } } PR_ASSERT( i == certcount ); PR_ASSERT( cinfo != NULL ); /************************************************** * Encode the PKCS #7 context into its DER encoding **************************************************/ info = createEncoderCallbackInfo(); if(info == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } status = SEC_PKCS7Encode(cinfo, encoderOutputCallback, (void*)info, NULL /* bulk key */, NULL /* password function */, NULL /* password function arg */ ); if( status != SECSuccess ) { JSS_throwMsgPrErr(env, CERTIFICATE_ENCODING_EXCEPTION, "Failed to encode PKCS #7 context"); } /* Make sure we got at least some data from the encoder */ PR_ASSERT(info->totalLen > 0); PR_ASSERT(info->head != NULL); /************************************************** * Create a new byte array to hold the encoded PKCS #7 **************************************************/ pkcs7ByteArray = (*env)->NewByteArray(env, info->totalLen); if(pkcs7ByteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } pkcs7Bytes = (*env)->GetByteArrayElements(env, pkcs7ByteArray, NULL); if(pkcs7Bytes == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /************************************************** * Copy the PKCS #7 encoding into the byte array **************************************************/ { BufferNode *node; unsigned long processed=0; for(node=info->head; node!=NULL; node = node->next) { PR_ASSERT(processed < info->totalLen); PR_ASSERT(node->data != NULL); PR_ASSERT(node->len > 0); memcpy(pkcs7Bytes+processed, node->data, node->len); processed += node->len; } PR_ASSERT( processed == info->totalLen ); } finish: /************************************************** * Free allocated resources **************************************************/ if( cinfo != NULL) { SEC_PKCS7DestroyContentInfo(cinfo); } if(pkcs7Bytes != NULL) { PR_ASSERT(pkcs7ByteArray != NULL); (*env)->ReleaseByteArrayElements(env, pkcs7ByteArray, pkcs7Bytes, 0); } if( info != NULL ) { destroyEncoderCallbackInfo(info); } /************************************************** * Return the PKCS #7 information in a byte array, or NULL if an * exception occurred **************************************************/ PR_ASSERT( (*env)->ExceptionOccurred(env)!=NULL || pkcs7ByteArray!=NULL ); return pkcs7ByteArray; } /*************************************************************************** * getCerts * * Gathers all certificates of the given type into a Java array. */ static jobjectArray getCerts(JNIEnv *env, PK11CertListType type) { jobjectArray certArray = NULL; jclass certClass; jobject certObject; CERTCertList *certList = NULL; CERTCertListNode *node; int numCerts, i; certList = PK11_ListCerts(type, NULL); if( certList == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to list certificates"); goto finish; } /* first count the damn certs */ numCerts = 0; for( node = CERT_LIST_HEAD(certList); ! CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { ++numCerts; } /************************************************** * Create array of Java certificates **************************************************/ certClass = (*env)->FindClass(env, X509_CERT_CLASS); if(certClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } certArray = (*env)->NewObjectArray( env, numCerts, certClass, NULL ); if( certArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT( (*env)->ExceptionOccurred(env) == NULL ); /************************************************** * Put all the certs in the array **************************************************/ i = 0; for( node = CERT_LIST_HEAD(certList); ! CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { PR_ASSERT( i < numCerts ); certObject = JSS_PK11_wrapCert(env, &(node->cert)); if( certObject == NULL ) { goto finish; } (*env)->SetObjectArrayElement(env, certArray, i, certObject); if( (*env)->ExceptionOccurred(env) ) { goto finish; } ++i; } PR_ASSERT( i == numCerts ); finish: if( certList != NULL ) { CERT_DestroyCertList(certList); } return certArray; } /*********************************************************************** * CryptoManager.getCACerts */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_getCACerts (JNIEnv *env, jobject this) { return getCerts(env, PK11CertListCA); } /*********************************************************************** * CryptoManager.getPermCerts */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_CryptoManager_getPermCerts (JNIEnv *env, jobject this) { return getCerts(env, PK11CertListUnique); } /* Imports a CRL, and stores it into the cert7.db * * @param the DER-encoded CRL. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_importCRLNative (JNIEnv *env, jobject this, jbyteArray der_crl, jstring url_jstr, jint rl_type) { CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); CERTSignedCrl *crl = NULL; SECItem *packageItem = NULL; int status = SECFailure; char *url = NULL; char *errmsg = NULL; /*************************************************** * Validate arguments ***************************************************/ PR_ASSERT( env!=NULL && this!=NULL ); if(der_crl == NULL) { PR_ASSERT(PR_FALSE); /* XXX need new exception here */ JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "CRL package is NULL"); goto finish; } PR_ASSERT(certdb != NULL); /* convert CRL byte[] into secitem */ packageItem = JSS_ByteArrayToSECItem(env, der_crl); if ( packageItem == NULL ) { goto finish; } /* XXX need to deal with if error */ if (url_jstr != NULL) { url = (char*) (*env)->GetStringUTFChars(env, url_jstr, NULL); PR_ASSERT(url!=NULL); } else { url = NULL; } crl = CERT_ImportCRL( certdb, packageItem, url, rl_type, NULL); if( crl == NULL ) { status = PR_GetError(); errmsg = NULL; switch (status) { case SEC_ERROR_OLD_CRL: case SEC_ERROR_OLD_KRL: /* not an error - leave as NULL */ errmsg = NULL; goto finish; case SEC_ERROR_CRL_EXPIRED: errmsg = "CRL Expired"; break; case SEC_ERROR_KRL_EXPIRED: errmsg = "KRL Expired"; break; case SEC_ERROR_CRL_NOT_YET_VALID: errmsg = "CRL Not yet valid"; break; case SEC_ERROR_KRL_NOT_YET_VALID: errmsg = "KRL Not yet valid"; break; case SEC_ERROR_CRL_INVALID: errmsg = "Invalid encoding of CRL"; break; case SEC_ERROR_KRL_INVALID: errmsg = "Invalid encoding of KRL"; break; case SEC_ERROR_BAD_DATABASE: errmsg = "Database error"; break; default: /* printf("NSS ERROR = %d\n",status); */ errmsg = "Failed to import Revocation List"; } if (errmsg) { JSS_throwMsgPrErr(env, CRL_IMPORT_EXCEPTION, errmsg); } } finish: if (packageItem) { SECITEM_FreeItem(packageItem, PR_TRUE /*freeit*/); } if(url != NULL) { (*env)->ReleaseStringUTFChars(env, url_jstr, url); } if (crl) { SEC_DestroyCrl(crl); } } /*********************************************************************** * CryptoManager.verifyCertificateNow * * Called by java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative */ SECStatus verifyCertificateNow(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage, SECCertificateUsage *currUsage) { SECStatus rv = SECFailure; SECCertificateUsage certificateUsage; CERTCertificate *cert=NULL; char *nickname=NULL; nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL); if( nickname == NULL ) { goto finish; } certificateUsage = required_certificateUsage; cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } else { /* 0 for certificateUsage in call to CERT_VerifyCertificateNow will * retrieve the current valid usage into currUsage */ rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, currUsage ); if ((rv == SECSuccess) && certificateUsage == 0x0000) { if (*currUsage == ( certUsageUserCertImport | certUsageVerifyCA | certUsageProtectedObjectSigner | certUsageAnyCA )) { /* the cert is good for nothing The folllowing usages cannot be verified: certUsageAnyCA certUsageProtectedObjectSigner certUsageUserCertImport certUsageVerifyCA (0x0b80) */ rv =SECFailure; } } } finish: if(nickname != NULL) { (*env)->ReleaseStringUTFChars(env, nickString, nickname); } if(cert != NULL) { CERT_DestroyCertificate(cert); } return rv; } /*********************************************************************** * CryptoManager.verifyCertificateNowNative * * Returns JNI_TRUE if success, JNI_FALSE otherwise */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage) { SECStatus rv = SECFailure; SECCertificateUsage certificateUsage; SECCertificateUsage currUsage; /* unexposed for now */ CERTCertificate *cert=NULL; char *nickname=NULL; nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL); if( nickname == NULL ) { goto finish; } certificateUsage = required_certificateUsage; cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } else { /* 0 for certificateUsage in call to CERT_VerifyCertificateNow to * just get the current usage (which we are not passing back for now * but will bypass the certificate usage check */ rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, &currUsage ); } finish: if(nickname != NULL) { (*env)->ReleaseStringUTFChars(env, nickString, nickname); } if(cert != NULL) { CERT_DestroyCertificate(cert); } if( rv == SECSuccess) { return JNI_TRUE; } else { return JNI_FALSE; } } /*********************************************************************** * CryptoManager.verifyCertificateNowCUNative * * Returns jint which contains bits in SECCertificateUsage that reflects * the cert usage(s) that the cert is good for * if the cert is good for nothing, returned value is * (0x0b80): * certUsageUserCertImport | * certUsageVerifyCA | * certUsageProtectedObjectSigner | * certUsageAnyCA */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig) { SECStatus VARIABLE_MAY_NOT_BE_USED rv = SECFailure; SECCertificateUsage currUsage = 0x0000; rv = verifyCertificateNow(env, self, nickString, checkSig, 0, &currUsage); /* rv is ignored */ return currUsage; } /*********************************************************************** * CryptoManager.verifyCertificateNowNative2 * * Verify a certificate that exists in the given cert database, * check if it's valid and that we trust the issuer. Verify time * against now. * @param nickname nickname of the certificate to verify. * @param checkSig verify the signature of the certificate * @param certificateUsage see certificate usage defined to verify certificate * * @exception InvalidNicknameException If the nickname is null. * @exception ObjectNotFoundException If no certificate could be found * with the given nickname. * @exception CertificateException If certificate is invalid. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage) { jint certificateUsage; SECCertificateUsage currUsage = 0x0000; /* unexposed for now */ SECStatus rv = SECFailure; CERTCertificate *cert = NULL; char *nickname = NULL; if (nickString == NULL) { JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname"); goto finish; } nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL); if (nickname == NULL) { JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname"); goto finish; } certificateUsage = required_certificateUsage; cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *msgBuf; msgBuf = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, msgBuf); PR_Free(msgBuf); goto finish; } /* 0 for certificateUsage in call to CERT_VerifyCertificateNow will * retrieve the current valid usage into currUsage */ rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, checkSig, certificateUsage, NULL, &currUsage); if (rv != SECSuccess) { JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Invalid certificate"); goto finish; } if ((certificateUsage == 0x0000) && (currUsage == ( certUsageUserCertImport | certUsageVerifyCA | certUsageProtectedObjectSigner | certUsageAnyCA ))) { /* The certificate is good for nothing. * The following usages cannot be verified: * certUsageAnyCA * certUsageProtectedObjectSigner * certUsageUserCertImport * certUsageVerifyCA * (0x0b80) */ JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Unusable certificate"); goto finish; } finish: if (nickname != NULL) { (*env)->ReleaseStringUTFChars(env, nickString, nickname); } if (cert != NULL) { CERT_DestroyCertificate(cert); } } /*********************************************************************** * CryptoManager.verifyCertNowNative * note: this calls obsolete NSS function * Returns JNI_TRUE if success, JNI_FALSE otherwise */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertNowNative(JNIEnv *env, jobject self, jstring nickString, jboolean checkSig, jint cUsage) { SECStatus rv = SECFailure; SECCertUsage certUsage; CERTCertificate *cert=NULL; char *nickname=NULL; nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL); if( nickname == NULL ) { goto finish; } certUsage = cUsage; cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname); if (cert == NULL) { char *message = PR_smprintf("Certificate not found: %s", nickname); JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, message); PR_smprintf_free(message); goto finish; } else { rv = CERT_VerifyCertNow(CERT_GetDefaultCertDB(), cert, checkSig, certUsage, NULL ); } finish: if(nickname != NULL) { (*env)->ReleaseStringUTFChars(env, nickString, nickname); } if(cert != NULL) { CERT_DestroyCertificate(cert); } if( rv == SECSuccess) { return JNI_TRUE; } else { return JNI_FALSE; } } /*********************************************************************** * CryptoManager.verifyCertNative * * Returns JNI_TRUE if success, JNI_FALSE otherwise */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_CryptoManager_verifyCertTempNative(JNIEnv *env, jobject self, jbyteArray packageArray,jboolean checkSig, jint cUsage) { SECStatus rv = SECFailure; SECCertUsage certUsage; SECItem *derCerts[2] = { NULL, NULL }; CERTCertificate **certArray = NULL; CERTCertDBHandle *certdb = CERT_GetDefaultCertDB(); /*************************************************** * Validate arguments ***************************************************/ if (packageArray == NULL) { JSS_throwMsg(env, CERTIFICATE_ENCODING_EXCEPTION, "Certificate package is NULL"); goto finish; } PR_ASSERT(certdb != NULL); derCerts[0] = JSS_ByteArrayToSECItem(env, packageArray); derCerts[1] = NULL; rv = CERT_ImportCerts(certdb, cUsage, 1, derCerts, &certArray, PR_FALSE /*temp Certs*/, PR_FALSE /*caOnly*/, NULL); if ( rv != SECSuccess || certArray == NULL || certArray[0] == NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to insert certificate" " into temporary database"); goto finish; } certUsage = cUsage; rv = CERT_VerifyCertNow(certdb, certArray[0], checkSig, certUsage, NULL ); finish: /* this checks for NULL */ CERT_DestroyCertArray(certArray, 1); if (derCerts[0]) { SECITEM_FreeItem(derCerts[0], PR_TRUE /*freeit*/); } if ( rv == SECSuccess) { return JNI_TRUE; } else { return JNI_FALSE; } } jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/000077500000000000000000000000001326145000000214775ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/Decryptor.java000066400000000000000000000066111326145000000243210ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.SecretDecoderRing; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.TokenException; import java.io.*; /** * Decrypts data with the SecretDecoderRing. */ public class Decryptor { private CryptoToken token; private KeyManager keyManager; /** * Creates a Decryptor for use with the given CryptoToken. */ public Decryptor(CryptoToken token) { this.token = token; this.keyManager = new KeyManager(token); } /** * Decrypts the given ciphertext. It must have been created previously * with the SecretDecoderRing, either the JSS version or the NSS version. * The key used for decryption must exist on the token that was passed * into the constructor. The token will be searched for a key whose keyID * matches the keyID in the encoded SecretDecoderRing result. * * @param ciphertext A DER-encoded Encoding object, created from a previous * call to Encryptor.encrypt(), or with the NSS SecretDecoderRing. * @return The decrypted plaintext. * @throws InvalidKeyException If no key can be found with the matching * keyID. */ public byte[] decrypt(byte[] ciphertext) throws CryptoManager.NotInitializedException, GeneralSecurityException, TokenException { CryptoManager cm = CryptoManager.getInstance(); CryptoToken savedToken = cm.getThreadToken(); try { cm.setThreadToken(token); // // decode ASN1 // Encoding encoding = (Encoding) ASN1Util.decode(Encoding.getTemplate(), ciphertext); // // lookup the algorithm // EncryptionAlgorithm alg = EncryptionAlgorithm.fromOID( encoding.getEncryptionOID() ); // // Lookup the key // SecretKey key = keyManager.lookupKey(alg, encoding.getKeyID()); if( key == null ) { throw new InvalidKeyException("No matching key found"); } // // do the decryption // IvParameterSpec ivSpec = new IvParameterSpec(encoding.getIv()); Cipher cipher = Cipher.getInstance(alg.toString(), Encryptor.PROVIDER); cipher.init(Cipher.DECRYPT_MODE, key, ivSpec); byte[] paddedPtext = cipher.doFinal(encoding.getCiphertext()); return org.mozilla.jss.crypto.Cipher.unPad(paddedPtext, alg.getBlockSize() ); } catch(InvalidBERException ibe) { throw new GeneralSecurityException(ibe.toString()); } catch(IllegalStateException ise) { throw new GeneralSecurityException(ise.toString()); } catch(org.mozilla.jss.crypto.BadPaddingException bpe) { throw new javax.crypto.BadPaddingException(bpe.getMessage()); } finally { cm.setThreadToken(savedToken); } } } jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/Encoding.java000066400000000000000000000073521326145000000240770ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.SecretDecoderRing; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import java.io.*; /** * An ASN.1 class for encoding the SecretDecoderRing result. * This class is used internally by the SecretDecoderRing. * You need not use this class directly in order to use the SecretDecoderRing. */ public class Encoding implements ASN1Value { private SEQUENCE seq = new SEQUENCE(); private byte[] iv; private OBJECT_IDENTIFIER encOID; private byte[] ctext; private byte[] keyID; public Encoding(byte[] keyID, byte[] iv, OBJECT_IDENTIFIER encOID, byte[] ctext) { this.keyID = keyID; this.iv = iv; this.encOID = encOID; this.ctext = ctext; AlgorithmIdentifier algID = new AlgorithmIdentifier( encOID, new OCTET_STRING(iv) ); seq.addElement(new OCTET_STRING(keyID)); seq.addElement(algID); seq.addElement(new OCTET_STRING(ctext)); } public byte[] getKeyID() { return keyID; } public byte[] getIv() { return iv; } public OBJECT_IDENTIFIER getEncryptionOID() { return encOID; } public byte[] getCiphertext() { return ctext; } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * An ASN.1 class for decoding the SecretDecoderRing result. * This class is used internally by the SecretDecoderRing. * You need not use this class directly in order to use the * SecretDecoderRing. */ public static class Template extends SEQUENCE.Template { private SEQUENCE.Template template; public Template() { template = new SEQUENCE.Template(); template.addElement(OCTET_STRING.getTemplate() ); template.addElement(AlgorithmIdentifier.getTemplate() ); template.addElement(OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) template.decode(implicitTag, istream); OCTET_STRING keyID = (OCTET_STRING) seq.elementAt(0); AlgorithmIdentifier algID = (AlgorithmIdentifier) seq.elementAt(1); OCTET_STRING ivOS = (OCTET_STRING) ((ANY)algID.getParameters()).decodeWith( OCTET_STRING.getTemplate()); OCTET_STRING ctextOS = (OCTET_STRING)seq.elementAt(2); return new Encoding(keyID.toByteArray(), ivOS.toByteArray(), algID.getOID(), ctextOS.toByteArray()); } } } jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/Encryptor.java000066400000000000000000000076421326145000000243400ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.SecretDecoderRing; import java.security.*; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.TokenException; import java.io.*; /** * Encrypts data with the SecretDecoderRing. */ public class Encryptor { private CryptoToken token; private byte[] keyID; private SecretKey key; private EncryptionAlgorithm alg; private KeyManager keyManager; /** * The default encryption algorithm, currently DES3_CBC. */ public static final EncryptionAlgorithm DEFAULT_ENCRYPTION_ALG = EncryptionAlgorithm.DES3_CBC; static final String PROVIDER = "Mozilla-JSS"; static final String RNG_ALG = "pkcs11prng"; /** * Creates an Encryptor on the given CryptoToken, using the key with * the given keyID and algorithm * @param token The CryptoToken to use for encryption. The key must * reside on this token. * @param keyID The keyID of the key to use for encryption. This key * must have been generated on this token with KeyManager. * @param alg The EncryptionAlgorithm this key will be used for. * @throws InvalidKeyException If no key exists on this token with this * keyID. */ public Encryptor(CryptoToken token, byte[] keyID, EncryptionAlgorithm alg) throws TokenException, InvalidKeyException { this.token = token; this.keyID = keyID; this.alg = alg; this.keyManager = new KeyManager(token); // make sure this key exists on the token key = keyManager.lookupKey(alg, keyID); if( key == null ) { throw new InvalidKeyException("Key not found"); } // make sure key matches algorithm // !!! not sure how to do this } /** * Encrypts a byte array. * @param plaintext The plaintext bytes to be encrypted. * @return The ciphertext. This is actually a DER-encoded Encoding * object. It contains the keyID, AlgorithmIdentifier, and the encrypted * plaintext. It is compatible with the SDRResult created by NSS's * SecretDecoderRing. */ public byte[] encrypt(byte[] plaintext) throws CryptoManager.NotInitializedException, GeneralSecurityException, InvalidBERException { CryptoManager cm = CryptoManager.getInstance(); CryptoToken savedToken = cm.getThreadToken(); try { cm.setThreadToken(token); // // generate an IV // byte[] iv = new byte[alg.getIVLength()]; SecureRandom rng = SecureRandom.getInstance(RNG_ALG, PROVIDER); rng.nextBytes(iv); IvParameterSpec ivSpec = new IvParameterSpec(iv); // // do the encryption // Cipher cipher = Cipher.getInstance(alg.toString(),PROVIDER); cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec); byte[] paddedPtext = org.mozilla.jss.crypto.Cipher.pad( plaintext, alg.getBlockSize() ); byte[] rawCtext = cipher.doFinal(paddedPtext); // // package the encrypted content and IV // Encoding encoding = new Encoding(keyID, iv, alg.toOID(), rawCtext); return ASN1Util.encode(encoding); } catch(IllegalStateException ise ) { throw new GeneralSecurityException(ise.toString()); } finally { cm.setThreadToken(savedToken); } } } jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/KeyManager.c000066400000000000000000000241301326145000000236660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_SecretDecoderRing_KeyManager.h" #include #include #include #include #include #include #include JNIEXPORT void JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jbyteArray keyIDba, jint keySize) { PK11SlotInfo *slot = NULL; CK_MECHANISM_TYPE mech; PK11SymKey *symk = NULL; SECItem *keyID = NULL; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key ID */ keyID = JSS_ByteArrayToSECItem(env, keyIDba); if( keyID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* get the algorithm */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } /* generate the key */ symk = PK11_TokenKeyGen(slot, mech, NULL /*param*/, keySize, keyID, PR_TRUE /* isToken */, NULL /*wincx*/); if( symk == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to generate token symmetric key"); goto finish; } finish: if( symk != NULL ) { PK11_FreeSymKey(symk); } if( keyID != NULL ) { SECITEM_FreeItem(keyID, PR_TRUE /*freeit*/); } return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_generateUniqueNamedKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jbyteArray keyIDba, jint keySize, jstring nickname) { PK11SlotInfo *slot = NULL; CK_MECHANISM_TYPE mech; PK11SymKey *symk = NULL; SECItem *keyID = NULL; const char *keyname = NULL; SECStatus status; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key ID */ keyID = JSS_ByteArrayToSECItem(env, keyIDba); if( keyID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* get the algorithm */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } /* generate the key */ symk = PK11_TokenKeyGen(slot, mech, NULL /*param*/, keySize, keyID, PR_TRUE /* isToken */, NULL /*wincx*/); if( symk == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to generate token symmetric key"); goto finish; } /* convert the Java String into a native "C" string */ keyname = (*env)->GetStringUTFChars( env, nickname, 0 ); /* name the key */ status = PK11_SetSymKeyNickname( symk, keyname ); if( status != SECSuccess ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to name token symmetric key"); } finish: if( symk != NULL ) { PK11_FreeSymKey(symk); } if( keyID != NULL ) { SECITEM_FreeItem(keyID, PR_TRUE /*freeit*/); } if( keyname != NULL ) { /* free the native "C" string */ (*env)->ReleaseStringUTFChars(env, nickname, keyname); } return; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jbyteArray keyIDba) { PK11SlotInfo *slot = NULL; PK11SymKey *symk = NULL; SECItem *keyID = NULL; jobject symkObj = NULL; CK_MECHANISM_TYPE mech; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key ID */ keyID = JSS_ByteArrayToSECItem(env, keyIDba); if( keyID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* get the algorithm */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } symk = PK11_FindFixedKey(slot, mech, keyID, NULL /*wincx*/); if( symk != NULL ) { symkObj = JSS_PK11_wrapSymKey(env, &symk); } finish: if( symk != NULL ) { PK11_FreeSymKey(symk); } if( keyID != NULL ) { SECITEM_FreeItem(keyID, PR_TRUE /*freeit*/); } return symkObj; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_lookupUniqueNamedKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject algObj, jstring nickname) { PK11SlotInfo *slot = NULL; CK_MECHANISM_TYPE mech; const char *keyname = NULL; char *name = NULL; int count = 0; int keys_found = 0; PK11SymKey *symKey = NULL; PK11SymKey *nextSymKey = NULL; jobject symKeyObj = NULL; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the algorithm -- although this is not currently used */ mech = JSS_getPK11MechFromAlg(env, algObj); if( mech == CKM_INVALID_MECHANISM) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to find PKCS #11 " "mechanism for key generation algorithm"); goto finish; } /* convert the Java String into a native "C" string */ keyname = (*env)->GetStringUTFChars( env, nickname, 0 ); /* initialize the symmetric key list. */ symKey = PK11_ListFixedKeysInSlot( /* slot */ slot, /* nickname */ NULL, /* wincx */ NULL ); /* iterate through the symmetric key list. */ while( symKey != NULL ) { name = PK11_GetSymKeyNickname( /* symmetric key */ symKey ); if( name != NULL ) { if( keyname != NULL ) { if( PL_strcmp( keyname, name ) == 0 ) { keys_found++; } } PORT_Free(name); } nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey ); PK11_FreeSymKey( /* symmetric key */ symKey ); symKey = nextSymKey; count++; } /* case 1: the token is empty */ if( count == 0 ) { /* the specified token is empty */ goto finish; } /* case 2: the specified key is not on this token */ if( ( keyname != NULL ) && ( keys_found == 0 ) ) { /* the key called "keyname" could not be found */ goto finish; } /* case 3: the specified key exists more than once on this token */ if( keys_found != 1 ) { /* more than one key called "keyname" was found on this token */ JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Duplicate named keys exist on this token"); goto finish; } /* Re-initialize the symmetric key list. */ symKey = PK11_ListFixedKeysInSlot( /* slot */ slot, /* nickname */ NULL, /* wincx */ NULL ); /* Reiterate through the symmetric key list once more, */ /* this time returning an actual reference to the key. */ while( symKey != NULL ) { name = PK11_GetSymKeyNickname( /* symmetric key */ symKey ); if( name != NULL ) { if( keyname != NULL ) { if( PL_strcmp( keyname, name ) == 0 ) { symKeyObj = JSS_PK11_wrapSymKey(env, &symKey); PORT_Free(name); goto finish; } } PORT_Free(name); } nextSymKey = PK11_GetNextSymKey( /* symmetric key */ symKey ); PK11_FreeSymKey( /* symmetric key */ symKey ); symKey = nextSymKey; } finish: if( symKey != NULL ) { PK11_FreeSymKey(symKey); } if( keyname != NULL ) { /* free the native "C" string */ (*env)->ReleaseStringUTFChars(env, nickname, keyname); } return symKeyObj; } JNIEXPORT void JNICALL Java_org_mozilla_jss_SecretDecoderRing_KeyManager_deleteKeyNative (JNIEnv *env, jobject this, jobject tokenObj, jobject key) { PK11SlotInfo *slot = NULL; PK11SymKey *symk = NULL; /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS ) { goto finish; } if( PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/) != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to login to token"); goto finish; } /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, key, &symk) != PR_SUCCESS) { goto finish; } if( PK11_DeleteTokenSymKey(symk) != SECSuccess ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to delete token symmetric key"); goto finish; } finish: /* don't free symk or slot, they are owned by their Java objects */ return; } jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/KeyManager.java000066400000000000000000000252351326145000000243740ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.SecretDecoderRing; import java.security.*; import javax.crypto.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.Assert; /** * Creates, finds, and deletes keys for SecretDecoderRing. */ public class KeyManager { private static final int KEYID_LEN = 16; private static final String RNG_ALG = "pkcs11prng"; private static final String RNG_PROVIDER = "Mozilla-JSS"; /** * The default key generation algorithm, currently DES3. */ public static final KeyGenAlgorithm DEFAULT_KEYGEN_ALG = KeyGenAlgorithm.DES3; /** * The default key size (in bytes). This is only relevant for algorithms * with variable-length keys, such as AES. */ public static final int DEFAULT_KEYSIZE = 0; private CryptoToken token; /** * Creates a new KeyManager using the given CryptoToken. * @param token The token on which this KeyManager operates. */ public KeyManager(CryptoToken token) { if( token == null ) { throw new NullPointerException("token is null"); } this.token = token; } /** * Generates an SDR key with the default algorithm and key size. * The default algorithm is stored in the constant DEFAULT_KEYGEN_ALG. * The default key size is stored in the constant DEFAULT_KEYSIZE. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateKey() throws TokenException { return generateKey(DEFAULT_KEYGEN_ALG, DEFAULT_KEYSIZE); } /** * Generates an SDR key with the given algorithm and key size. * @param keySize Length of key in bytes. This is only relevant for * algorithms that take more than one key size. Otherwise it can just * be set to 0. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateKey(KeyGenAlgorithm alg, int keySize) throws TokenException { if( alg == null ) { throw new NullPointerException("alg is null"); } byte[] keyID = generateUnusedKeyID(); generateKeyNative(token, alg, keyID, keySize); return keyID; } /** * @param keySize Key length in bytes. */ private native void generateKeyNative(CryptoToken token, KeyGenAlgorithm alg, byte[] keyID, int keySize); /** * Generates an SDR key with the default algorithm and key size. * and names it with the specified nickname. * The default algorithm is stored in the constant DEFAULT_KEYGEN_ALG. * The default key size is stored in the constant DEFAULT_KEYSIZE. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateUniqueNamedKey(String nickname) throws TokenException { return generateUniqueNamedKey(DEFAULT_KEYGEN_ALG, DEFAULT_KEYSIZE, nickname); } /** * Generates an SDR key with the given algorithm, key size, and nickname. * @param alg The algorithm that this key will be used for. * This is necessary because it will be stored along with the * key for later use by the security library. * @param keySize Length of key in bytes. This is only relevant for * algorithms that take more than one key size. Otherwise it can just * be set to 0. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. * @return The keyID of the generated key. A random keyID will be chosen * that is not currently used on the token. The keyID must be stored * by the application in order to use this key for encryption in the * future. */ public byte[] generateUniqueNamedKey(KeyGenAlgorithm alg, int keySize, String nickname) throws TokenException { // always strip all preceding/trailing whitespace // from passed-in String parameters if( nickname != null ) { nickname = nickname.trim(); } if( alg == null ) { throw new NullPointerException("alg is null"); } // disallow duplicates (i. e. - symmetric keys with the same name) if( uniqueNamedKeyExists(nickname) ) { throw new NullPointerException("duplicate symmetric key"); } byte[] keyID = generateUnusedKeyID(); generateUniqueNamedKeyNative(token, alg, keyID, keySize, nickname); return keyID; } /** * @param keySize Key length in bytes. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. */ private native void generateUniqueNamedKeyNative(CryptoToken token, KeyGenAlgorithm alg, byte[] keyID, int keySize, String nickname); /** * Generates a key ID that is currently unused on this token. * The caller is responsible for synchronization issues that may arise * if keys are generated by different threads. */ private byte[] generateUnusedKeyID() throws TokenException { try { SecureRandom rng = SecureRandom.getInstance(RNG_ALG, RNG_PROVIDER); byte[] keyID = new byte[KEYID_LEN]; do { rng.nextBytes(keyID); } while( keyExists(keyID) ); return keyID; } catch(NoSuchAlgorithmException nsae) { throw new RuntimeException("No such algorithm: " + RNG_ALG); } catch(NoSuchProviderException nspe) { throw new RuntimeException("No such provider: " + RNG_PROVIDER); } } private boolean keyExists(byte[] keyid) throws TokenException { return (lookupKey(Encryptor.DEFAULT_ENCRYPTION_ALG, keyid) != null); } /** * Looks up the key on this token with the given algorithm and key ID. * @param alg The algorithm that this key will be used for. * This is necessary because it will be stored along with the * key for later use by the security library. It should match * the actual algorithm of the key you are looking for. If you * pass in a different algorithm and try to use the key that is returned, * the results are undefined. * @return The key, or null if the key is not found. */ public SecretKey lookupKey(EncryptionAlgorithm alg, byte[] keyid) throws TokenException { if( alg == null || keyid == null ) { throw new NullPointerException(); } SymmetricKey k = lookupKeyNative(token, alg, keyid); if( k == null ) { return null; } else { return new SecretKeyFacade(k); } } private native SymmetricKey lookupKeyNative(CryptoToken token, EncryptionAlgorithm alg, byte[] keyid) throws TokenException; public boolean uniqueNamedKeyExists(String nickname) throws TokenException { return (lookupUniqueNamedKey(Encryptor.DEFAULT_ENCRYPTION_ALG, nickname) != null); } /** * Looks up the key on this token with the given algorithm and nickname. * @param alg The algorithm that this key will be used for. * This is necessary because it will be stored along with the * key for later use by the security library. It should match * the actual algorithm of the key you are looking for. If you * pass in a different algorithm and try to use the key that is returned, * the results are undefined. * @param nickname the name of the symmetric key. Duplicate keynames * will be checked for, and are not allowed. * @return The key, or null if the key is not found. */ public SecretKey lookupUniqueNamedKey(EncryptionAlgorithm alg, String nickname) throws TokenException { // always strip all preceding/trailing whitespace // from passed-in String parameters if( nickname != null ) { nickname = nickname.trim(); } if( alg == null || nickname == null || nickname.equals("") ) { throw new NullPointerException(); } SymmetricKey k = lookupUniqueNamedKeyNative(token, alg, nickname); if( k == null ) { return null; } else { return new SecretKeyFacade(k); } } private native SymmetricKey lookupUniqueNamedKeyNative(CryptoToken token, EncryptionAlgorithm alg, String nickname) throws TokenException; /** * Deletes the key with the given keyID from this token. * @throws InvalidKeyException If the key does not exist on this token. */ public void deleteKey(byte[] keyID) throws TokenException, InvalidKeyException { deleteKey(lookupKey(Encryptor.DEFAULT_ENCRYPTION_ALG, keyID)); } /** * If it exists, delete the key with the specified nickname from this * token. */ public void deleteUniqueNamedKey(String nickname) throws TokenException, InvalidKeyException { // only delete this symmetric key if it exists if( uniqueNamedKeyExists(nickname) ) { deleteKey(lookupUniqueNamedKey(Encryptor.DEFAULT_ENCRYPTION_ALG, nickname)); } } /** * Deletes this key from this token. * @throws InvalidKeyException If the key does not reside on this token, * or is not a JSS key. */ public void deleteKey(SecretKey key) throws TokenException, InvalidKeyException { if( key == null ) { throw new NullPointerException(); } if( ! (key instanceof SecretKeyFacade) ) { throw new InvalidKeyException("Key must be a JSS key"); } deleteKeyNative(token, ((SecretKeyFacade)key).key); } private native void deleteKeyNative(CryptoToken token, SymmetricKey key) throws TokenException; } jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/Makefile000066400000000000000000000035451326145000000231460ustar00rootroot00000000000000#! gmake # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/config.mk000066400000000000000000000004201326145000000232710ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/manifest.mn000066400000000000000000000006161326145000000236440ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 REQUIRES = nspr20 nss PACKAGE = org/mozilla/jss/SecretDecoderRing CSRCS = KeyManager.c \ $(NULL) LIBRARY_NAME = jsssdr jss-4.4.3/jss/org/mozilla/jss/SecretDecoderRing/package.html000066400000000000000000000010511326145000000237550ustar00rootroot00000000000000 A facility for encrypting and decrypting small amounts of data with a symmetric key. This is most commonly used for encrypting password files to implement single sign-on.

KeyManager is used to create, lookup, and delete the symmetric keys used for SecretDecoderRing. Encryptor is used to encrypt data. Decryptor is used to decrypt data that was previously encrypted with Encryptor. Encoding and Encoding.Template are used internally, but they were made public because they may occasionally be useful to applications. jss-4.4.3/jss/org/mozilla/jss/asn1/000077500000000000000000000000001326145000000170065ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/asn1/ANY.java000066400000000000000000000204071326145000000203030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import org.mozilla.jss.util.Assert; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; /** * Represents an ASN.1 ANY value. An ANY is just an arbitrary * ASN.1 value. It can be thought of as the simplest implementation of the * ASN1Value interface. Although they can be created * from scratch (from raw BER), instances of ANY are usually * found after decoding * with a template that has an ANY field. * *

An ANY supports extracting the BER encoding, or decoding * with a different template. */ public class ANY implements ASN1Value { private ANY() { } // The complete encoding of header + contents private byte[] encoded; private Tag tag; /** * Creates an ANY value, which is just a generic ASN.1 value. * This method is provided for efficiency if the tag is already known, * so that we don't have to parse the encoding for it. * @param tag The tag of this value. It must be the same as the actual tag * contained in the encoding. * @param encoded The complete BER encoding of this value, including * tag, form, length, and contents. */ public ANY(Tag tag, byte[] encoded) { this.encoded = encoded; this.tag = tag; } /** * Creates an ANY value, which is just a generic ASN.1 value. * @param encoded The complete BER encoding of this value, including * tag, form, length, and contents. */ public ANY(byte[] encoded) throws InvalidBERException { try { this.encoded = encoded; ByteArrayInputStream bis = new ByteArrayInputStream(encoded); ASN1Header head = new ASN1Header(bis); this.tag = head.getTag(); } catch(IOException e) { throw new org.mozilla.jss.util.AssertionException( "IOException while creating ANY: "+e); } } /** * Returns the tag of this value. */ public Tag getTag() { return tag; } /** * Returns the complete encoding of header and contents, as passed into * the constructor or read from a BER input stream. */ public byte[] getEncoded() { return encoded; } /** * Returns the ASN.1 header from the encoding. */ public ASN1Header getHeader() throws InvalidBERException, IOException { if( header == null ) { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); header = new ASN1Header(bis); } return header; } private ASN1Header header=null; /** * Strips out the header and returns just the contents octets of the * encoding. */ private byte[] contents=null; public byte[] getContents() throws InvalidBERException { try { if( contents==null ) { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); header = new ASN1Header(bis); contents = new byte[ bis.available() ]; if( (contents.length != header.getContentLength()) && ( header.getContentLength() != -1 ) ) { throw new InvalidBERException("Length of contents was not the "+ "same as the header predicted"); } ASN1Util.readFully(contents, bis); } return contents; } catch( IOException e ) { Assert.notReached("IOException reading from byte array"); return null; } } public void encode(OutputStream ostream) throws IOException { ostream.write(encoded); } /** * Decodes this ANY using the given template. This is useful if you * originally decoded something as an ANY because you didn't know * what it was, but now you know what it is supposed to be. * * @param template The template to use to decode this ANY. * @return The output of the given template when it is fed the * encoding of this ANY. */ public ASN1Value decodeWith(ASN1Template template) throws InvalidBERException { try { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(bis); } catch( IOException e ) { Assert.notReached("IOException while reading from byte array input"+ " stream"); return null; } } /** * Decodes this ANY using the given template. This is useful if you * originally decoded something as an ANY because you didn't know * what it was, but now you know what it is supposed to be. * * @param implicitTag The implicit tag for the encoding. * @param template The template to use to decode this ANY. * @return The output of the given template when it is fed the * encoding of this ANY. */ public ASN1Value decodeWith(Tag implicitTag, ASN1Template template) throws IOException, InvalidBERException { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(implicitTag, bis); } /** * @param implicitTag This parameter is ignored, because * ANY values cannot have implicit tags. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { if( ! implicitTag.equals(tag) ) { Assert.notReached("No implicit tags allowed for ANY"); } ostream.write(encoded); } /** * Extracts the contents from the ANY and encodes them with * the provided tag. */ public void encodeWithAlternateTag(Tag alternateTag, OutputStream ostream) throws IOException, InvalidBERException { byte[] contents = getContents(); ASN1Header oldHead = getHeader(); Assert._assert( contents.length == oldHead.getContentLength() ); ASN1Header newHead = new ASN1Header( alternateTag, oldHead.getForm(), contents.length); newHead.encode(ostream); ostream.write(contents); } /** * Returns a singleton instance of a decoding template. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A class for decoding ANY values from BER. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return true; // wheeeeee...it's ANY! } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = ASN1Header.lookAhead(istream); if( head.getContentLength() == -1 ) { // indefinite length encoding ByteArrayOutputStream recording = new ByteArrayOutputStream(); // eat the header off the input stream head = new ASN1Header(istream); // write the header to the recording stream recording.write( head.encode() ); // write all objects from the input stream to the recording // stream, until we hit an END-OF-CONTENTS tag ANY any; ANY.Template anyt = new ANY.Template(); int count=0; do { any = (ANY) anyt.decode(istream); recording.write( any.getEncoded() ); } while( ! any.getTag().equals(Tag.EOC) ); return new ANY( head.getTag(), recording.toByteArray() ); } else { // definite length encoding byte[] data = new byte[ (int) head.getTotalLength() ]; ASN1Util.readFully(data, istream); return new ANY(head.getTag(), data); } } catch( InvalidBERException e ) { throw new InvalidBERException(e, "ANY"); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { throw new InvalidBERException("Implicit tag on ANY"); } } // End of Template } jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Header.java000066400000000000000000000274411326145000000214740ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.math.BigInteger; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.util.Vector; import org.mozilla.jss.util.Assert; /** * The portion of a BER encoding that precedes the contents octets. Consists * of the tag, form, and length octets. */ public class ASN1Header { // This is set by the the decoding constructor, and by the encode() // method. If it is set by the decoding constructor, it is supposed // to represent what was actually read from the input stream, so it // must not be overwritten later by the output of encode(), which could // be a different encoding (DER vs. BER, for example). private byte[] cachedEncoding = null; /** * Returns the length of the header plus the length of the contents; * the total length of the DER encoding of an ASN1 value. Returns * -1 if indefinite length encoding was used. */ public long getTotalLength() { if( contentLength == -1 ) { return -1; } else { return encode().length + contentLength; } } private Tag tag; public Tag getTag() { return tag; } // -1 means indefinite length encoding private long contentLength; /** * Returns -1 for indefinite length encoding. */ public long getContentLength() { return contentLength; } // PRIMITIVE or CONSTRUCTED public static final Form PRIMITIVE = Form.PRIMITIVE; public static final Form CONSTRUCTED = Form.CONSTRUCTED; private Form form; /** * Returns the Form, PRIMITIVE or CONSTRUCTED. */ public Form getForm() { return form; } // This is the maximum size of ASN1 Header we support. // 32 bytes is pretty huge, I've never seen anything bigger than 7. private static final int MAX_LOOK_AHEAD = 32; /** * Returns information about the next item in the stream, but does not * consume any octets. * @exception IOException If the input stream does not support look ahead. */ public static ASN1Header lookAhead(InputStream derStream) throws IOException, InvalidBERException { if( ! derStream.markSupported() ) { throw new IOException("Mark not supported on this input stream"); } derStream.mark(MAX_LOOK_AHEAD); ASN1Header info = new ASN1Header(derStream); derStream.reset(); return info; } /** * Gets info about the next item in the DER stream, consuming the * identifier and length octets. */ public ASN1Header(InputStream istream) throws InvalidBERException, IOException { // default BAOS size is 32 bytes, which is plenty ByteArrayOutputStream encoding = new ByteArrayOutputStream(); int inInt = istream.read(); if( inInt == -1 ) { throw new InvalidBERException("End-of-file reached while "+ "decoding ASN.1 header"); } encoding.write(inInt); byte byte1 = (byte) inInt; Tag.Class tagClass; // // Get Tag Class // tagClass = Tag.Class.fromInt( (byte1 & 0xff) >>> 6 ); // // Get form // if( (byte1 & 0x20) == 0x20 ) { form = CONSTRUCTED; } else { form = PRIMITIVE; } // // Get Tag Number // long tagNum; if( (byte1 & 0x1f) == 0x1f ) { // long form // // read all octets into a Vector of Bytes // byte next; Vector bV = new Vector(); // last byte has MSB == 0. do { inInt = istream.read(); if( inInt == -1 ) { throw new InvalidBERException("End-of-file reached while" +" decoding ASN.1 header"); } encoding.write(inInt); next = (byte) inInt; bV.addElement( new Byte(next) ); } while( (next & 0x80) == 0x80 ); Assert._assert( bV.size() > 0 ); // // Copy Vector of 7-bit bytes into array of 8-bit bytes. // byte[] bA = new byte[ ( (bV.size()*7) + 7 ) / 8 ]; int v; // vector index int a; // array index // clear the target array for( a = 0; a < bA.length; a++ ) { bA[a] = 0; } int shift = 0; // the amount the Vector is shifted from the array // copy bits from the Vector to the array, going from the // end (LSB) to the beginning (MSB). a = bA.length - 1; for( v=bV.size()-1 ; v >= 0; v--) { Assert._assert( v >= 0 ); Assert._assert( v < bV.size() ); Assert._assert( a >= 0 ); Assert._assert( a < bA.length ); // MSB is not part of the number byte b = (byte) ( ((Byte)bV.elementAt(v)).byteValue() & 0x7f ); bA[a] |= b << shift; if( shift > 1 ) { // The byte from the Vector falls across a byte boundary // in the array. We've already got the less-significant // bits, now copy the more-significant bits into // the next element of the array. Assert._assert( a > 0 ); --a; bA[a] |= b >>> (8-shift); } shift = (shift+7)%8; // update shift } // Create a new unsigned BigInteger from the byte array tagNum = (new BigInteger( 1, bA )).longValue(); } else { // short form tagNum = byte1 & 0x1f; } tag = new Tag(tagClass, tagNum); // // Get Length // inInt = istream.read(); if(inInt == -1) { throw new InvalidBERException("End-of-file reached while "+ "decoding ASN.1 header"); } encoding.write(inInt); byte lenByte = (byte) inInt; if( (lenByte & 0x80) == 0 ) { // short form contentLength = lenByte; } else { // long form if( (lenByte & 0x7f) == 0 ) { // indefinite contentLength = -1; } else { // definite byte[] lenBytes = new byte[ lenByte & 0x7f ]; ASN1Util.readFully(lenBytes, istream); encoding.write( lenBytes ); contentLength = (new BigInteger( 1, lenBytes )).longValue(); } } // save our encoding so we don't have to recompute it later cachedEncoding = encoding.toByteArray(); } /** * This constructor is to be called when we are constructing an ASN1Value * rather than decoding it. * @param contentLength Must be ≥0. Although indefinite length * decoding is supported, indefinite length encoding * is not. */ public ASN1Header( Tag tag, Form form, long contentLength) { this.tag = tag; this.form = form; Assert._assert(contentLength >= 0); this.contentLength = contentLength; } public void encode( OutputStream ostream ) throws IOException { ostream.write( encode() ); } public byte[] encode() { // It's important that we not recompute the encoding if it was // set by ASN1Header(InputStream), since in that case it represents // the encoding that was actually read from the InputStream. if( cachedEncoding != null ) { return cachedEncoding; } ByteArrayOutputStream cache = new ByteArrayOutputStream(); // // Identifier octet(s) // byte idOctet = 0; idOctet |= tag.getTagClass().toInt() << 6; if( form == CONSTRUCTED ) { idOctet |= 0x20; } if( tag.getNum() <= 30 ) { // short form idOctet |= (tag.getNum() & 0x1f ); cache.write( idOctet ); } else { // long form idOctet |= 0x1f; BigInteger tagNum = BigInteger.valueOf(tag.getNum()); cache.write( idOctet ); int bitlength = tagNum.bitLength(); int reps = (bitlength+6)/7; for( reps = reps-1; reps > 0 ; reps--) { long shifted = tag.getNum() >>> ( 7*reps ); cache.write( (((byte)shifted) & 0x7f) | 0x80 ); } cache.write( ((byte)tag.getNum()) & 0x7f ); } // // Length Octets // if( contentLength == -1 ) { // indefinite form cache.write( (byte) 0x80 ); } else if( contentLength <= 127 ) { // short form cache.write( (byte) contentLength ); } else { // long form byte[] val = unsignedBigIntToByteArray( BigInteger.valueOf(contentLength) ); cache.write( ((byte)val.length) | 0x80 ); cache.write( val, 0, val.length ); } cachedEncoding = cache.toByteArray(); return cachedEncoding; } /** * Converts an unsigned BigInteger to a minimal-length byte array. * This is necessary because BigInteger.toByteArray() attaches an extra * sign bit, which could cause the size of the byte representation to * be bumped up by an extra byte. */ public static byte[] unsignedBigIntToByteArray(BigInteger bi) { // make sure it is not negative Assert._assert( bi.compareTo(BigInteger.valueOf(0)) != -1 ); // find minimal number of bytes to hold this value int bitlen = bi.bitLength(); // minimal number of bits, without sign int bytelen; if( bitlen == 0 ) { // special case, since bitLength() returns 0 bytelen = 1; } else { bytelen = (bitlen + 7) / 8; } byte[] withSign = bi.toByteArray(); if( bytelen == withSign.length ) { return withSign; } else { // trim off extra byte at the beginning Assert._assert( bytelen == withSign.length - 1 ); Assert._assert( withSign[0] == 0 ); byte[] without = new byte[bytelen]; System.arraycopy(withSign,1, without, 0, bytelen); return without; } } /** * Verifies that this header has the given tag and form. * @exception InvalidBERException If the header's tag or form * differ from those passed in. */ public void validate(Tag expectedTag, Form expectedForm) throws InvalidBERException { validate(expectedTag); if( getForm() != expectedForm ) { throw new InvalidBERException("Incorrect form: expected ["+ expectedForm+"], found ["+getForm()); } } /** * Verifies that this head has the given tag. * @exception InvalidBERException If the header's tag differs from that * passed in. */ public void validate(Tag expectedTag) throws InvalidBERException { if( ! getTag().equals( expectedTag ) ) { throw new InvalidBERException("Incorrect tag: expected ["+ expectedTag+"], found ["+getTag()+"]"); } } /** * Returns true if this is a BER end-of-contents marker. */ public boolean isEOC() { return( tag.equals(Tag.EOC) ); } } jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Template.java000066400000000000000000000030741326145000000220530ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.OutputStream; import java.io.InputStream; import java.io.IOException; /** * An interface for decoding ASN1Values from their BER encodings. * * @see ASN1Value */ public interface ASN1Template { /** * Determines whether the given tag will satisfy this template. */ public boolean tagMatch(Tag tag); /** * Decodes an ASN1Value from the InputStream without an implicit tag. * @param istream Must support marking (markSupported() == true). * For example, ByteArrayInputStream and BufferedInputStream * support marking, but FileInputStream does not. If your source * does not support marking, you can wrap it in a * BufferedInputStream. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException; /** * Decodes an ASN1Value from the InputStream with the given implicit * tag. * @param istream Must support marking (markSupported() == true). * For example, ByteArrayInputStream and BufferedInputStream * support marking, but FileInputStream does not. If your source * does not support marking, you can wrap it in a * BufferedInputStream. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException; } jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Util.c000066400000000000000000000071231326145000000205150ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "_jni/org_mozilla_jss_asn1_ASN1Util.h" #include #include #include #include #include #include #include #include #include /*********************************************************************** * * Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid * retrieves OID description by NSS's OID Tag identifier * the OID byte array is expected to be without the OID Tag (6) and size * (together 2 bytes) */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid(JNIEnv *env, jobject this, jbyteArray oidBA) { SECItem *oid = NULL; SECOidTag oidTag = SEC_OID_UNKNOWN; const char *oidDesc = NULL; jstring description = (jstring)""; if (oidBA == NULL) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "JSS getTagDescriptionByOid: oidBA null"); goto finish; } else { /************************************************** * Setup the parameters *************************************************/ oid = JSS_ByteArrayToSECItem(env, oidBA); if (oid == NULL) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "JSS getTagDescriptionByOid: JSS_ByteArrayToSECItem failed"); goto finish; } /* * SECOID_FindOIDTag() returns SEC_OID_UNKNOWN if no match */ oidTag = SECOID_FindOIDTag(oid); if (oidTag == SEC_OID_UNKNOWN) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "JSS getTagDescriptionByOid: OID UNKNOWN"); goto finish; } oidDesc = SECOID_FindOIDTagDescription(oidTag); if (oidDesc == NULL) { oidDesc = ""; } description = (*env)->NewStringUTF(env, oidDesc); } finish: return description; } jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Util.java000066400000000000000000000115421326145000000212140ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.*; import java.util.Arrays; import org.mozilla.jss.asn1.InvalidBERException; import org.mozilla.jss.util.Assert; public class ASN1Util { public static byte[] encode(ASN1Value val) { return encode(val.getTag(), val); } public static byte[] encode(Tag implicitTag, ASN1Value val) { try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); val.encode(implicitTag, bos); return bos.toByteArray(); } catch( IOException e ) { Assert.notReached("Encoding to byte array gave IOException"); return null; } } public static ASN1Value decode(ASN1Template template, byte[] encoded) throws InvalidBERException { try { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(bis); } catch( IOException e ) { Assert.notReached("Decoding from byte array gave IOException"); return null; } } public static ASN1Value decode(Tag implicitTag, ASN1Template template, byte[] encoded) throws InvalidBERException { try { ByteArrayInputStream bis = new ByteArrayInputStream(encoded); return template.decode(implicitTag, bis); } catch( IOException e ) { Assert.notReached("Decoding from byte array gave IOException"); return null; } } /** * Fills a byte array with bytes from an input stream. This method * keeps reading until the array is filled, an IOException occurs, or EOF * is reached. The byte array will be completely filled unless an * exception is thrown. * * @param bytes A byte array which will be filled up. * @param istream The input stream from which to read the bytes. * @exception IOException If an IOException occurs reading from the * stream, or EOF is reached before the byte array is filled. */ public static void readFully(byte[] bytes, InputStream istream) throws IOException { int numRead=0; while(numRead < bytes.length) { int nr = istream.read(bytes, numRead, bytes.length-numRead); if( nr == -1 ) { throw new EOFException(); } numRead += nr; } } /** * returns the ECC curve byte array given the X509 public key byte array * * @param X509PubKeyBytes byte array of an X509PubKey * @param withHeader tells if the return byes should inclulde the tag and size header or not */ public static byte[] getECCurveBytesByX509PublicKeyBytes(byte[] X509PubKeyBytes, boolean withHeader) throws IllegalArgumentException, ArrayIndexOutOfBoundsException, NullPointerException { if ((X509PubKeyBytes == null) || (X509PubKeyBytes.length == 0)) { throw new IllegalArgumentException("X509PubKeyBytes null"); } /* EC public key OID complete with tag and size */ byte[] EC_PubOIDBytes_full = ASN1Util.encode(OBJECT_IDENTIFIER.EC_PUBKEY_OID); /* EC public key OID without tag and size */ byte[] EC_PubOIDBytes = Arrays.copyOfRange(EC_PubOIDBytes_full, 2, EC_PubOIDBytes_full.length); int curveBeginIndex = 0; for (int idx = 0; idx<= X509PubKeyBytes.length; idx++) { byte[] tmp = Arrays.copyOfRange(X509PubKeyBytes, idx, idx+EC_PubOIDBytes.length); if (Arrays.equals(tmp, EC_PubOIDBytes)) { curveBeginIndex = idx+ EC_PubOIDBytes.length; break; } } int curveByteArraySize = (int) X509PubKeyBytes[curveBeginIndex+ 1]; if (withHeader) { /* actual curve with tag and size */ byte curve[] = Arrays.copyOfRange(X509PubKeyBytes, curveBeginIndex, curveBeginIndex + curveByteArraySize + 2); return curve; } else { /* actual curve without tag and size */ byte curve[] = Arrays.copyOfRange(X509PubKeyBytes, curveBeginIndex + 2, curveBeginIndex + 2 + curveByteArraySize); return curve; } } /** * getOIDdescription() returns a text description of the OID * from OID byte array * the OID byte array is expected to be without the OID Tag (6) and size * (together 2 bytes) */ public static String getOIDdescription(byte[] oidBA) { return getTagDescriptionByOid(oidBA); } /** * get OID description JNI method */ private native static String getTagDescriptionByOid(byte[] oidBA); } jss-4.4.3/jss/org/mozilla/jss/asn1/ASN1Value.java000066400000000000000000000016251326145000000213540ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.OutputStream; import java.io.IOException; /** * A value that can be decoded from BER and encoded to DER. * * @see ASN1Template */ public interface ASN1Value { /** * Returns the base tag for this type, not counting any tags * that may be imposed on it by its context. */ public Tag getTag(); /** * Write this value's DER encoding to an output stream using * its own base tag. */ public void encode(OutputStream ostream) throws IOException; /** * Write this value's DER encoding to an output stream using * an implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException; } jss-4.4.3/jss/org/mozilla/jss/asn1/BIT_STRING.java000066400000000000000000000226471326145000000213700ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.util.BitSet; /** * An ASN.1 BIT STRING, which is an ordered sequence of bits. * The bits are stored the same way they are encoded in BER: as an array * of bytes with 0-7 unused bits at the end. */ public class BIT_STRING implements ASN1Value { private BIT_STRING() { } private byte[] bits; private int padCount; private boolean removeTrailingZeroes = false; /** * @param bits The bits packed into an array of bytes, with padding * at the end. The array may be empty (but not null), in which case * padCount must be zero. The array is referenced, * not cloned. * @param padCount The number of padding bits at the end of the array. * Must be in the range [0,7]. * @exception NumberFormatException If padCount is not in * the range [0,7], or bits is * empty and padCount is non-zero. */ public BIT_STRING(byte[] bits, int padCount) throws NumberFormatException { if(padCount < 0 || padCount > 7) { throw new NumberFormatException(); } if(bits.length == 0 && padCount != 0) { throw new NumberFormatException(); } this.bits = bits; this.padCount = padCount; } /** * Constructs a BIT_STRING from a BitSet. * @param bs A BitSet. * @param numBits The number of bits to copy from the BitSet. * This is necessary because the size of a BitSet is always padded * up to a multiple of 64, but not all of these bits may * be significant. * @exception NumberFormatException If numBits is larger * than bs.size() or less than zero. */ public BIT_STRING(BitSet bs, int numBits) throws NumberFormatException { if( numBits < 0 || numBits > bs.size() ) { throw new NumberFormatException(); } // allocate enough bytes to hold all the bits bits = new byte[(numBits+7) / 8]; padCount = (bits.length * 8) - numBits; Assert._assert( padCount >= 0 && padCount <= 7); for(int i=0; i < numBits; i++) { if( bs.get(i) ) { bits[i/8] |= 0x80 >>> (i%8); } } } /** * Determines whether the DER-encoding of this bitstring will have * its trailing zeroes removed. Generally, DER requires that trailing * zeroes be removed when the bitstring is used to hold flags, but * not when it is used to hold binary data (such as a public key). * The default is false. */ public boolean getRemoveTrailingZeroes() { return this.removeTrailingZeroes; } /** * Determines whether the DER-encoding of this bitstring will have * its trailing zeroes removed. Generally, DER requires that trailing * zeroes be removed when the bitstring is used to hold flags, but * not when it is used to hold binary data (such as a public key). * The default is false. If this bit string is used to hold * flags, you should set this to true. */ public void setRemoveTrailingZeroes(boolean removeTrailingZeroes) { this.removeTrailingZeroes = removeTrailingZeroes; } /** * Returns the bits packed into an array of bytes, with padding * at the end. The array may be empty (but not null), in which case * padCount must be zero. The array is referenced, * not cloned. */ public byte[] getBits() { return bits; } /** * Copies this BIT STRING into a Java BitSet. Note that BitSet.size() * will not accurately reflect the number of bits in the BIT STRING, * because the size of a BitSet is always rounded up to the next multiple * of 64. The extra bits will be set to 0. */ public BitSet toBitSet() { BitSet bs = new BitSet(); int numBits = (bits.length * 8) - padCount; for( int i=0; i < numBits; i++) { if( (bits[i/8] & (0x80 >>> (i%8))) != 0 ) { bs.set(i); } else { bs.clear(i); } } return bs; } /** * Copies this BIT STRING into a boolean array. Each element of the array * represents one bit with true for 1 and false * for 0. */ public boolean[] toBooleanArray() { boolean[] array = new boolean[(bits.length*8) - padCount]; // all elements are set to false by default for(int i=0; i < array.length; i++) { if( (bits[i/8] & (0x80 >>> (i%8))) != 0 ) { array[i] = true; } } return array; } /** * Returns the number of padding bits at the end of the array. * Must be in the range [0,7]. */ public int getPadCount() { return padCount; } public static final Tag TAG = new Tag(Tag.UNIVERSAL, 3); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // force all unused bits to be zero, in support of DER standard. if( bits.length > 0 ) { bits[bits.length-1] &= (0xff << padCount); } int padBits; int numBytes; if( removeTrailingZeroes ) { // first pare off empty bytes numBytes = bits.length; for( ; numBytes > 0; --numBytes) { if( bits[numBytes-1] != 0 ) { break; } } // Now compute the number of unused bits. This includes any // trailing zeroes, whether they are significant or not. if( numBytes == 0 ) { padBits = 0; } else { for( padBits=0; padBits < 8; ++padBits ) { if( (bits[numBytes-1] & (1 << padBits)) != 0 ) { break; } } Assert._assert(padBits >=0 && padBits <= 7); } } else { // Don't remove trailing zeroes. Just write the bits out as-is. padBits = padCount; numBytes = bits.length; } ASN1Header head = new ASN1Header(implicitTag, FORM, numBytes+1); head.encode(ostream); ostream.write(padBits); ostream.write(bits, 0, numBytes); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding a BIT_STRING from its BER encoding. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return( TAG.equals(tag) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header( istream ); head.validate( implicitTag ); if( head.getContentLength() == -1 ) { // indefinite length encoding ByteArrayOutputStream bos = new ByteArrayOutputStream(); int padCount=0; ASN1Header ahead; do { ahead = ASN1Header.lookAhead(istream); if( ! ahead.isEOC() ) { if(padCount != 0 ) { throw new InvalidBERException("Element of constructed "+ "BIT STRING has nonzero unused bits, but is not\n"+ "the last element of the construction."); } BIT_STRING.Template bst = new BIT_STRING.Template(); BIT_STRING bs = (BIT_STRING) bst.decode(istream); bos.write( bs.getBits() ); padCount = bs.getPadCount(); } } while( ! ahead.isEOC() ); // consume the EOC ahead = new ASN1Header(istream); return new BIT_STRING( bos.toByteArray(), padCount ); } // First octet is the number of unused bits in last octet int padCount = istream.read(); if( padCount == -1 ) { throw new InvalidBERException.EOF(); } else if( padCount < 0 || padCount > 7 ) { throw new InvalidBERException("Unused bits not in range [0,7]"); } // get the rest of the octets byte[] bits = new byte[ (int) head.getContentLength() - 1]; ASN1Util.readFully(bits, istream); return new BIT_STRING(bits, padCount); } catch(InvalidBERException e) { throw new InvalidBERException(e, "BIT STRING"); } } } // end of Template } jss-4.4.3/jss/org/mozilla/jss/asn1/BMPString.java000066400000000000000000000063341326145000000214640ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; import java.io.UnsupportedEncodingException; import org.mozilla.jss.util.Assert; /** * The ASN.1 type BMPString. BMPStrings use the Unicode character set. * They are encoded and decoded in big-endian format using two octets. */ public class BMPString extends CharacterString implements ASN1Value { /** * Creates a new BMPString from an array of Java characters. */ public BMPString(char[] chars) throws CharConversionException { super(chars); } /** * Creates a new BMPString from a Java String. */ public BMPString(String s) throws CharConversionException { super(s); } /** * Returns the conversion object for converting between an encoded byte * array an an array of Java characters. */ CharConverter getCharConverter() { return converterInstance; } private static final BMPConverter converterInstance = new BMPConverter(); static final Tag TAG = new Tag( Tag.UNIVERSAL, 30 ); static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } /** * Returns a singleton instance of BMPString.Template. This is more * efficient than creating a new BMPString.Template. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new BMPConverter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new BMPString(chars); } protected String typeName() { return "BMPString"; } } private static class BMPConverter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { try { String s = new String(bytes, offset, len, "UnicodeBig"); return s.toCharArray(); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UnicodeBig encoding mechanism"; Assert.notReached(err); throw new CharConversionException(err); } } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { try { // We don't want the byte-order mark String s = new String(chars, offset, len); return s.getBytes("UnicodeBigUnmarked"); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UnicodeBigUnmarked encoding mechanism"; Assert.notReached(err); throw new CharConversionException(err); } } } // end of char converter } jss-4.4.3/jss/org/mozilla/jss/asn1/BOOLEAN.java000066400000000000000000000056241326145000000207370ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.OutputStream; import java.io.IOException; import java.io.InputStream; /** * An ASN.1 BOOLEAN value. */ public class BOOLEAN implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 1); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } private ASN1Header getHeader() { return getHeader(TAG); } private ASN1Header getHeader(Tag implicitTag) { return new ASN1Header(implicitTag, FORM, 1 ); } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { getHeader(implicitTag).encode(ostream); if( val ) { ostream.write( 0xff ); } else { ostream.write( 0x00 ); } } private BOOLEAN() { } private boolean val; /** * Creates a BOOLEAN with the given value. */ public BOOLEAN(boolean val) { this.val = val; } /** * Returns the boolean value of this BOOLEAN. */ public boolean toBoolean() { return val; } /** * Returns "true" or "false". */ public String toString() { if(val) { return "true"; } else { return "false"; } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Class for decoding BOOLEAN values from their BER * encodings. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return( tag.equals( BOOLEAN.TAG ) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag tag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(tag, FORM); int b = istream.read(); if( b == -1 ) { throw new InvalidBERException("End-of-file reached while "+ "decoding BOOLEAN"); } if( b == 0x00 ) { return new BOOLEAN(false); } else { return new BOOLEAN(true); } } catch(InvalidBERException e) { throw new InvalidBERException(e, "BOOLEAN"); } } } } jss-4.4.3/jss/org/mozilla/jss/asn1/CHOICE.java000066400000000000000000000167431326145000000206160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.mozilla.jss.util.Assert; /** * Objects of this class are generated by CHOICE.Template.decode(). It is * not necessary to use them to encode a CHOICE. Since the encoding of a * CHOICE is simply the encoding of the chosen element, it is easier * to just write out the chosen element. */ public class CHOICE implements ASN1Value { private CHOICE() { } private Tag tag; private ASN1Value val; /** * Create a CHOICE whose chosen element has an implicit tag. */ public CHOICE(Tag implicitTag, ASN1Value val) { tag = implicitTag; this.val = val; } /** * Create a CHOICE whose chosen element has no implicit tag. */ public CHOICE(ASN1Value val) { this.tag = val.getTag(); this.val = val; } /** * Returns the tag that the chosen element is encoded with, which is * either the underlying tag of the element or an implicit tag. */ public Tag getTag() { return tag; } /** * Returns the chosen value. */ public ASN1Value getValue() { return val; } public static CHOICE.Template getTemplate() { return new CHOICE.Template(); } /** * Encodes this CHOICE. This merely consists of encoding the chosen * element with an implicit tag, if one was given in the constructor, * or with its own underlying tag. */ public void encode( OutputStream ostream ) throws IOException { val.encode( tag, ostream ); } /** * Encodes this CHOICE. This merely consists of encoding the chosen * element with an implicit tag, if one was given in the constructor, * or with its own underlying tag. * * @param implicitTag This value is ignored. The tag of a CHOICE * is merely the tag of the chosen element of the CHOICE. A * CHOICE cannot itself have an implicit tag. */ public void encode( Tag implicitTag, OutputStream ostream ) throws IOException { Assert._assert(implicitTag.equals(tag)); val.encode( tag, ostream ); } /** * A Template for decoding ASN.1 CHOICEs */ public static class Template implements ASN1Template { // The the various possibilities in this CHOICE private Vector templates = new Vector(); /** * Creates an empty CHOICE template */ public Template() { } /** * Adds a new sub-template to this CHOICE template with no implicit tag. */ public void addElement( ASN1Template template ) { templates.addElement( new Element( template ) ); } /** * Adds a new sub-template to this CHOICE template with an implicit tag. */ public void addElement( Tag implicitTag, ASN1Template template) { templates.addElement( new Element( implicitTag, template) ); } /** * Returns the number of elements in this CHOICE template. */ public int size() { return templates.size(); } /** * Retrieves the element at the specified index. */ public ASN1Template elementAt(int index) { return ((Element)templates.elementAt(index)).getTemplate(); } /** * Retrieves the implicit tag of the element at the specified index. * Returns null if there is no implicit tag for this element. */ public Tag implicitTagAt(int index) { return ((Element)templates.elementAt(index)).getImplicitTag(); } /** * Empties this CHOICE template. */ public void removeAllElements() { templates.removeAllElements(); } /** * Removes the element at the specified index. */ public void removeElementAt(int index) { templates.removeElementAt(index); } /** * Determines whether the given tag will satisfy this template. * For a CHOICE, this is true if the tag satisfies any sub-template. */ public boolean tagMatch(Tag t) { int size = size(); for(int i = 0; i < size; i++) { Tag impl = implicitTagAt(i); if( impl != null ) { // There is an implicit tag, if we match it we have a match if( impl.equals(t) ) { return true; } } else { // no implicit tag, look at the sub-template itself ASN1Template templ = elementAt(i); if( templ.tagMatch(t) ) { return true; } } } // none of the elements matched return false; } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { ASN1Header head = ASN1Header.lookAhead(istream); Tag tag = head.getTag(); // Loop over all the elements of the CHOICE template until we // find one with a matching tag. int size = size(); for(int i=0; i < size; i++) { if( implicitTagAt(i) != null ) { if( implicitTagAt(i).equals(tag) ) { // match by implicit tag! ASN1Value val = elementAt(i).decode( implicitTagAt(i), istream ); //return elementAt(i).decode( implicitTagAt(i), istream ); return new CHOICE( implicitTagAt(i), val ); } } else { if( elementAt(i).tagMatch(tag) ) { // match by base tag ! //return elementAt(i).decode(istream); return new CHOICE( elementAt(i).decode(istream) ); } } } // we didn't find any match throw new InvalidBERException("Unable to decode CHOICE"); } // Implicit tags are illegal for CHOICE (and ANY) /** * Decodes a CHOICE. * @param implicitTag This parameter is ignored. A choice * cannot have an implicit tag. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return decode(istream); } /** * An element in a CHOICE template, consisting of a nested template * and, optionally, an implicit tag for that template. */ private static class Element { private ASN1Template template; private Tag implicitTag=null; /** * Creates a CHOICE template element with no implicit tag. */ public Element(ASN1Template template) { this.template = template; } /** * Creates a CHOICE template element with an implicit tag. */ public Element(Tag implicitTag, ASN1Template template) { this.template = template; this.implicitTag = implicitTag; } /** * Returns the template of this CHOICE template element. */ public ASN1Template getTemplate() { return template; } /** * Returns the implicit tag for this CHOICE template element, * if there is one. If not, returns null. */ public Tag getImplicitTag() { return implicitTag; } } } } jss-4.4.3/jss/org/mozilla/jss/asn1/CharConverter.java000066400000000000000000000007701326145000000224220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; interface CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException; public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException; } jss-4.4.3/jss/org/mozilla/jss/asn1/CharacterString.java000066400000000000000000000105411326145000000227350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.ByteArrayOutputStream; /** * An abstract base class for all character string types in ASN.1. */ public abstract class CharacterString implements ASN1Value { abstract CharConverter getCharConverter(); public abstract Tag getTag(); static final Form FORM = Form.PRIMITIVE; private char[] chars; /** * Converts this ASN.1 character string to a Java String. */ public String toString() { return new String(chars); } /** * Converts this ASN.1 character string to an array of Java characters. */ public char[] toCharArray() { return chars; } protected CharacterString(char[] chars) throws CharConversionException { this.chars = chars; cachedContents = computeContents(); } protected CharacterString(String s) throws CharConversionException { this.chars = s.toCharArray(); cachedContents = computeContents(); } private byte[] cachedContents; private byte[] getEncodedContents() { return cachedContents; } private byte[] computeContents() throws CharConversionException { CharConverter converter = getCharConverter(); byte[] contents = converter.charToByte(chars, 0, chars.length); return contents; } public void encode(OutputStream ostream) throws IOException { encode( getTag(), ostream ); } public void encode( Tag implicitTag, OutputStream ostream ) throws IOException { byte[] contents = getEncodedContents(); ASN1Header head = new ASN1Header( implicitTag, FORM, contents.length); head.encode(ostream); ostream.write( contents ); } public abstract static class Template implements ASN1Template { /** * Must be overridden to return the tag for the subclass. */ protected abstract Tag getTag(); public abstract boolean tagMatch(Tag tag); /** * Must be overridden to return the correct character converter * for the subclass. */ protected abstract CharConverter getCharConverter(); /** * Must be overridden to create an instance of the subclass given * a char array. */ protected abstract CharacterString generateInstance(char[] chars) throws CharConversionException; /** * Must be overridden to provide the name of the subclass, for including * into error messages. */ protected abstract String typeName(); public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(implicitTag); byte[] raw; // raw bytes, not translated to chars yet if( head.getContentLength() == -1 ) { // indefinite length encoding ASN1Header ahead; ByteArrayOutputStream bos = new ByteArrayOutputStream(); do { ahead = ASN1Header.lookAhead( istream ); if( ! ahead.isEOC() ) { OCTET_STRING.Template ot = new OCTET_STRING.Template(); OCTET_STRING os = (OCTET_STRING) ot.decode(istream); bos.write( os.toByteArray() ); } } while( ! ahead.isEOC() ); // consume EOC ahead = new ASN1Header(istream); raw = bos.toByteArray(); } else { // definite length raw = new byte[ (int) head.getContentLength() ]; ASN1Util.readFully(raw, istream); } char[] chars = getCharConverter().byteToChar(raw, 0, raw.length); return generateInstance(chars); } catch( CharConversionException e ) { throw new InvalidBERException(e.getMessage()); } catch( InvalidBERException e ) { throw new InvalidBERException(e, typeName()); } } } } jss-4.4.3/jss/org/mozilla/jss/asn1/CountingStream.java000066400000000000000000000051741326145000000226220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.*; /** * This class keeps track of the number of bytes that have been read from * a stream. It will be incremented by the number of bytes read or skipped. * If the stream is marked and then reset, the number of bytes read will * be reset as well. */ class CountingStream extends InputStream { private int count=0; private int markpos; private InputStream source; private static final boolean DEBUG = false; private CountingStream() { } public CountingStream(InputStream source) { this.source = source; } public int available() throws IOException { return source.available(); } public void mark(int readlimit) { source.mark(readlimit); markpos = count; if(DEBUG) { System.out.println("Marked at position "+markpos); } } public boolean markSupported() { return source.markSupported(); } public int read() throws IOException { int n = source.read(); if( n != -1 ) { count++; if(DEBUG) { System.out.println("read() 1 byte, count="+count); } } return n; } public int read(byte[] buffer) throws IOException { int n = source.read(buffer); if( n != -1 ) { count += n; } if(DEBUG) { System.out.println("read([]) "+n+" bytes, count="+count); } return n; } public int read(byte[] buffer, int offset, int count) throws IOException { int n = source.read(buffer, offset, count); if( n != -1 ) { this.count += n; } if(DEBUG) { System.out.println("read(...) "+n+" bytes, count="+this.count); } return n; } public void reset() throws IOException { source.reset(); if(DEBUG) { System.out.println("reset from "+count+" to "+markpos); } count = markpos; } public long skip(long count) throws IOException { this.count += count; if(DEBUG) { System.out.println("skipped "+count+", now at "+this.count); } return source.skip(count); } public int getNumRead() { return count; } public void resetNumRead() { count = 0; markpos = 0; if(DEBUG) { System.out.println("resetting count to 0"); } } } jss-4.4.3/jss/org/mozilla/jss/asn1/ENUMERATED.java000066400000000000000000000043151326145000000213050ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.IOException; import java.io.InputStream; /** * Represents an ASN.1 ENUMERATED value. This has the same * interface as INTEGER */ public class ENUMERATED extends INTEGER implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 10); public Tag getTag() { return TAG; } /** * Creates a new ENUMERATED value from a long. */ public ENUMERATED( long val ) { super( val ); } ENUMERATED( byte[] valBytes ) { super( valBytes ); } /** * Returns the value as a long. */ public long getValue() { return longValue(); } private static final ENUMERATED.Template templateInstance = new ENUMERATED.Template(); public static ASN1Template getTemplate() { return templateInstance; } /** * A template for decoding ENUMERATED values from their BER encodings. * The template reads the value as an INTEGER. It does not check that it * is a valid value for the ENUMERATED type. */ public static class Template extends INTEGER.Template implements ASN1Template { Tag getTag() { return ENUMERATED.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(ENUMERATED.TAG) ); } public ASN1Value decode(Tag tag, InputStream derStream) throws InvalidBERException, IOException { try { ASN1Header wrapper = new ASN1Header(derStream); wrapper.validate(tag, FORM); // Is length < 1 ? if( wrapper.getContentLength() < 1 ) { throw new InvalidBERException("Invalid 0 length for ENUMERATED"); } byte[] valBytes = new byte[ (int) wrapper.getContentLength() ]; ASN1Util.readFully(valBytes, derStream); return new ENUMERATED( valBytes ); } catch(InvalidBERException e) { throw new InvalidBERException(e, "ENUMERATED"); } } } // end of Template } jss-4.4.3/jss/org/mozilla/jss/asn1/EXPLICIT.java000066400000000000000000000075141326145000000211010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import org.mozilla.jss.util.Assert; /** * An explicit tag. */ public class EXPLICIT implements ASN1Value { public static final Form FORM = Form.CONSTRUCTED; private ASN1Value content; private Tag tag; private EXPLICIT() { } /** * Creates an EXPLICIT tag wrapping some other ASN1Value. For example, * for the following ASN.1 snippet: *

     * MyType [3] EXPLICIT INTEGER
     * 
* assuming a sample value of 5 for the INTEGER, a MyType could be * created with: *
     *  EXPLICIT myValue = new EXPLICIT( new Tag(3), new INTEGER(5) );
     * 
*/ public EXPLICIT( Tag tag, ASN1Value content ) { Assert._assert(tag!=null && content!=null); this.content = content; this.tag = tag; } /** * Returns the ASN1Value that is wrapped by this EXPLICIT tag. */ public ASN1Value getContent() { return content; } /** * Returns the Tag of this EXPLICIT tag. */ public Tag getTag() { return tag; } public void encode(OutputStream ostream) throws IOException { encode(tag, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); content.encode(bos); byte[] contentBytes = bos.toByteArray(); ASN1Header head = new ASN1Header(implicitTag, FORM, contentBytes.length ); head.encode(ostream); ostream.write(contentBytes); } public static Template getTemplate( Tag tag, ASN1Template content) { return new Template(tag, content); } /** * A template for decoding an object wrapped in an EXPLICIT tag. */ public static class Template implements ASN1Template { private ASN1Template content; private Tag tag; private Template() { } /** * Creates a template for unwrapping an object wrapped in an explicit tag. * For example, to decode: *
     * MyValue ::= [3] EXPLICIT INTEGER
     * 
* use: *
     * EXPLICIT.Template myTemplate = new EXPLICIT.Template( new Tag(3),
     *      new INTEGER.Template() );
     * 
* * @param tag The tag value of the EXPLICIT tag. * @param content The template for decoding the object that is wrapped * in the explicit tag. */ public Template(Tag tag, ASN1Template content) { this.content = content; this.tag = tag; } public boolean tagMatch(Tag tag) { return( this.tag.equals(tag) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(tag, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate( implicitTag, FORM.CONSTRUCTED ); ASN1Value val = content.decode(istream); EXPLICIT e = new EXPLICIT(tag, val); // if indefinite content length, consume the end-of-content marker if( head.getContentLength() == -1 ) { head = new ASN1Header(istream); if( ! head.isEOC() ) { throw new InvalidBERException("No end-of-contents marker"); } } return e; } catch(InvalidBERException e) { throw new InvalidBERException(e, "EXPLICIT"); } } } // end of Template } jss-4.4.3/jss/org/mozilla/jss/asn1/FieldNotPresentException.java000066400000000000000000000010051326145000000245710ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; /** * An exception thrown when an optional field is not present. */ public class FieldNotPresentException extends java.lang.Exception { public FieldNotPresentException() { super(); } public FieldNotPresentException(String msg) { super(msg); } } jss-4.4.3/jss/org/mozilla/jss/asn1/Form.java000066400000000000000000000012601326145000000205530ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; /** * An enumerated type representing the forms of an ASN.1 value. * The possibilities are PRIMITIVE and CONSTRUCTED. */ public class Form { private String name; private Form() { } private Form(String name) { this.name = name; } public static final Form PRIMITIVE = new Form("PRIMITIVE"); public static final Form CONSTRUCTED = new Form("CONSTRUCTED"); public String toString() { return name; } } jss-4.4.3/jss/org/mozilla/jss/asn1/GeneralizedTime.java000066400000000000000000000031431326145000000227220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.mozilla.jss.util.Assert; /** * The ASN.1 type GeneralizedTime */ public class GeneralizedTime extends TimeBase implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 24); public Tag getTag() { return TAG; } /** * Creates a GeneralizedTime from a Date. */ public GeneralizedTime(Date date) { super(date); } protected boolean isUTC() { return false; } private static final GeneralizedTime.Template templateInstance = new GeneralizedTime.Template(); public static GeneralizedTime.Template getTemplate() { return templateInstance; } /** * A class for decoding GeneralizedTimes. */ public static class Template extends TimeBase.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected boolean isUTC() { return false; } protected TimeBase generateInstance(Date date) { return new GeneralizedTime(date); } } } jss-4.4.3/jss/org/mozilla/jss/asn1/IA5String.java000066400000000000000000000050071326145000000214200ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; public class IA5String extends CharacterString implements ASN1Value { public IA5String(char[] chars) throws CharConversionException { super(chars); } public IA5String(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new IA5Converter(); } public static final Tag TAG = new Tag( Tag.Class.UNIVERSAL, 22 ); public Tag getTag() { return TAG; } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { public Tag getTag() { return IA5String.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals( IA5String.TAG )); } protected CharConverter getCharConverter() { return new IA5Converter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new IA5String(chars); } protected String typeName() { return "IA5String"; } } // nested class private static class IA5Converter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { char[] chars = new char[len]; int c; // char index int b; // byte index for(b = offset, c=0; c < len; b++, c++) { if( (bytes[b] & 0x80) != 0 ) { throw new CharConversionException("Invalid character: "+ bytes[b]); } chars[c] = (char) (bytes[b] & 0x7f); } return chars; } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { byte[] bytes = new byte[len]; int c; // char index int b; // byte index for(c = offset, b = 0; b < len; c++, b++) { if( (chars[c] & 0x7f) != chars[c] ) { throw new CharConversionException("Invalid character: "+ chars[c]); } bytes[b] = (byte) (chars[c] & 0x7f); } return bytes; } } } jss-4.4.3/jss/org/mozilla/jss/asn1/INTEGER.java000066400000000000000000000141721326145000000207530ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.IOException; import java.io.OutputStream; import java.io.InputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.math.BigInteger; import java.util.Random; /** * The ASN.1 type INTEGER. This class extends BigInteger. */ public class INTEGER extends BigInteger implements ASN1Value { private byte[] encodedContents = null; private byte[] getEncodedContents() { if( encodedContents == null ) { encodedContents = toByteArray(); } return encodedContents; } private ASN1Header getHeader(Tag t) { return new ASN1Header( t, FORM, getContentLength() ); } public INTEGER(String s) throws NumberFormatException { super(s); } public INTEGER(String s, int r) throws NumberFormatException { super(s, r); } public INTEGER(byte[] bval) throws NumberFormatException { super(bval); } public INTEGER(int sign, byte[] mag) throws NumberFormatException { super(sign, mag); } public INTEGER(int numBits, Random rnd) throws NumberFormatException { super(numBits, rnd); } public INTEGER(int bitLength, int certainty, Random rnd) { super(bitLength, certainty, rnd); } public INTEGER(long val) { super( BigInteger.valueOf(val).toByteArray() ); } public INTEGER(BigInteger bi) { super( bi.toByteArray() ); } public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 2); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; public void encode(OutputStream outStream) throws IOException { encode(getTag(), outStream); } public void encode(Tag implicitTag, OutputStream outStream) throws IOException { // write header getHeader(implicitTag).encode( outStream ); // write contents outStream.write( getEncodedContents() ); } public long getContentLength() { return getEncodedContents().length; } public byte[] encode() throws IOException { ByteArrayOutputStream b = new ByteArrayOutputStream(); encode(b); return b.toByteArray(); } private static final INTEGER.Template templateInstance = new INTEGER.Template(); public static ASN1Template getTemplate() { return templateInstance; } /** * Tests the DER encoding and decoding of the INTEGER class. */ public static void main(String args[]) { try { int[] Is = new int[11]; int[][] Bs = new int[11][]; int i = 0; Is[i] = 0; Bs[i++] = new int[]{ 0x02, 0x01, 0x00 }; Is[i] = 1; Bs[i++] = new int[]{ 0x02, 0x01, 0x01 }; Is[i] = -1; Bs[i++] = new int[]{ 0x02, 0x01, 0xff }; Is[i] = 127; Bs[i++] = new int[]{ 0x02, 0x01, 0x7f }; Is[i] = 128; Bs[i++] = new int[]{ 0x02, 0x02, 0x00, 0x80 }; Is[i] = 255; Bs[i++] = new int[]{ 0x02, 0x02, 0x00, 0xff }; Is[i] = 256; Bs[i++] = new int[]{ 0x02, 0x02, 0x01, 0x00 }; Is[i] = -128; Bs[i++] = new int[]{ 0x02, 0x01, 0x80 }; Is[i] = -129; Bs[i++] = new int[]{ 0x02, 0x02, 0xff, 0x7f }; Is[i] = 43568; Bs[i++] = new int[]{ 0x02, 0x03, 0x00, 0xaa, 0x30 }; Is[i] = -43568; Bs[i++] = new int[]{ 0x02, 0x03, 0xff, 0x55, 0xd0 }; for( i = 0; i < Is.length; i++) { INTEGER I = new INTEGER( Is[i] ); byte[] compare = I.encode(); if( ! arraysEqual(compare, Bs[i]) ) { System.err.println("Encoding FAILED: "+Is[i]); System.exit(-1); } ByteArrayInputStream bis = new ByteArrayInputStream(compare); Template template = new Template(); INTEGER create = (INTEGER) template.decode(bis); if( create.intValue() != Is[i] ) { System.err.println("Decoding FAILED: "+Is[i]); System.exit(-1); } } System.out.println("PASS"); } catch( Exception e ) { e.printStackTrace(); } } private static boolean arraysEqual(byte[] bytes, int[] ints) { if(bytes == null || ints == null) { return false; } if(bytes.length != ints.length) { return false; } for( int i=0; i < bytes.length; i++) { if( bytes[i] != (byte)ints[i] ) { return false; } } return true; } /////////////////////////////////////////////////////////////////////// // INTEGER.Template // This is a nested class. // public static class Template implements ASN1Template { Tag getTag() { return INTEGER.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(INTEGER.TAG)); } public ASN1Value decode(InputStream derStream) throws InvalidBERException, IOException { return decode( getTag(), derStream ); } public ASN1Value decode(Tag tag, InputStream derStream) throws InvalidBERException, IOException { try { ASN1Header wrapper = new ASN1Header(derStream); wrapper.validate(tag, FORM); // Is length < 1 ? if( wrapper.getContentLength() < 1 ) { throw new InvalidBERException("Invalid 0 length for INTEGER"); } byte[] valBytes = new byte[ (int) wrapper.getContentLength() ]; ASN1Util.readFully(valBytes, derStream); return new INTEGER( valBytes ); } catch(InvalidBERException e) { throw new InvalidBERException(e, "INTEGER"); } } } // end of class Template } jss-4.4.3/jss/org/mozilla/jss/asn1/InvalidBERException.java000066400000000000000000000040321326145000000234460ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.util.Vector; /** * An exception thrown when BER decoding fails. */ public class InvalidBERException extends java.lang.Exception { private InvalidBERException child=null; private Vector mesgList = new Vector(); public InvalidBERException(String mesg) { super(mesg); } public void append(String mesg) { mesgList.addElement(mesg); } public InvalidBERException(InvalidBERException e, String mesg) { super(mesg); child = e; } /** * Prints out the exception class and error message, including * all the nested exceptions. */ private void appendMessages(StringBuffer sb) { int numMessages = mesgList.size(); for( int i=numMessages-1; i >= 0; --i ) { sb.append(mesgList.elementAt(i)); sb.append(" >> "); } sb.append(getMessage()); } public String toString() { StringBuffer sb = new StringBuffer(); sb.append( this.getClass().getName() ); sb.append(": "); appendMessages(sb); return sb.toString(); } public String toStringNested() { StringBuffer sb = new StringBuffer(); appendMessages(sb); if( child != null ) { sb.append(" >> "); sb.append( child.toStringNested() ); } return sb.toString(); } public static class EOF extends InvalidBERException { public EOF() { super("Unexpected end-of-file encountered"); } } public static class InvalidChar extends InvalidBERException { public InvalidChar(byte b, int offset) { super("Invalid character ("+b+") encountered at offset "+offset); } public InvalidChar(char c, int offset) { super("Invalid character ("+c+") encountered at offset"+offset); } } } jss-4.4.3/jss/org/mozilla/jss/asn1/Makefile000066400000000000000000000040371326145000000204520ustar00rootroot00000000000000#! gmake # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### run: $(DEBUG_CMD) /share/builds/components/jdk/1.2.2_05a/SunOS/jre/bin/java -classpath $(JAVA_HOME)/lib/classes.zip:$(SOURCE_CLASSES_DIR)_DBG org.mozilla.jss.asn1.SEQUENCE /tmp/p10 jss-4.4.3/jss/org/mozilla/jss/asn1/NULL.java000066400000000000000000000037651326145000000204360ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.OutputStream; import java.io.InputStream; import java.io.IOException; public class NULL implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 5); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { ASN1Header head = new ASN1Header(implicitTag, FORM, 0); head.encode(ostream); } private static final NULL instance = new NULL(); public static NULL getInstance() { return instance; } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { public Tag getTag() { return NULL.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(NULL.TAG) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(implicitTag, FORM); if( head.getContentLength() != 0 ) { throw new InvalidBERException("Invalid length ("+ head.getContentLength()+") for NULL; only 0 is permitted"); } return new NULL(); } catch(InvalidBERException e) { throw new InvalidBERException(e, "NULL"); } } } // end of Template } jss-4.4.3/jss/org/mozilla/jss/asn1/OBJECT_IDENTIFIER.java000066400000000000000000000435061326145000000223310ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; import java.util.Vector; import java.util.StringTokenizer; public class OBJECT_IDENTIFIER implements ASN1Value { /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Standard object identifiers /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * The OID space for EC */ public static final OBJECT_IDENTIFIER EC_PUBKEY_OID = new OBJECT_IDENTIFIER( new long[]{1, 2, 840, 10045, 2, 1} ); /** * The OID space for RSA Data Security, Inc. */ public static final OBJECT_IDENTIFIER RSADSI = new OBJECT_IDENTIFIER( new long[]{1, 2, 840, 113549} ); /** * The OID space for RSA's PKCS (public key cryptography standards). */ public static final OBJECT_IDENTIFIER PKCS = RSADSI.subBranch(1); /** * The OID space for RSA's PKCS #1. */ public static final OBJECT_IDENTIFIER PKCS1 = PKCS.subBranch(1); /** * The OID space for RSA's PKCS #2, which has since been folded into * PKCS #1. */ public static final OBJECT_IDENTIFIER PKCS2 = PKCS.subBranch(2); /** * The OID space for RSA's message digest algorithms. */ public static final OBJECT_IDENTIFIER RSA_DIGEST = RSADSI.subBranch(2); /** * The OID space for RSA's password-based encryption standard. */ public static final OBJECT_IDENTIFIER PKCS5 = PKCS.subBranch(5); /** * The OID space for RSA's Selected Attribute Types standard, PKCS #9. */ public static final OBJECT_IDENTIFIER PKCS9 = PKCS.subBranch(9); /** * The OID space for RSA's personal information exchange syntax standard. */ public static final OBJECT_IDENTIFIER PKCS12 = PKCS.subBranch(12); /** * The OID space for RSA's ciphers. */ public static final OBJECT_IDENTIFIER RSA_CIPHER = RSADSI.subBranch(3); /** * The OID space for FIPS standardized algorithms. */ public static final OBJECT_IDENTIFIER ALGORITHM = new OBJECT_IDENTIFIER( new long[] { 1, 3, 14, 3, 2 } ); /** * The OID space for FIPS-180-2 SHA256/SHA384/SHA512 standardized algorithms. */ public static final OBJECT_IDENTIFIER HASH_ALGORITHM = new OBJECT_IDENTIFIER( new long[] {2, 16, 840, 1, 101, 3, 4, 2 } ); /** * The OID space for PKIX. */ public static final OBJECT_IDENTIFIER PKIX = new OBJECT_IDENTIFIER( new long[] { 1, 3, 6, 1, 5, 5, 7 } ); public static final OBJECT_IDENTIFIER id_cmc = PKIX.subBranch( 7 ); /** * CMC control attributes */ public static final OBJECT_IDENTIFIER id_cmc_cMCStatusInfo = id_cmc.subBranch(1); public static final OBJECT_IDENTIFIER id_cmc_identification = id_cmc.subBranch(2); public static final OBJECT_IDENTIFIER id_cmc_identityProof = id_cmc.subBranch(3); public static final OBJECT_IDENTIFIER id_cmc_dataReturn = id_cmc.subBranch(4); public static final OBJECT_IDENTIFIER id_cmc_transactionId = id_cmc.subBranch(5); public static final OBJECT_IDENTIFIER id_cmc_senderNonce = id_cmc.subBranch(6); public static final OBJECT_IDENTIFIER id_cmc_recipientNonce = id_cmc.subBranch(7); public static final OBJECT_IDENTIFIER id_cmc_addExtensions = id_cmc.subBranch(8); public static final OBJECT_IDENTIFIER id_cmc_encryptedPOP = id_cmc.subBranch(9); public static final OBJECT_IDENTIFIER id_cmc_decryptedPOP = id_cmc.subBranch(10); public static final OBJECT_IDENTIFIER id_cmc_lraPOPWitness = id_cmc.subBranch(11); public static final OBJECT_IDENTIFIER id_cmc_getCert = id_cmc.subBranch(15); public static final OBJECT_IDENTIFIER id_cmc_getCRL = id_cmc.subBranch(16); public static final OBJECT_IDENTIFIER id_cmc_revokeRequest = id_cmc.subBranch(17); public static final OBJECT_IDENTIFIER id_cmc_regInfo = id_cmc.subBranch(18); public static final OBJECT_IDENTIFIER id_cmc_responseInfo = id_cmc.subBranch(19); public static final OBJECT_IDENTIFIER id_cmc_QueryPending = id_cmc.subBranch(21); public static final OBJECT_IDENTIFIER id_cmc_idPOPLinkRandom = id_cmc.subBranch(22); public static final OBJECT_IDENTIFIER id_cmc_idPOPLinkWitness = id_cmc.subBranch(23); public static final OBJECT_IDENTIFIER id_cmc_idConfirmCertAcceptance = id_cmc.subBranch(24); // rfc 5272 public static final OBJECT_IDENTIFIER id_cmc_statusInfoV2 = id_cmc.subBranch(25); public static final OBJECT_IDENTIFIER id_cmc_trustedAnchors = id_cmc.subBranch(26); public static final OBJECT_IDENTIFIER id_cmc_authData = id_cmc.subBranch(27); public static final OBJECT_IDENTIFIER id_cmc_batchRequests = id_cmc.subBranch(28); public static final OBJECT_IDENTIFIER id_cmc_batchResponses = id_cmc.subBranch(29); public static final OBJECT_IDENTIFIER id_cmc_publishCert = id_cmc.subBranch(30); public static final OBJECT_IDENTIFIER id_cmc_modCertTemplate = id_cmc.subBranch(31); public static final OBJECT_IDENTIFIER id_cmc_controlProcessed = id_cmc.subBranch(32); public static final OBJECT_IDENTIFIER id_cmc_popLinkWitnessV2 = id_cmc.subBranch(33); public static final OBJECT_IDENTIFIER id_cmc_identityProofV2 = id_cmc.subBranch(34); public static final OBJECT_IDENTIFIER id_cct = PKIX.subBranch( 12 ); public static final OBJECT_IDENTIFIER id_cct_PKIData = id_cct.subBranch( 2 ); public static final OBJECT_IDENTIFIER id_cct_PKIResponse = id_cct.subBranch( 3 ); public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 6); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; private long[] numbers; /** * Creates an OBJECT_IDENTIFIER from an array of longs, which constitute * the numbers that make up the OBJECT IDENTIFIER. */ public OBJECT_IDENTIFIER( long[] numbers ) { checkLongArray(numbers); this.numbers = numbers; } /** * Checks the given array of numbers to see if it is a valid OID. * This is not an exhaustive test, it just looks for obvious problems. * It will throw an assertion if a problem is found. With DEBUG turned * off, it just checks for null. */ private static void checkLongArray(long[] numbers) { Assert._assert(numbers != null); if(numbers == null) { throw new NullPointerException(); } Assert._assert(numbers.length >= 2); Assert._assert( numbers[0]==0 || numbers[0]==1 || numbers[0]==2 ); } /** * Creates an OBJECT_IDENTIFIER from a String version. The proper format * for the OID string is dotted numbers, for example: * "3.2.456.53.23.64". * * Because the toString() method here provides a different format, we also * allow that format, for example: * "{3 2 456 53 23 64}". * * @exception NumberFormatException If the given string cannot be * parsed into an OID. */ public OBJECT_IDENTIFIER( String dottedOID ) throws NumberFormatException { if( dottedOID == null || dottedOID.length()==0 ) { throw new NumberFormatException("OID string is zero-length"); } if (dottedOID.startsWith("{")) { // input string is of the format provided by OBJECT_IDENTIFIER,toString() // convert this first to dotted OID // remove the leading and trailing brackets dottedOID = dottedOID.substring(1, dottedOID.length()-1); // convert spaces to dots dottedOID = dottedOID.replaceAll(" ", "."); } StringTokenizer stok = new StringTokenizer(dottedOID, "."); numbers = new long[ stok.countTokens() ]; int i = 0; while(stok.hasMoreElements()) { numbers[i++] = Long.parseLong( stok.nextToken() ); } Assert._assert( i == numbers.length ); checkLongArray(numbers); } public long[] getNumbers() { return numbers; } public int hashCode() { int code = 1; for(int i = 0; i < numbers.length; i++) { code = (int) (code + numbers[i])*10; } return code; } /** * Creates a new OBJECT_IDENTIFIER that is a sub-branch of this one. * For example, if OBJECT_IDENTIFIER oid has the value * { 1 3 5 6 }, * then calling oid.subBranch(4) would return a new * OBJECT_IDENTIFIER with the value { 1 3 5 6 4 }. */ public OBJECT_IDENTIFIER subBranch(long num) { long[] nums = new long[ numbers.length + 1]; System.arraycopy(numbers, 0, nums, 0, numbers.length); nums[numbers.length] = num; return new OBJECT_IDENTIFIER(nums); } /** * Creates a new OBJECT_IDENTIFIER that is a sub-branch of this one. * For example, if OBJECT_IDENTIFIER oid has the value * { 1 3 5 6 }, * then calling oid.subBranch(new long[]{ 4, 3}) * would return a new * OBJECT_IDENTIFIER with the value { 1 3 5 6 4 3}. */ public OBJECT_IDENTIFIER subBranch(long[] newNums) { long[] nums = new long[ numbers.length + newNums.length]; System.arraycopy(numbers, 0, nums, 0, numbers.length); System.arraycopy(newNums, 0, nums, numbers.length, newNums.length); return new OBJECT_IDENTIFIER(nums); } public boolean equals(Object obj) { if(obj == null || ! (obj instanceof OBJECT_IDENTIFIER)) { return false; } long[] nums = ((OBJECT_IDENTIFIER)obj).numbers; if( nums.length != numbers.length ) { return false; } for(int i = 0; i < nums.length; i++) { if( nums[i] != numbers[i] ) { return false; } } return true; } public String toString() { String ret = "{" + String.valueOf(numbers[0]); for(int i=1; i < numbers.length; i++) { ret = ret + " " + numbers[i]; } ret += "}"; return ret; } public String toDottedString() { String ret = String.valueOf(numbers[0]); for(int i=1; i < numbers.length; i++) { ret = ret + "." + numbers[i]; } return ret; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } private byte[] encodedContents = null; /** * Gets the encoding of the contents, or a cached copy. * Since the content encoding is the same regardless of the Tag, * this only needs to be computed once. */ private byte[] getEncodedContents() { if( encodedContents == null ) { encodedContents = computeEncodedContents(); } return encodedContents; } // We cache our encoding for a given tag. 99% of the time, only // one tag will be used for an instance, so we will get a cache hit. // In the remaining 1%, we'll have to recompute the encoding. byte[] cachedEncoding=null; Tag tagForCache=null; /** * Returns the encoding for the given tag. If the encoding for * this tag was previously computed (and no encoding for a different * tag has since been computed), this method returns a cached copy. * Otherwise, the encoding will be recomputed. */ private byte[] getEncoding(Tag tag) { if( ! tag.equals(tagForCache) ) { // recompute for new tag ByteArrayOutputStream out = new ByteArrayOutputStream(); ASN1Header head = getHeader(tag); try { head.encode(out); } catch( IOException e ) { // should never happen on a byte array output stream Assert.notReached("exception while encoding ASN.1 header"); } out.write( getEncodedContents(), 0, getEncodedContents().length ); tagForCache = tag; cachedEncoding = out.toByteArray(); } return cachedEncoding; } /** * Compute the ASN1 header for this tag. */ private ASN1Header getHeader(Tag implicitTag) { return new ASN1Header( implicitTag, FORM, getEncodedContents().length ); } /** * Actually computes the encoding of this object identifier. */ private byte[] computeEncodedContents() { ByteArrayOutputStream out = new ByteArrayOutputStream(); // handle first number Assert._assert(numbers.length >= 2); long n = numbers[0]; Assert._assert( n == 0 || n == 1 || n == 2 ); long outb = ( numbers[0] * 40 ) + numbers[1]; Assert._assert( ((byte)outb) == outb ); out.write( (byte)outb ); // handle consecutive numbers for( int i = 2; i < numbers.length; i++ ) { n = numbers[i]; Assert._assert( n >= 0 ); // array of output bytes, in reverse order. 10 bytes, at 7 bits // per byte, is 70 bits, which is more than enough to handle // the maximum value of a long, which takes up 63 bits. byte[] rev = new byte[10]; int idx=0; // index into reversed bytes // Create reversed byte list do { rev[idx++] = (byte) (n % 128); n = n / 128; } while( n > 0 ); idx--; // backup to point to last element // now print them in reverse order while( idx > 0 ) { // all but last byte have MSB==1 out.write( rev[idx--] | 0x80 ); } Assert._assert(idx == 0); // last byte has MSB==0 out.write( rev[0] ); } return out.toByteArray(); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { ostream.write( getEncoding(implicitTag) ); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /////////////////////////////////////////////////////////////////////// // OBJECT_IDENTIFIER.Template // public static class Template implements ASN1Template { public Tag getTag() { return OBJECT_IDENTIFIER.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(OBJECT_IDENTIFIER.TAG) ); } public Form getForm() { return OBJECT_IDENTIFIER.FORM; } public boolean formMatch(Form form) { return( form == OBJECT_IDENTIFIER.FORM ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); long remainingContent = head.getContentLength(); // Check the information gleaned from the header if( ! head.getTag().equals( implicitTag ) ) { throw new InvalidBERException("Incorrect tag for "+ "OBJECT IDENTIFIER: "+ head.getTag() ); } if( head.getForm() != getForm() ) { throw new InvalidBERException("Incorrect form for OBJECT "+ "IDENTIFIER"); } if( remainingContent < 1 ) { throw new InvalidBERException("Invalid 0 length for OBJECT"+ " IDENTIFIER"); } Vector numberV = new Vector(); // handle first byte, which contains first two numbers byte b = readByte(istream); remainingContent--; long num = b % 40; numberV.addElement( new Long( b % 40 ) ); // second number numberV.insertElementAt( new Long( b / 40 ), 0); // first number // handle the rest of the numbers while( remainingContent > 0 ) { num = 0; // keep reading until MSB == 0 int bitcount=0; do { if( (bitcount+=7) > 63 ) { // we're about to overflow our long throw new InvalidBERException("OBJECT IDENTIFIER "+ "element too long; max is 63 bits"); } b = readByte(istream); remainingContent--; num <<= 7; num |= (b & 0x7f); } while( (b & 0x80) != 0 ); numberV.addElement( new Long( num ) ); } // convert Vector to array long numbers[] = new long[ numberV.size() ]; for(int i = 0; i < numbers.length; i++) { numbers[i] = ((Long)numberV.elementAt(i)).longValue(); } // create OBJECT_IDENTIFIER from array return new OBJECT_IDENTIFIER(numbers); } catch(InvalidBERException e) { throw new InvalidBERException(e, "OBJECT IDENTIFIER"); } } /** * Reads in a byte from the stream, throws an InvalidBERException * if EOF is reached. */ private static byte readByte(InputStream istream) throws InvalidBERException, IOException { int n = istream.read(); if( n == -1 ) { throw new InvalidBERException("End-of-file reached while "+ "decoding OBJECT IDENTIFIER"); } Assert._assert( (n & 0xff) == n ); return (byte) n; } } // end of OBJECT_IDENTIFIER.Template } jss-4.4.3/jss/org/mozilla/jss/asn1/OCTET_STRING.java000066400000000000000000000061131326145000000216160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.ByteArrayOutputStream; public class OCTET_STRING implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 4); public Tag getTag() { return TAG; } public static final Form FORM = Form.PRIMITIVE; byte[] data; private OCTET_STRING() { } public OCTET_STRING( byte[] data ) { this.data = data; } public byte[] toByteArray() { return data; } public void encode(OutputStream ostream) throws IOException { // use getTag() so we can be subclassed encode(getTag(), ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { ASN1Header head = new ASN1Header(implicitTag, FORM, data.length); head.encode(ostream); ostream.write(data); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { public Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return( TAG.equals(tag) ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } // this can be overridden by subclasses protected ASN1Value generateInstance(byte[] bytes) { return new OCTET_STRING( bytes ); } // this can be overridden by subclasses protected String getName() { return "OCTET_STRING"; } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header head = new ASN1Header(istream); head.validate(implicitTag); byte[] data; if( head.getContentLength() == -1 ) { // indefinite length encoding ASN1Header ahead; ByteArrayOutputStream bos = new ByteArrayOutputStream(); do { ahead = ASN1Header.lookAhead( istream ); if( ! ahead.isEOC() ) { OCTET_STRING.Template ot = new OCTET_STRING.Template(); OCTET_STRING os = (OCTET_STRING) ot.decode(istream); bos.write( os.toByteArray() ); } } while( ! ahead.isEOC() ); // consume EOC ahead = new ASN1Header(istream); data = bos.toByteArray(); } else { data = new byte[ (int) head.getContentLength() ]; ASN1Util.readFully(data, istream); } return generateInstance(data); } catch( InvalidBERException e ) { throw new InvalidBERException(e, getName()); } } } // end of Template } jss-4.4.3/jss/org/mozilla/jss/asn1/PrintableString.java000066400000000000000000000070311326145000000227610ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; public class PrintableString extends CharacterString implements ASN1Value { public PrintableString(char[] chars) throws CharConversionException { super(chars); } public PrintableString(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new PrintableConverter(); } public static final Tag TAG = new Tag( Tag.UNIVERSAL, 19 ); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } /** * Returns a singleton instance of the decoding template for this class. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new PrintableConverter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new PrintableString(chars); } protected String typeName() { return "PrintableString"; } } private static class PrintableConverter implements CharConverter { private static boolean[] isPrintable = new boolean[128]; static { char b; for(b='A'; b <= 'Z'; b++) { isPrintable[b] = true; } for(b='a'; b <= 'z'; b++) { isPrintable[b] = true; } for(b='0'; b <= '9'; b++) { isPrintable[b] = true; } isPrintable[' '] = true; isPrintable['\''] = true; isPrintable['('] = true; isPrintable[')'] = true; isPrintable['+'] = true; isPrintable[','] = true; isPrintable['-'] = true; isPrintable['.'] = true; isPrintable['/'] = true; isPrintable[':'] = true; isPrintable['='] = true; isPrintable['?'] = true; } public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { char[] chars = new char[len]; int c; // char index int b; // byte index for(c=0, b=offset; c < len; b++, c++) { if( (bytes[b] & 0x80) != 0 || !isPrintable[bytes[b]] ) { /* fix for bug 359010 - don't throw, just skip * throw new CharConversionException(bytes[b]+ " is not "+ * "a valid character for a PrintableString"); */ } else { chars[c] = (char) bytes[b]; } } return chars; } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { byte[] bytes = new byte[len]; int c; // char index int b; // byte index for(c=0, b=0; b < len; b++, c++) { if( (chars[c] & 0xff80) != 0 || !isPrintable[chars[c]] ) { throw new CharConversionException(chars[c]+ " is not "+ "a valid character for a PrintableString"); } bytes[b] = (byte) (chars[c] & 0x7f); } return bytes; } } // end of char converter } jss-4.4.3/jss/org/mozilla/jss/asn1/SEQUENCE.java000066400000000000000000000607171326145000000210740ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; /** * An ASN.1 SEQUENCE. This class is an ordered collection of ASN.1 values. * It has an interface similar to a Java Vector. * Null entries may be added; they will be skipped when encoded. */ public class SEQUENCE extends SET implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 16); public Tag getTag() { return TAG; } public static Template getTemplate() { return new Template(); } /** * Writes the DER encoding to the given output stream, * using the given implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { BERencode(implicitTag, ostream); } // SET.Element and SEQUENCE.Element are identical types. We could // have just reused SET.Element, but that would have been a bit // confusing for users. private static class Element extends SET.Element { public Element( ASN1Value val ) { super(val); } public Element( Tag implicitTag, ASN1Value val) { super(implicitTag, val); } } /** * A class for constructing a SEQUENCE from its BER encoding. * It is an ordered collection of sub-templates. Each sub-template can be * marked optional, or a default value can be given. */ public static class Template implements ASN1Template { private Vector elements = new Vector(); private void addElement(Element el) { elements.addElement( el ); } private void insertElementAt(Element e, int index) { elements.insertElementAt(e, index); } /** * Adds a sub-template to the end of this SEQUENCE template. For example, * if the ASN.1 included: *
     * MySequence ::= SEQUENCE {
     *      item        SubType,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new SubType.Template() );
     * 
*/ public void addElement( ASN1Template t ) { addElement( new Element(null, t, false) ); } /** * Inserts the template at the given index. */ public void insertElementAt( ASN1Template t, int index ) { insertElementAt( new Element(null, t, false), index ); } /** * Adds a sub-template to the end of this SEQUENCE template, with the * given implicit tag. For example, if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      item        [0] IMPLICIT  SubType,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new Tag(0), new SubType.Template());
     * 
*/ public void addElement( Tag implicitTag, ASN1Template t ) { addElement( new Element(implicitTag, t, false) ); } /** * Inserts the template with the given implicit tag at the given index. */ public void insertElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, false), index ); } /** * Adds an optional sub-template. For example, if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      item        SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addOptionalElement( new SubType.Template() );
     * 
*/ public void addOptionalElement( ASN1Template t ) { addElement( new Element(null, t, true) ); } /** * Inserts the optional template at the given index. */ public void insertOptionalElementAt( ASN1Template t, int index ) { insertElementAt( new Element(null, t, true), index ); } /** * Adds an optional sub-template with an implicit tag. For example, * if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      item        [0] IMPLICIT SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addOptionalElement( new SubType.Template() );
     * 
*/ public void addOptionalElement( Tag implicitTag, ASN1Template t ) { addElement( new Element(implicitTag, t, true) ); } /** * Inserts the optional template with the given default * value at the given index. */ public void insertOptionalElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, true), index ); } /** * Adds a sub-template with a default value. For example, * if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      version     INTEGER DEFAULT 1,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new INTEGER.Template(), new INTEGER(1) );
     * 
* @param def The default value for this field, which will be used if * no value is supplied by the encoded structure. It must be of * the same type as what the template would produce. */ public void addElement( ASN1Template t, ASN1Value def ) { addElement( new Element(null, t, def) ); } /** * Inserts the template with the given default * value at the given index. */ public void insertElementAt( ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(null, t, def), index ); } /** * Adds a sub-template with a default value and an implicit tag. * For example, if the ASN.1 were: *
     * MySequence ::= SEQUENCE {
     *      version     [0] IMPLICIT INTEGER DEFAULT 1,
     *      ... }
     * 
* the "item" element would be added to the MySequence template with: *
     *  mySequence.addElement( new Tag(0), new INTEGER.Template(),
     *      new INTEGER(1) );
     * 
* @param def The default value for this field, which will be used if * no value is supplied by the encoded structure. It must be of * the same type as what the template would produce. */ public void addElement( Tag implicitTag, ASN1Template t, ASN1Value def) { addElement( new Element(implicitTag, t, def) ); } /** * Inserts the template with the given implicit tag and given default * value at the given index. */ public void insertElementAt( Tag implicit, ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(implicit, t, def), index ); } /** * Returns the implicit tag of the item stored at the given index. * May be NULL if no implicit tag was specified. */ public Tag implicitTagAt( int index ) { return ((Element)elements.elementAt(index)).getImplicitTag(); } /** * Returns the sub-template stored at the given index. */ public ASN1Template templateAt( int index ) { return ((Element)elements.elementAt(index)).getTemplate(); } /** * Returns whether the sub-template at the given index is optional. */ public boolean isOptionalAt( int index ) { return ((Element)elements.elementAt(index)).isOptional(); } /** * Returns the default value for the sub-template at the given index. * May return NULL if no default value was specified. */ public ASN1Value defaultAt( int index ) { return ((Element)elements.elementAt(index)).getDefault(); } /** * Returns the number of elements in this SEQUENCE template. */ public int size() { return elements.size(); } /** * Removes all sub-templates from this SEQUENCE template. */ public void removeAllElements() { elements.removeAllElements(); } /** * Removes the sub-template at the given index. */ public void removeElementAt(int index) { elements.removeElementAt(index); } Tag getTag() { return SEQUENCE.TAG; } public boolean tagMatch(Tag tag) { return( tag.equals(SEQUENCE.TAG) ); } /** * Decodes a SEQUENCE from its BER encoding. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } /** * Decodes a SEQUENCE from its BER encoding, where the SEQUENCE itself has * an implicit tag. */ public ASN1Value decode(Tag tag, InputStream istream) throws IOException, InvalidBERException { int index = 0; try { ASN1Header header = new ASN1Header(istream); header.validate( tag, Form.CONSTRUCTED ); // will be -1 for indefinite encoding long remainingContent = header.getContentLength(); boolean repeatableElement=false; SEQUENCE seq = new SEQUENCE(); ASN1Header lookAhead=null; // go through the whole template for( index = 0; index < size(); index++ ) { // find out about the next item if( remainingContent == 0 ) { lookAhead = null; } else { // remainingContent > 0 or remainingContent == -1, which means // indefinite encoding. lookAhead = ASN1Header.lookAhead(istream); } // skip over items that don't match. Hopefully they are // optional or have a default. Otherwise, it's an error. Element e = (Element) elements.elementAt(index); if( (lookAhead == null) || lookAhead.isEOC() || ! e.tagMatch( lookAhead.getTag() ) ) { if( e.isRepeatable() ) { repeatableElement = true; } else if( e.isOptional() ) { // put an empty entry into the SEQUENCE SEQUENCE.Element se = new SEQUENCE.Element(null, null ); seq.addElement( null ); } else if( e.getDefault() != null ) { // use the default seq.addElement( e.getDefault() ); } else { String tagDesc; if( lookAhead == null ) { tagDesc = "(null)"; } else { tagDesc = lookAhead.getTag().toString(); } throw new InvalidBERException("Missing item #" + index + ": found " + tagDesc ); } continue; } // Decode this element ASN1Template t = e.getTemplate(); ASN1Value val; CountingStream countstream = new CountingStream(istream); if( e.getImplicitTag() == null ) { val = t.decode(countstream); } else { val = t.decode(e.getImplicitTag(), countstream); } // Decrement remaining count long len = countstream.getNumRead(); if( remainingContent != -1 ) { if( remainingContent < len ) { // this item went past the end of the SEQUENCE throw new InvalidBERException("Item went "+ (len-remainingContent)+" bytes past the end of"+ " the SEQUENCE"); } remainingContent -= len; } // Store this element in the SEQUENCE if( e.producesOutput() ) { if( e.getImplicitTag() == null ) { // no implicit tag seq.addElement( val ); } else { // there is an implicit tag seq.addElement( e.getImplicitTag(), val ); } } // If this element is repeatable, don't go on to the next element if( e.isRepeatable() ) { repeatableElement = true; index--; } } if( remainingContent > 0 ) { throw new InvalidBERException("SEQUENCE is " + remainingContent + " bytes longer than expected"); } Assert._assert( remainingContent == 0 || remainingContent == -1 ); // If this was indefinite-length encoding, consume the end-of-contents if( remainingContent == -1 ) { lookAhead = new ASN1Header(istream); if( ! lookAhead.isEOC() ) { throw new InvalidBERException("No end-of-contents marker"); } } // Make sure we stayed in sync if( ! repeatableElement ) { Assert._assert(index == seq.size()); } return seq; } catch(InvalidBERException e) { e.append("SEQUENCE(item #" +index + ")"); throw e; } } /** * An element of a SEQUENCE template. For each sub-template, contains the * template, its optionality, its implicit tag, and its default value. */ static class Element { /** * Creates a new element, which may or may not be optional. */ public Element(Tag implicitTag, ASN1Template type, boolean optional) { this(implicitTag, type, optional, true); } /** * Creates a new element, which may or may not be optional. */ public Element(Tag implicitTag, ASN1Template type, boolean optional, boolean doesProduceOutput) { this.type = type; defaultVal = null; this.optional = optional; this.implicitTag = implicitTag; this.doesProduceOutput = doesProduceOutput; } /** * Creates a new element with a default value. */ public Element(Tag implicitTag, ASN1Template type, ASN1Value defaultVal) { this.type = type; this.defaultVal = defaultVal; optional = false; this.implicitTag = implicitTag; } private boolean doesProduceOutput = true; boolean producesOutput() { return doesProduceOutput; } // repeatability is provided to allow for SEQUENCE OF SIZE // constructs. It is package private. private boolean repeatable; void makeRepeatable() { repeatable = true; } boolean isRepeatable() { return repeatable; } private boolean optional; public boolean isOptional() { return optional; } private Tag implicitTag=null; public Tag getImplicitTag() { return implicitTag; } public boolean tagMatch(Tag tag) { if( implicitTag != null ) { return( implicitTag.equals(tag) ); } else { return type.tagMatch(tag); } } private ASN1Template type; public ASN1Template getTemplate() { return type; } private ASN1Value defaultVal=null; public ASN1Value getDefault() { return defaultVal; } } } // End of SEQUENCE.Template /** * A Template for decoding SEQUENCE OF values. The main difference between * a SEQUENCE.Template and a SEQUENCE.OF_Template is that a regular template * specifies the exact ordering, number, and type of elements of the sequence, * while * an OF_Template has an indefinite number of elements, all the same type. * For example, given: *
 * MyType ::= SEQUENCE OF Extension
 * 
* a MyType could be decoded with: *
 *  SEQUENCE.OF_Template myTypeTemplate = new SEQUENCE.OF_Template( new
 *      Extension.Template) );
 *  SEQUENCE seq = (SEQUENCE) myTypeTemplate.decode(someInputStream);
 * 
* The number of Extensions actually decoded could be found * with seq.size(). */ public static class OF_Template implements ASN1Template { private OF_Template() { } Template template; // a normal SEQUENCE template public OF_Template(ASN1Template type) { template = new Template(); Template.Element el = new Template.Element(null, type, true); //optional el.makeRepeatable(); template.addElement( el ); } public static OF_Template makeOutputlessOFTemplate(ASN1Template type) { OF_Template t = new OF_Template(); t.template = new Template(); Template.Element el = new Template.Element(null, type, true, false); el.makeRepeatable(); t.template.addElement(el); return t; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } /** * Decodes a SEQUENCE OF from an input stream. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return template.decode(istream); } /** * Decodes a SEQUENCE OF with an implicit tag from an input stream. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return template.decode(implicitTag, istream); } } public static void main(String args[]) { try { if(args.length > 0) { // input Template type = new Template(); type.addOptionalElement( new Tag(15), new INTEGER.Template() ); type.addElement( new Tag(16), new INTEGER.Template(), new INTEGER(42) ); type.addElement( new INTEGER.Template() ); type.addElement( new BOOLEAN.Template() ); type.addElement( new INTEGER.Template() ); type.addOptionalElement( new Tag(12), new INTEGER.Template() ); type.addElement( new BOOLEAN.Template() ); type.addElement( new Tag(13), new INTEGER.Template(), new INTEGER(53) ); type.addElement( new INTEGER.Template() ); type.addElement( new INTEGER.Template() ); type.addOptionalElement( new Tag(14), new INTEGER.Template() ); type.addElement( new OBJECT_IDENTIFIER.Template() ); type.addElement( new NULL.Template() ); type.addElement( new EXPLICIT.Template( new Tag(27), new INTEGER.Template())); type.addElement( new ENUMERATED.Template() ); type.addElement( new OCTET_STRING.Template() ); type.addElement( new IA5String.Template() ); CHOICE.Template choice = new CHOICE.Template(); choice.addElement( new Tag(23), new INTEGER.Template() ); choice.addElement( new BOOLEAN.Template() ); type.addElement( choice ); type.addElement( new BIT_STRING.Template() ); type.addElement( new ANY.Template() ); type.addElement( new PrintableString.Template() ); type.addElement( new OF_Template( new INTEGER.Template() ) ); type.addElement( new OF_Template( new INTEGER.Template() ) ); FileInputStream fin = new FileInputStream(args[0]); System.out.println("Available: "+fin.available()); byte[] stuff = new byte[ fin.available() ]; ASN1Util.readFully(stuff, fin); SEQUENCE s=null; for( int i = 0; i < 1; i++) { s = (SEQUENCE) type.decode( new ByteArrayInputStream(stuff) ); } for(int i=0; i < s.size(); i ++ ) { ASN1Value v = s.elementAt(i); if(v instanceof ENUMERATED) { ENUMERATED en = (ENUMERATED) v; System.out.println("ENUMERATED: "+en); } else if( v instanceof INTEGER ) { INTEGER in = (INTEGER) v; System.out.println("INTEGER: "+in); } else if(v instanceof BOOLEAN ) { BOOLEAN bo = (BOOLEAN) v; System.out.println("BOOLEAN: "+bo); } else if(v instanceof OBJECT_IDENTIFIER) { OBJECT_IDENTIFIER oid = (OBJECT_IDENTIFIER) v; System.out.println("OID: "+oid); } else if(v instanceof NULL) { NULL n = (NULL) v; System.out.println("NULL"); } else if(v instanceof EXPLICIT) { EXPLICIT ex = (EXPLICIT) v; INTEGER in = (INTEGER) ex.getContent(); System.out.println("EXPLICIT ["+ex.getTag()+"]: "+ "INTEGER: "+in); } else if(v instanceof OCTET_STRING) { OCTET_STRING os = (OCTET_STRING) v; byte[] bytes = os.toByteArray(); System.out.print("OCTET_STRING: "); for(int j = 0; j < bytes.length; j++) { System.out.print(bytes[j]+" "); } System.out.println(""); } else if( v instanceof CharacterString ) { CharacterString cs = (CharacterString) v; System.out.println("String: "+cs); } else if( v instanceof BIT_STRING ) { BIT_STRING bs = (BIT_STRING) v; System.out.print("BIT_STRING: padCount="+ bs.getPadCount()+" : "); byte[] bits = bs.getBits(); for(int j = 0; j < bits.length; j++) { System.out.print(bits[j]+" "); } System.out.println(""); } else if( v instanceof ANY ) { ANY any = (ANY) v; Tag tag = any.getTag(); System.out.println("Got ANY, tag is "+tag); ByteArrayInputStream bos = new ByteArrayInputStream( any.getEncoded() ); INTEGER in = (INTEGER) new INTEGER.Template().decode(bos); System.out.println(" INTEGER: "+in); } else if(v instanceof SEQUENCE ) { SEQUENCE seq = (SEQUENCE)v; System.out.println("SEQUENCE: "); for(int j=0; j < seq.size(); j++ ) { INTEGER in = (INTEGER) seq.elementAt(j); System.out.println(" INTEGER: "+in); } } else { System.out.println("Unknown value"); } } } else { // output SEQUENCE seq = new SEQUENCE(); seq.addElement( new INTEGER(5) ); seq.addElement( new BOOLEAN(true) ); seq.addElement( new INTEGER(-322) ); seq.addElement( new BOOLEAN(false) ); seq.addElement( new INTEGER(0) ); seq.addElement( new INTEGER("2934293834242") ); seq.addElement( new OBJECT_IDENTIFIER( new long[] { 1, 2, 127, 563, 1231982 } ) ); seq.addElement( new NULL() ); seq.addElement( new EXPLICIT( new Tag(27), new INTEGER(39) )); seq.addElement( new ENUMERATED(983) ); seq.addElement( new OCTET_STRING( new byte[] { (byte)0x0, (byte)0xff, (byte)0xcc} ) ); seq.addElement( new IA5String("foobar") ); seq.addElement( new Tag(23), new INTEGER(234) ); //seq.addElement( new BOOLEAN(false) ); byte[] bits = new byte[]{ (byte)0x80, (byte)0xff, (byte)0x0f }; seq.addElement( new BIT_STRING( bits, 3 ) ); seq.addElement( new INTEGER(82734) ); seq.addElement( new PrintableString("I'm printable??") ); SEQUENCE nested = new SEQUENCE(); nested.addElement( new INTEGER( 5 ) ); nested.addElement( new INTEGER( 6 ) ); seq.addElement( nested ); nested = new SEQUENCE(); seq.addElement( nested ); seq.encode(System.out); System.out.flush(); } } catch( Exception e) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/asn1/SET.java000066400000000000000000000640121326145000000203070ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.math.BigInteger; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.io.FileInputStream; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; /** * An ASN.1 SET, which is an unordered collection of ASN.1 values. * It has an interface like a Java Vector, but the ordering is arbitrary. * Null entries may be added; they will be skipped when encoding. */ public class SET implements ASN1Value { public static final Tag TAG = new Tag(Tag.Class.UNIVERSAL, 17); public Tag getTag() { return TAG; } protected static final Form FORM = Form.CONSTRUCTED; // The elements of the set protected Vector elements = new Vector(); private void addElement( Element e ) { elements.addElement(e); } private void insertElementAt( Element e, int index ) { elements.insertElementAt(e, index); } /** * Adds an element to this SET. */ public void addElement( ASN1Value v ) { addElement( new Element(v) ); } /** * Adds an element to this SET with the given implicit tag. For example, * if the ASN.1 were: *
     *  MyType ::= SET {
     *      item        [0] IMPLICIT INTEGER,
     *      ... }
     * 
* then the "item" element could be added (with a sample value of 45) * to the SET with: *
     * myTypeInstance.addElement( new Tag(0), new INTEGER(45) );
     * 
*/ public void addElement( Tag implicitTag, ASN1Value v ) { addElement( new Element(implicitTag, v) ); } /** * Inserts an element at the given index. */ public void insertElementAt( ASN1Value v, int index ) { insertElementAt( new Element(v), index ); } /** * Inserts an element with the given implicit tag at the given index. */ public void insertElementAt( Tag implicitTag, ASN1Value v, int index ) { insertElementAt( new Element(implicitTag, v), index ); } /** * Returns the element at the given index in the SET. */ public ASN1Value elementAt( int index ) { return ((Element)elements.elementAt(index)).getValue(); } /** * Returns the tag of the element at the given index. If the element * has an implicit tag, that is returned. Otherwise, the tag of the * underlying type is returned. */ public Tag tagAt( int index ) { Tag implicit = ((Element)elements.elementAt(index)).getImplicitTag(); if( implicit != null ) { return implicit; } else { return elementAt(index).getTag(); } } /** * Returns the element with the given Tag, or null if no element exists * with the given tag. */ public ASN1Value elementWithTag( Tag tag ) { // hmmm...linear search for now, should use hashtable later int size = elements.size(); for( int i=0; i < size; i++ ) { Element e = (Element) elements.elementAt(i); if( e.getTag().equals(tag) ) { return e.getValue(); } } return null; } /** * Returns the number of elements in this SET. */ public int size() { return elements.size(); } /** * Removes all elements from this SET. */ public void removeAllElements() { elements.removeAllElements(); } /** * Removes the element from the specified index. */ public void removeElementAt(int index) { elements.removeElementAt(index); } /** * Writes the DER encoding to the given output stream. */ public void encode(OutputStream ostream) throws IOException { encode(getTag(), ostream); } /** * Writes the DER encoding to the given output stream, * using the given implicit tag. To satisfy DER encoding rules, * the elements will be re-ordered either by tag or lexicographically. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // what ordering method? boolean lexOrdering; if( elements.size() < 2 ) { // doesn't matter, only one element lexOrdering = true; } else if( tagAt(0).equals(tagAt(1)) ) { // tags are the same, lexicographic ordering lexOrdering = true; } else { // tags are different, order by tag lexOrdering = false; } // compute and order contents int numElements = elements.size(); int totalBytes = 0; Vector encodings = new Vector(numElements); Vector tags = new Vector(numElements); int i; for(i = 0; i < numElements; i++ ) { // if an entry is null, just skip it if( elementAt(i) != null ) { byte[] enc = ASN1Util.encode(tagAt(i), elementAt(i)); totalBytes += enc.length; if( lexOrdering ) { insertInOrder(encodings, enc); } else { insertInOrder(encodings, enc, tags, (int) tagAt(i).getNum()); } } } // write header ASN1Header header = new ASN1Header( implicitTag, FORM, totalBytes ); header.encode(ostream); // write contents in order for(i=0; i < numElements; i++ ) { ostream.write( (byte[]) encodings.elementAt(i) ); } } /** * Encodes this SET without re-ordering it. This may violate * DER, but it is within BER. */ public void BERencode(Tag implicitTag, OutputStream ostream) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); // compute contents int size = elements.size(); for(int i = 0; i < size; i++ ) { ASN1Value el = elementAt(i); if(el!=null) { el.encode(tagAt(i), bos); } } byte[] bytes = bos.toByteArray(); // write header ASN1Header header = new ASN1Header( implicitTag, FORM, bytes.length ); header.encode(ostream); // write contents ostream.write(bytes); } // performs ascending lexicographic ordering // linear search, but number of items is usually going to be small. private static void insertInOrder(Vector encs, byte[] enc) { int size = encs.size(); // find the lowest item that we are less than or equal to int i; for(i=0; i < size; i++) { if( compare(enc, (byte[])encs.elementAt(i)) < 1 ) { break; } } // insert ourself before this item encs.insertElementAt(enc, i); } // performs ascending ordering by tag // linear search, but number of items is usually going to be small. private static void insertInOrder(Vector encs, byte[] enc, Vector tags, int tag) { int size = encs.size(); // find the lowest item that we are less than or equal to int i; for(i = 0; i < size; i++) { if( tag <= ((Integer)tags.elementAt(i)).intValue() ) { break; } } // insert ourself before this item encs.insertElementAt(enc, i); tags.insertElementAt(new Integer(i), i ); } // compares two byte arrays // returns 1 if left > right, -1 if left < right, 0 if left == right private static int compare(byte[] left, byte[] right) { int min = (left.length < right.length) ? left.length : right.length; for(int i=0; i < min; i++) { if( (left[i]&0xff) < (right[i]&0xff) ) { return -1; } else if( (left[i]&0xff) > (right[i]&0xff) ) { return 1; } } // equal up to the minimal endpoint if( left.length > min ) { Assert._assert(right.length==min); return 1; } if( right.length > min ) { Assert._assert(left.length==min); return -1; } return 0; } /** * An element of a SET */ static class Element { /** * Makes a new SET element from the given value. */ public Element( ASN1Value val ) { this.val = val; } /** * Makes a new SET element from the given value with the given * implicit tag. */ public Element( Tag implicitTag, ASN1Value val ) { this.val = val; this.implicitTag = implicitTag; } private ASN1Value val; /** * Returns the value of this SET element. */ public ASN1Value getValue() { return val; } /** * Returns the tag that actually shows up in the encoding. * If there is an implicit tag, it will be used. Otherwise, * it will be the base tag for the value. */ public Tag getTag() { if(implicitTag!=null) { return implicitTag; } else { return val.getTag(); } } private Tag implicitTag=null; /** * Returns the implicit tag for this value, if there is one. * If not, returns null. */ public Tag getImplicitTag() { return implicitTag; } } /** * SET.Template * This class is used for decoding DER-encoded SETs. */ public static class Template implements ASN1Template { private Vector elements = new Vector(); private void addElement( Element e ) { elements.addElement(e); } private void insertElementAt( Element e, int index ) { elements.insertElementAt(e, index); } /** * Adds a sub-template to the end of this SET template. For example, * if the ASN.1 included: *
     * MySet ::= SET {
     *      item        SubType,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new SubType.Template() );
     * 
*/ public void addElement( ASN1Template t ) { addElement( new Element(TAG, t, false) ); } /** * Inserts the template at the given index. */ public void insertElementAt( ASN1Template t, int index ) { insertElementAt( new Element(TAG, t, false), index ); } /** * Adds a sub-template with the given implicit tag to the end of this * SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        [0] IMPLICIT SubType,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new Tag(0), new SubType.Template() );
     * 
*/ public void addElement( Tag implicit, ASN1Template t ) { addElement( new Element(implicit, t, false) ); } /** * Inserts the template with the given implicit tag at the given index. */ public void insertElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, false), index ); } /** * Adds an optional sub-template to the end * of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addOptionalElement( new SubType.Template() );
     * 
*/ public void addOptionalElement( ASN1Template t ) { addElement( new Element(TAG, t, true) ); } /** * Inserts the optional template at the given index. */ public void insertOptionalElementAt( ASN1Template t, int index ) { insertElementAt( new Element(null, t, true), index ); } /** * Adds an optional sub-template with the given implicit tag to the end * of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        [0] IMPLICIT SubType OPTIONAL,
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addOptionalElement( new Tag(0), new SubType.Template() );
     * 
*/ public void addOptionalElement( Tag implicit, ASN1Template t ) { addElement( new Element(implicit, t, true) ); } /** * Inserts the optional template with the given default * value at the given index. */ public void insertOptionalElementAt( Tag implicit, ASN1Template t, int index ) { insertElementAt( new Element(implicit, t, true), index ); } /** * Adds a sub-template with the given default value to the end * of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        INTEGER DEFAULT (5),
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new SubType.Template(), new INTEGER(5) );
     * 
*/ public void addElement( ASN1Template t, ASN1Value def ) { addElement( new Element(TAG, t, def) ); } /** * Inserts the template with the given default * value at the given index. */ public void insertElementAt( ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(null, t, def), index ); } /** * Adds a sub-template with the given default value and implicit tag to * the end of this SET template. For example, if the ASN.1 included: *
     * MySet ::= SET {
     *      item        [0] IMPLICIT INTEGER DEFAULT (5),
     *      ... }
     * 
* the "item" element would be added to the MySet template with: *
     *  mySet.addElement( new Tag(0), new SubType.Template(), new INTEGER(5) );
     * 
*/ public void addElement( Tag implicit, ASN1Template t, ASN1Value def ) { addElement( new Element(implicit, t, def) ); } /** * Inserts the template with the given implicit tag and given default * value at the given index. */ public void insertElementAt( Tag implicit, ASN1Template t, ASN1Value def, int index ) { insertElementAt( new Element(implicit, t, def), index ); } /** * Returns the implicit tag of the item stored at the given index. * May be NULL if no implicit tag was specified. */ public Tag implicitTagAt(int index) { return ((Element)elements.elementAt(index)).getImplicitTag(); } /** * Returns the sub-template stored at the given index. */ public ASN1Template templateAt(int index) { return ((Element)elements.elementAt(index)).getTemplate(); } /** * Returns true if the sub-template at the given index * is optional. */ public boolean isOptionalAt(int index) { return ((Element)elements.elementAt(index)).isOptional(); } private boolean isRepeatableAt(int index) { return ((Element)elements.elementAt(index)).isRepeatable(); } /** * Returns the default value for the sub-template at the given index. * May return NULL if no default value was specified. */ public ASN1Value defaultAt(int index) { return ((Element)elements.elementAt(index)).getDefault(); } /** * Returns the number of elements in the SET. */ public int size() { return elements.size(); } public void removeAllElements() { elements.removeAllElements(); } public void removeElementAt(int index) { elements.removeElementAt(index); } private Tag getTag() { return SET.TAG; } /** * Determines whether the given tag satisfies this template. */ public boolean tagMatch(Tag tag) { return( tag.equals(SET.TAG) ); } /** * Decodes the input stream into a SET value. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } /** * Decodes the input stream into a SET value with the given implicit * tag. */ public ASN1Value decode(Tag tag, InputStream istream) throws IOException, InvalidBERException { try { ASN1Header header = new ASN1Header(istream); header.validate( tag, Form.CONSTRUCTED ); // remainingContent will be -1 for indefinite length encoding long remainingContent = header.getContentLength(); SET set = new SET(); ASN1Header lookAhead; boolean[] found = new boolean[ elements.size() ]; // while content remains, try to decode it while( remainingContent > 0 || remainingContent == -1) { // find out about the next item lookAhead = ASN1Header.lookAhead(istream); // if we found the end-of-content marker, we're done if( lookAhead.isEOC() ) { if( remainingContent != -1 ) { throw new InvalidBERException("Unexpected end-of-content"+ "marker"); } lookAhead = new ASN1Header(istream); break; } // Find the element with the matching tag int index = findElementByTag( lookAhead.getTag() ); if( index == -1 ) { // element not found throw new InvalidBERException("Unexpected Tag in SET: "+ lookAhead.getTag() ); } Element e = (Element) elements.elementAt(index); if( found[index] && ! e.isRepeatable() ) { // element already found, and it's not repeatable throw new InvalidBERException("Duplicate Tag in SET: "+ lookAhead.getTag() ); } // mark this element as found found[index] = true; // Decode this element ASN1Template t = e.getTemplate(); ASN1Value val; CountingStream countstream = new CountingStream(istream); if( e.getImplicitTag() == null ) { val = t.decode(countstream); } else { val = t.decode(e.getImplicitTag(), countstream); } // Decrement remaining count long len = countstream.getNumRead(); if( remainingContent != -1 ) { if( remainingContent < len ) { // this item went past the end of the SET throw new InvalidBERException("Item went "+ (len-remainingContent)+" bytes past the end of"+ " the SET"); } remainingContent -= len; } // Store this element in the SET SET.Element se; if( e.getImplicitTag() == null ) { // no implicit tag se = new SET.Element(val); } else { // there is an implicit tag se = new SET.Element( e.getImplicitTag(), val ); } set.addElement(se); } // We check for this after we read in each item, so this shouldn't // happen Assert._assert( remainingContent == 0 || remainingContent == -1); // Deal with elements that weren't present. int size = elements.size(); for(int i = 0; i < size; i++) { if( !found[i] ) { if( isOptionalAt(i) || isRepeatableAt(i) ) { // no problem } else if( defaultAt(i) != null ) { set.addElement( new SET.Element(defaultAt(i)) ); } else { throw new InvalidBERException("Field not found in SET"); } } } return set; } catch(InvalidBERException e) { throw new InvalidBERException(e, "SET"); } } /** * Returns the index in the vector of the type with this tag and class, * or -1 if not found. * lame linear search - but we're dealing with small numbers of elements, * so it's probably not worth it to use a hashtable */ private int findElementByTag(Tag tag) { int size = elements.size(); for( int i = 0; i < size ; i++ ) { Element e = (Element) elements.elementAt(i); if( e.tagMatch( tag ) ) { // match! return i; } } // no match return -1; } /** * An element of a SET template. */ public static class Element { public Element(Tag implicitTag, ASN1Template type, boolean optional) { this.type = type; defaultVal = null; this.optional = optional; this.implicitTag = implicitTag; } public Element(Tag implicitTag, ASN1Template type, ASN1Value defaultVal) { this.type = type; this.defaultVal = defaultVal; optional = false; this.implicitTag = implicitTag; } // Repeatability is used for SET OF. It is package private. private boolean repeatable; void makeRepeatable() { repeatable = true; } boolean isRepeatable() { return repeatable; } private boolean optional; public boolean isOptional() { return optional; } private Tag implicitTag=null; public Tag getImplicitTag() { return implicitTag; } /** * Determines whether the given tag satisfies this SET element. */ public boolean tagMatch(Tag tag) { if( implicitTag != null ) { return( implicitTag.equals(tag) ); } else { return type.tagMatch(tag); } } private ASN1Template type; /** * Returns the template for this element. */ public ASN1Template getTemplate() { return type; } private ASN1Value defaultVal=null; /** * Returns the default value for this element, if one exists. * Otherwise, returns null. */ public ASN1Value getDefault() { return defaultVal; } } } // End of SET.Template /** * A Template for decoding SET OF values. * Use this if you have a SIZE qualifier on your SET OF. * The SET will consume as many instances of type as it can, rather than * stopping after the first one. This is equivalent to SIZE (0..MAX). * If you need something more restrictive, you can look at what gets parsed * and decide whether it's OK or not yourself. */ public static class OF_Template implements ASN1Template { private OF_Template() { } private Template template; // a normal SET template /** * Creates an OF_Template with the given type. For example: *
     * MySet ::= SET OF INTEGER;
     * 
* A MySet template would be constructed with: *
     * SET.OF_Template mySetTemplate = new SET.OF_Template( new
     *                                          INTEGER.Template() );
     * 
*/ public OF_Template(ASN1Template type) { template = new Template(); Template.Element el = new Template.Element( null, type, false ); el.makeRepeatable(); template.addElement( el ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } /** * Decodes a SET OF from its BER encoding. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return template.decode(istream); } /** * Decodes a SET OF with an implicit tag from its BER * encoding. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return template.decode(implicitTag, istream); } } // Test driver for SET public static void main(String args[]) { try { if(args.length > 0) { FileInputStream fin = new FileInputStream( args[0] ); Template t = new SET.Template(); t.addElement(new Tag(0), new INTEGER.Template() ); t.addElement( new Tag(3), new INTEGER.Template() ); t.addOptionalElement( new Tag(4), new INTEGER.Template() ); t.addElement( new Tag(5), new INTEGER.Template(), new INTEGER(67) ); t.addElement( new Tag(29), new BOOLEAN.Template() ); t.addElement( new Tag(30), new BOOLEAN.Template(), new BOOLEAN(false) ); t.addElement( new Tag(1), new INTEGER.Template() ); t.addElement( new Tag(2), new INTEGER.Template() ); SET st = (SET) t.decode(new BufferedInputStream(fin) ); for(int i=0; i < st.size(); i++) { ASN1Value v = st.elementAt(i); if( v instanceof INTEGER ) { INTEGER in = (INTEGER) st.elementAt(i); System.out.println("INTEGER: "+in); } else if( v instanceof BOOLEAN ) { BOOLEAN bo = (BOOLEAN) st.elementAt(i); System.out.println("BOOLEAN: "+bo); } else { System.out.println("Unknown value"); } } } else { SET s = new SET(); s.addElement( new Tag(0), new INTEGER(255) ); s.addElement( new Tag(29), new BOOLEAN(true) ); s.addElement( new Tag(1), new INTEGER(-322) ); s.addElement( new Tag(2), new INTEGER(0) ); s.addElement( new Tag(3), new INTEGER("623423948273") ); s.encode(System.out); } } catch( Exception e ) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/asn1/Tag.java000066400000000000000000000115321326145000000203660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.math.BigInteger; /** * Represents an ASN.1 Tag. A tag consists of a class and a number. */ public class Tag { private long num; /** * Returns the tag number. */ public long getNum() { return num; } private Class tClass; /** * Returns the tag class. */ public Class getTagClass() { return tClass; } private Tag() { } /** * A tag class. */ public static final Class UNIVERSAL = Class.UNIVERSAL; /** * A tag class. */ public static final Class APPLICATION = Class.APPLICATION; /** * A tag class. */ public static final Class CONTEXT_SPECIFIC = Class.CONTEXT_SPECIFIC; /** * A tag class. */ public static final Class PRIVATE = Class.PRIVATE; /** * The end-of-contents marker for indefinite length encoding. * It is encoded the same as an ASN.1 header whose tag is [UNIVERSAL 0]. */ public static final Tag END_OF_CONTENTS = new Tag( UNIVERSAL, 0 ); /** * An alias for END_OF_CONTENTS. */ public static final Tag EOC = END_OF_CONTENTS; /** * Creates a tag with the given class and number. * @param clazz The class of the tag. * @param num The tag number. */ public Tag(Class clazz, long num) { tClass = clazz; this.num = num; } /** * Creates a CONTEXT-SPECIFIC tag with the given tag number. * @param num The tag number. */ public Tag(long num) { this(Class.CONTEXT_SPECIFIC, num); } /////////////////////////////////////////////////////////////////////// // Tag Instances // // Since grabbing a context-specific tag is a very common operation, // let's make singletons of the most frequently used tags. /////////////////////////////////////////////////////////////////////// private static final int numTagInstances = 10; private static Tag tagInstances[] = new Tag[numTagInstances]; static { for(int i=0; i < numTagInstances; i++) { tagInstances[i] = new Tag(i); } } /** * Returns an instance of a context-specific tag with the given number. * The returned instance may be singleton. It is usually more efficient to * call this method than create your own context-specific tag. */ public static Tag get(long num) { if( num >= 0 && num < numTagInstances ) { return tagInstances[(int)num]; } else { return new Tag(num); } } public int hashCode() { return (tClass.toInt() * 131) + (int)num; } /** * Compares two tags for equality. Tags are equal if they have * the same class and tag number. */ public boolean equals(Object obj) { if(obj == null) { return false; } if(! (obj instanceof Tag) ) { return false; } Tag t = (Tag) obj; if( num == t.num && tClass == t.tClass ) { return true; } else { return false; } } /** * Returns a String representation of the tag. For example, a tag * whose class was UNIVERSAL and whose number was 16 would return * "UNIVERSAL 16". */ public String toString() { return tClass+" "+num; } /** * An enumeration of the ASN.1 tag classes. */ public static class Class { private Class() { } private Class(int enc, String name) { encoding = enc; this.name = name; } private int encoding; private String name; public static final Class UNIVERSAL = new Class(0, "UNIVERSAL"); public static final Class APPLICATION = new Class(1, "APPLICATION"); public static final Class CONTEXT_SPECIFIC = new Class(2, "CONTEXT-SPECIFIC"); public static final Class PRIVATE = new Class(3, "PRIVATE"); public int toInt() { return encoding; } public String toString() { return name; } /** * @exception InvalidBERException If the given int does not correspond * to any tag class. */ public static Class fromInt(int i) throws InvalidBERException { if( i == 0 ) { return UNIVERSAL; } else if(i == 1) { return APPLICATION; } else if(i == 2) { return CONTEXT_SPECIFIC; } else if(i == 3) { return PRIVATE; } else { throw new InvalidBERException("Invalid tag class: " + i); } } } } jss-4.4.3/jss/org/mozilla/jss/asn1/TeletexString.java000066400000000000000000000050571326145000000224610ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; /** * The ASN.1 type TeletexString. */ public class TeletexString extends CharacterString implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 20); public Tag getTag() { return TAG; } public TeletexString(char[] chars) throws CharConversionException { super(chars); } public TeletexString(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new TeletexConverter(); } /** * Returns a singleton instance of the decoding template for this class. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new TeletexConverter(); } protected CharacterString generateInstance(char[] bytes) throws CharConversionException { return new TeletexString( bytes ); } protected String typeName() { return "TeletexString"; } } // end of Template private static class TeletexConverter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { char[] chars = new char[len]; int b; int c; for(b=offset, c=0; c < len; b++, c++) { chars[c] = (char) (bytes[b] & 0xff); } return chars; } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { byte[] bytes = new byte[len]; int b; int c; for(b=0, c=offset; b < len; b++, c++) { if( (chars[c]&0xff00) != 0 ) { throw new CharConversionException("Invalid character for"+ " TeletexString"); } bytes[b] = (byte) (chars[c] & 0xff); } return bytes; } } } jss-4.4.3/jss/org/mozilla/jss/asn1/TimeBase.java000066400000000000000000000230011326145000000213360ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import org.mozilla.jss.util.Assert; public abstract class TimeBase implements ASN1Value { public static final Form FORM = Form.PRIMITIVE; abstract public Tag getTag(); private Date date; public Date toDate() { return date; } abstract protected boolean isUTC(); private TimeBase() { } public TimeBase(Date date) { this.date = date; } public void encode(OutputStream ostream) throws IOException { encode(getTag(), ostream); } /** * Write the DER-encoding of this TimeBase. */ public void encode(Tag implicit, OutputStream ostream) throws IOException { if( isUTC() ) { // length will always be 13 (new ASN1Header(implicit, FORM, 13)).encode(ostream); } else { // length will always be 15 (new ASN1Header(implicit, FORM, 15)).encode(ostream); } int i=0, val; // DER-encoding mandates GMT time zone Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") ); cal.setTime( date ); if( isUTC() ) { val = cal.get(Calendar.YEAR); ostream.write( ((val % 100) / 10) + '0' ); ostream.write( (val % 10) + '0' ); } else { val = cal.get(Calendar.YEAR); ostream.write( ((val % 10000) / 1000) + '0' ); ostream.write( ((val % 1000) / 100) + '0' ); ostream.write( ((val % 100) / 10) + '0' ); ostream.write( (val % 10) + '0' ); } val = cal.get(Calendar.MONTH) + 1; Assert._assert( val >= 1 && val <= 12 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.DAY_OF_MONTH); Assert._assert( val >=1 && val <= 31 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.HOUR_OF_DAY); Assert._assert( val >= 0 && val <= 23 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.MINUTE); Assert._assert( val >=0 && val <= 59 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); val = cal.get(Calendar.SECOND); Assert._assert( val >= 0 && val <= 59 ); ostream.write( (val / 10) + '0' ); ostream.write( (val % 10) + '0' ); ostream.write('Z'); } public abstract static class Template { protected abstract boolean isUTC(); protected abstract Tag getTag(); protected abstract TimeBase generateInstance(Date date); public boolean tagMatch(Tag tag) { return getTag().equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(), istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { PrintableString.Template pst = new PrintableString.Template(); PrintableString ps = (PrintableString) pst.decode(implicitTag, istream); char[] chars = ps.toCharArray(); int i=0; int year, month, day, hour, minute, second, hourOff, minOff; ////////////////////////////////////////// // Get year // if( isUTC() ) { checkBounds(i, 2, chars.length); year = (chars[i] - '0') * 10; year += chars[i+1] - '0'; // Y2K HACK!!!!! But this is what the spec says to do. // The range is 1970 to 2069 if( year < 70 ) { year += 2000; } else { year += 1900; } i += 2; } else { checkBounds(i, 4, chars.length); year = (chars[i] - '0') * 1000; year += (chars[i+1] - '0') * 100; year += (chars[i+2] - '0') * 10; year += (chars[i+3] - '0'); checkRange(year, 0, 9999, "year"); i += 4; } ////////////////////////////////////////// // get month // month = 0; checkBounds(i, 2, chars.length); month = (chars[i] - '0') * 10; month += chars[i+1] - '0'; checkRange(month, 1, 12, "month"); month--; // Java months start at 0 i += 2; ////////////////////////////////////////// // get day // checkBounds(i, 2, chars.length); day = (chars[i] - '0') * 10; day += chars[i+1] - '0'; checkRange(day, 1, 31, "day"); i += 2; ////////////////////////////////////////// // get hour // checkBounds(i, 2, chars.length); hour = (chars[i] - '0') * 10; hour += chars[i+1] - '0'; checkRange(hour, 0, 23, "hour"); i += 2; ////////////////////////////////////////// // get minute // checkBounds(i, 2, chars.length); minute = (chars[i] - '0') * 10; minute += chars[i+1] - '0'; checkRange(minute, 0, 59, "minute"); i += 2; ////////////////////////////////////////// // get second, if it's there // if( i < chars.length && chars[i] >= '0' && chars[i] <= '9' ) { checkBounds(i, 2, chars.length); second = (chars[i] - '0') * 10; second += chars[i+1] - '0'; checkRange(second, 0, 59, "second"); i += 2; } else { second = 0; } ////////////////////////////////////////// // Skip milliseconds for GeneralizedTime. There are no // milliseconds in UTCTime. // if( ! isUTC() ) { while( i < chars.length && chars[i] != '+' && chars[i] != '-' && chars[i] != 'Z' ) { i++; } } ////////////////////////////////////////// // get time zone // TimeZone tz; if( i < chars.length ) { checkBounds(i, 1, chars.length); if( chars[i] == '+' || chars[i] == '-') { checkBounds(i+1, 4, chars.length); hourOff = (chars[i+1] - '0') * 10; hourOff += chars[i+2] - '0'; minOff = (chars[i+3] - '0') * 10; minOff += chars[i+4] - '0'; checkRange(hourOff, 0, 23, "hour offset"); checkRange(minOff, 0, 59, "minute offset"); if( chars[i] == '-' ) { hourOff = -hourOff; minOff = -minOff; } i += 5; tz = (TimeZone) TimeZone.getTimeZone("GMT").clone(); tz.setRawOffset( ((hourOff*60)+minOff)*60*1000 ); } else if( chars[i] == 'Z' ) { i += 1; hourOff = minOff = 0; tz = (TimeZone) TimeZone.getTimeZone("GMT").clone(); } else { throw new InvalidBERException("Invalid character "+ chars[i]); } } else { if( isUTC() ) { // Only UTC requires timezone throw new InvalidBERException("no timezone specified for"+ " UTCTime"); } // No timezone specified, use local time. // This is generally a bad idea, because who knows what the // local timezone is? But the spec allows it. tz = TimeZone.getDefault(); } // make sure we ate all the characters, there were no stragglers // at the end if( i != chars.length ) { throw new InvalidBERException("Extra characters at end"); } // Create a calendar object from the date and time zone. Calendar cal = Calendar.getInstance( tz ); cal.set(year, month, day, hour, minute, second); return generateInstance(cal.getTime()); } private static void checkRange(int val, int low, int high, String field) throws InvalidBERException { if( val < low || val > high ) { throw new InvalidBERException("Invalid "+field); } } private static void checkBounds(int index, int increment, int bound) throws InvalidBERException { if(index+increment > bound) { throw new InvalidBERException("Too few characters in " + "TimeBase"); } } } } jss-4.4.3/jss/org/mozilla/jss/asn1/UTCTime.java000066400000000000000000000023411326145000000211230ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.IOException; import java.util.Date; public class UTCTime extends TimeBase implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 23); public Tag getTag() { return TAG; } public UTCTime(Date date) { super(date); } protected boolean isUTC() { return true; } private static final UTCTime.Template templateInstance = new UTCTime.Template(); public static UTCTime.Template getTemplate() { return templateInstance; } public static class Template extends TimeBase.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected boolean isUTC() { return true; } protected TimeBase generateInstance(Date date) { return new UTCTime(date); } } } jss-4.4.3/jss/org/mozilla/jss/asn1/UTF8String.java000066400000000000000000000052251326145000000215720ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; import java.io.UnsupportedEncodingException; import org.mozilla.jss.util.Assert; public class UTF8String extends CharacterString implements ASN1Value { public UTF8String(char[] chars) throws CharConversionException { super(chars); } public UTF8String(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new UTF8Converter(); } public static final Tag TAG = new Tag( Tag.UNIVERSAL, 12 ); public static final Form FORM = Form.PRIMITIVE; public Tag getTag() { return TAG; } private static final Template templateInstance = new Template(); /** * Returns a singleton instance of UTF8String.Template. This is more * efficient than creating a new UTF8String.Template. */ public static Template getTemplate() { return templateInstance; } // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new UTF8Converter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new UTF8String(chars); } protected String typeName() { return "UTF8String"; } } private static class UTF8Converter implements CharConverter { public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { try { String s = new String(bytes, offset, len, "UTF8"); return s.toCharArray(); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UTF8 encoding mechanism"; Assert.notReached(err); throw new CharConversionException(err); } } public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { try { String s = new String(chars, offset, len); return s.getBytes("UTF8"); } catch( UnsupportedEncodingException e ) { String err = "Unable to find UTF8 encoding mechanism"; Assert.notReached(err); throw new CharConversionException(err); } } } // end of char converter } jss-4.4.3/jss/org/mozilla/jss/asn1/UniversalString.java000066400000000000000000000152061326145000000230140ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.asn1; import java.io.CharConversionException; import java.io.CharArrayWriter; import java.io.ByteArrayOutputStream; /** * A UCS4 string. */ public class UniversalString extends CharacterString implements ASN1Value { public static final Tag TAG = new Tag(Tag.UNIVERSAL, 28); public Tag getTag() { return TAG; } public UniversalString(char[] chars) throws CharConversionException { super(chars); } public UniversalString(String s) throws CharConversionException { super(s); } CharConverter getCharConverter() { return new UniversalConverter(); } /** * Returns a singleton instance of the decoding template for this class. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); // nested class public static class Template extends CharacterString.Template implements ASN1Template { protected Tag getTag() { return TAG; } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } protected CharConverter getCharConverter() { return new UniversalConverter(); } protected CharacterString generateInstance(char[] chars) throws CharConversionException { return new UniversalString( chars ); } protected String typeName() { return "UniversalString"; } } // end of Template /** * A class for converting between Unicode and UCS4. */ private static class UniversalConverter implements CharConverter { // This is the maximum a UCS4 character can be if it has // straight Unicode inside it. public static final int MAX_UNICODE = 0x0000ffff; // This is the maximum a UCS4 character can be if it is UTF-16 // encoded. UTF-16 encoding allows UCS4 chars to be stored across // two Unicode chars. public static final int MAX_UTF16 = 0x0010ffff; // This Unicode character is used to represent an unknown character // in some other encoding. We use it for UCS4 characters that // are not a part of normal Unicode and also cannot be encoded // across two Unicode chars with UTF-16. public static final char REPLACEMENT_CHAR = 0xfffd; // This is the base for UCS4 characters that can be mapped with UTF16. public static final int UTF16_BASE = 0x00100000; // In UTF16 encoding, each Unicode character has 10 bits of // information. public static final int HALF_SHIFT = 10; // The lowest 10 bits public static final int HALF_MASK = 0x3ff; public static final int UTF16_HIGH_START = 0xd800; public static final int UTF16_HIGH_END = 0xdcff; public static final int UTF16_LOW_START = 0xdc00; public static final int UTF16_LOW_END = 0xdfff; /** * Turns big-endian UCS4 characters into Unicode Java characters */ public char[] byteToChar(byte[] bytes, int offset, int len) throws CharConversionException { // Each UCS4 character is 4 bytes. Most UCS4 characters will // map to one Unicode character. The exception is UTF-16 // characters, which map to two Unicode characters. CharArrayWriter out = new CharArrayWriter( len / 4 ); int end = offset + len; while( offset < end ) { // eat 4 bytes and make a UCS4 char if( end - offset < 4 ) { throw new CharConversionException("input exhausted"); } int ucs4 = (bytes[offset++] & 0xff) << 24; ucs4 += (bytes[offset++] & 0xff) << 16; ucs4 += (bytes[offset++] & 0xff) << 8; ucs4 += bytes[offset++] & 0xff; // convert UCS4 to Unicode if( ucs4 <= MAX_UNICODE ) { // Unicode is a subset of UCS4, and this char is // in the common subset. Just chop off the unused top // two bytes. out.write( ucs4 & 0xffff ); } else if( ucs4 <= MAX_UTF16 ) { // This UCS4 char is not in Unicode, but can be encoded // into two Unicode chars using UTF16. ucs4 -= UTF16_BASE; out.write( (ucs4 >>> HALF_SHIFT) + UTF16_HIGH_START ); out.write( (ucs4 & HALF_MASK) + UTF16_LOW_START ); } else { // This character is not in Unicode or UTF16. We can't // provide a suitable translation, so use the Unicode // replacement char. out.write( REPLACEMENT_CHAR ); } } return out.toCharArray(); } // Convert Unicode chars to UCS4 chars public byte[] charToByte(char[] chars, int offset, int len) throws CharConversionException { ByteArrayOutputStream out = new ByteArrayOutputStream(len * 4); int end = offset + len; while( offset < end ) { char c = chars[offset++]; int ucs4; if( c >= UTF16_HIGH_START && c <= UTF16_HIGH_END ) { // This is the beginning of a UTF16 char if( offset == end ) { throw new CharConversionException("input exhausted"); } char low = chars[offset++]; // make sure the next char is the low half of a UTF16 char if( low < UTF16_LOW_START || low > UTF16_LOW_END ) { throw new CharConversionException("UTF16 high "+ "character not followed by a UTF16 low character"); } ucs4 = UTF16_BASE; ucs4 += (c - UTF16_HIGH_START) << HALF_SHIFT; ucs4 += low - UTF16_LOW_START; } else { // this is a normal Unicode char ucs4 = (c & 0x0000ffff); } out.write( (ucs4 & 0xff000000) >>> 24 ); out.write( (ucs4 & 0x00ff0000) >>> 16 ); out.write( (ucs4 & 0x0000ff00) >>> 8 ); out.write( (ucs4 & 0x000000ff) ); } return out.toByteArray(); } } } jss-4.4.3/jss/org/mozilla/jss/asn1/config.mk000066400000000000000000000004151326145000000206040ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/asn1/manifest.mn000066400000000000000000000075721326145000000211630ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 REQUIRES = nspr20 nss PACKAGE = org/mozilla/jss/asn1 CLASSES = \ ANY \ ASN1Header \ ASN1Template \ ASN1Util \ ASN1Value \ BIT_STRING \ BMPString \ BOOLEAN \ CharacterString \ CharConverter \ CHOICE \ CountingStream \ ENUMERATED \ EXPLICIT \ FieldNotPresentException \ Form \ GeneralizedTime \ IA5String \ INTEGER \ InvalidBERException \ NULL \ OBJECT_IDENTIFIER \ OCTET_STRING \ PrintableString \ SEQUENCE \ SET \ Tag \ TeletexString \ TimeBase \ UniversalString \ UTCTime \ UTF8String \ $(NULL) JSRCS = \ ANY.java \ ASN1Header.java \ ASN1Template.java \ ASN1Util.java \ ASN1Value.java \ BIT_STRING.java \ BMPString.java \ BOOLEAN.java \ CharacterString.java \ CharConverter.java \ CHOICE.java \ CountingStream.java \ ENUMERATED.java \ EXPLICIT.java \ FieldNotPresentException.java \ Form.java \ GeneralizedTime.java \ IA5String.java \ INTEGER.java \ InvalidBERException.java \ NULL.java \ OBJECT_IDENTIFIER.java \ OCTET_STRING.java \ PrintableString.java \ SEQUENCE.java \ SET.java \ Tag.java \ TeletexString.java \ TimeBase.java \ UniversalString.java \ UTCTime.java \ UTF8String.java \ $(NULL) CSRCS = \ ASN1Util.c \ $(NULL) LIBRARY_NAME = jssasn1 jss-4.4.3/jss/org/mozilla/jss/asn1/package.html000066400000000000000000000004441326145000000212710ustar00rootroot00000000000000 ASN.1 structures, BER decoding, and DER encoding. jss-4.4.3/jss/org/mozilla/jss/config.mk000066400000000000000000000004161326145000000177430ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE=1 jss-4.4.3/jss/org/mozilla/jss/crypto/000077500000000000000000000000001326145000000174645ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/crypto/Algorithm.c000066400000000000000000000207401326145000000215610ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include "_jni/org_mozilla_jss_crypto_Algorithm.h" #include "Algorithm.h" static PRStatus getAlgInfo(JNIEnv *env, jobject alg, JSS_AlgInfo *info); /*********************************************************************** ** ** Algorithm indices. This must be kept in sync with the algorithm ** tags in the Algorithm class. ** We only store CKMs as a last resort if there is no corresponding ** SEC_OID. **/ JSS_AlgInfo JSS_AlgTable[NUM_ALGS] = { /* 0 */ {SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 1 */ {SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 2 */ {SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 3 */ {SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, SEC_OID_TAG}, /* 4 */ {SEC_OID_PKCS1_RSA_ENCRYPTION, SEC_OID_TAG}, /* 5 */ {CKM_RSA_PKCS_KEY_PAIR_GEN, PK11_MECH}, /* 6 */ {CKM_DSA_KEY_PAIR_GEN, PK11_MECH}, /* 7 */ {SEC_OID_ANSIX9_DSA_SIGNATURE, SEC_OID_TAG}, /* 8 */ {SEC_OID_RC4, SEC_OID_TAG}, /* 9 */ {SEC_OID_DES_ECB, SEC_OID_TAG}, /* 10 */ {SEC_OID_DES_CBC, SEC_OID_TAG}, /* 11 */ {CKM_DES_CBC_PAD, PK11_MECH}, /* 12 */ {CKM_DES3_ECB, PK11_MECH}, /* 13 */ {SEC_OID_DES_EDE3_CBC, SEC_OID_TAG}, /* 14 */ {CKM_DES3_CBC_PAD, PK11_MECH}, /* 15 */ {CKM_DES_KEY_GEN, PK11_MECH}, /* 16 */ {CKM_DES3_KEY_GEN, PK11_MECH}, /* 17 */ {CKM_RC4_KEY_GEN, PK11_MECH}, /* 18 */ {SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC, SEC_OID_TAG}, /* 19 */ {SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC, SEC_OID_TAG}, /* 20 */ {SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC, SEC_OID_TAG}, /* 21 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4, SEC_OID_TAG}, /* 22 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4, SEC_OID_TAG}, /* 23 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC, SEC_OID_TAG}, /* 24 */ {SEC_OID_MD2, SEC_OID_TAG}, /* 25 */ {SEC_OID_MD5, SEC_OID_TAG}, /* 26 */ {SEC_OID_SHA1, SEC_OID_TAG}, /* 27 */ {CKM_SHA_1_HMAC, PK11_MECH}, /* 28 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC, SEC_OID_TAG}, /* 29 */ {SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC, SEC_OID_TAG}, /* 30 */ {SEC_OID_RC2_CBC, SEC_OID_TAG}, /* 31 */ {CKM_PBA_SHA1_WITH_SHA1_HMAC, PK11_MECH}, /* 32 */ {CKM_AES_KEY_GEN, PK11_MECH}, /* 33 */ {CKM_AES_ECB, PK11_MECH}, /* 34 */ {CKM_AES_CBC, PK11_MECH}, /* 35 */ {CKM_AES_CBC_PAD, PK11_MECH}, /* 36 */ {CKM_RC2_CBC_PAD, PK11_MECH}, /* 37 */ {CKM_RC2_KEY_GEN, PK11_MECH}, /* 38 */ {SEC_OID_SHA256, SEC_OID_TAG}, /* 39 */ {SEC_OID_SHA384, SEC_OID_TAG}, /* 40 */ {SEC_OID_SHA512, SEC_OID_TAG}, /* 41 */ {SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 42 */ {SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 43 */ {SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION, SEC_OID_TAG}, /* 44 */ {SEC_OID_ANSIX962_EC_PUBLIC_KEY, SEC_OID_TAG}, /* 45 */ {SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE, SEC_OID_TAG}, /* 46 */ {CKM_EC_KEY_PAIR_GEN, PK11_MECH}, /* 47 */ {SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, SEC_OID_TAG}, /* 48 */ {SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE, SEC_OID_TAG}, /* 49 */ {SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE, SEC_OID_TAG}, /* 50 */ {SEC_OID_HMAC_SHA256, SEC_OID_TAG}, /* 51 */ {SEC_OID_HMAC_SHA384, SEC_OID_TAG}, /* 52 */ {SEC_OID_HMAC_SHA512, SEC_OID_TAG}, /* 53 */ {SEC_OID_PKCS5_PBKDF2, SEC_OID_TAG}, /* 54 */ {SEC_OID_PKCS5_PBES2, SEC_OID_TAG}, /* 55 */ {SEC_OID_PKCS5_PBMAC1, SEC_OID_TAG}, /* 56 */ {SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, SEC_OID_TAG}, /* 57 */ {CKM_NSS_AES_KEY_WRAP, PK11_MECH}, /* 58 */ {CKM_NSS_AES_KEY_WRAP_PAD, PK11_MECH}, /* 59 */ {SEC_OID_AES_128_ECB, SEC_OID_TAG}, /* 60 */ {SEC_OID_AES_128_CBC, SEC_OID_TAG}, /* 61 */ {SEC_OID_AES_192_ECB, SEC_OID_TAG}, /* 62 */ {SEC_OID_AES_192_CBC, SEC_OID_TAG}, /* 63 */ {SEC_OID_AES_256_ECB, SEC_OID_TAG}, /* 64 */ {SEC_OID_AES_256_CBC, SEC_OID_TAG} /* REMEMBER TO UPDATE NUM_ALGS!!! */ }; /*********************************************************************** * * J S S _ g e t P K 1 1 M e c h F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * CK_MECHANISM_TYPE corresponding to this algorithm, or * CKM_INVALID_MECHANISM if none exists. */ CK_MECHANISM_TYPE JSS_getPK11MechFromAlg(JNIEnv *env, jobject alg) { JSS_AlgInfo info; if( getAlgInfo(env, alg, &info) != PR_SUCCESS) { return CKM_INVALID_MECHANISM; } if( info.type == PK11_MECH ) { return (CK_MECHANISM_TYPE) info.val; } else { PR_ASSERT( info.type == SEC_OID_TAG ); return PK11_AlgtagToMechanism( (SECOidTag) info.val); } } /*********************************************************************** * * J S S _ g e t O i d T a g F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * SECOidTag corresponding to this algorithm, or SEC_OID_UNKNOWN * if none was found. */ SECOidTag JSS_getOidTagFromAlg(JNIEnv *env, jobject alg) { JSS_AlgInfo info; if( getAlgInfo(env, alg, &info) != PR_SUCCESS) { return SEC_OID_UNKNOWN; } if( info.type == SEC_OID_TAG ) { return (SECOidTag) info.val; } else { PR_ASSERT( info.type == PK11_MECH ); /* We only store things as PK11 mechanisms as a last resort if * there is no corresponding sec oid tag. */ return SEC_OID_UNKNOWN; } } /*********************************************************************** * * J S S _ g e t A l g I n d e x * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * The index obtained from the algorithm, or -1 if an exception was * thrown. */ static jint getAlgIndex(JNIEnv *env, jobject alg) { jclass algClass; jint index=-1; jfieldID indexField; PR_ASSERT(env!=NULL && alg!=NULL); algClass = (*env)->GetObjectClass(env, alg); #ifdef DEBUG /* Make sure this really is an Algorithm. */ { jclass realClass = ((*env)->FindClass(env, ALGORITHM_CLASS_NAME)); PR_ASSERT( (*env)->IsInstanceOf(env, alg, realClass) ); } #endif indexField = (*env)->GetFieldID( env, algClass, OID_INDEX_FIELD_NAME, OID_INDEX_FIELD_SIG); if(indexField==NULL) { ASSERT_OUTOFMEM(env); goto finish; } index = (*env)->GetIntField(env, alg, indexField); PR_ASSERT( (index >= 0) && (index < NUM_ALGS) ); finish: return index; } /*********************************************************************** * * J S S _ g e t E n u m F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * OUTPUTS * info * Pointer to a JSS_AlgInfo which will get the information about * this algorithm, if it is found. Must not be NULL. * RETURNS * PR_SUCCESS if the enum was found, otherwise PR_FAILURE. */ static PRStatus getAlgInfo(JNIEnv *env, jobject alg, JSS_AlgInfo *info) { jint index; PRStatus status = PR_FAILURE; PR_ASSERT(env!=NULL && alg!=NULL && info!=NULL); index = getAlgIndex(env, alg); if( index == -1 ) { goto finish; } *info = JSS_AlgTable[index]; status = PR_SUCCESS; finish: return status; } /*********************************************************************** * * EncryptionAlgorithm.getIVLength * */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_crypto_EncryptionAlgorithm_getIVLength (JNIEnv *env, jobject this) { CK_MECHANISM_TYPE mech; mech = JSS_getPK11MechFromAlg(env, this); if( mech == CKM_INVALID_MECHANISM ) { PR_ASSERT(PR_FALSE); return 0; } else { return PK11_GetIVLength(mech); } } /* * This must be synchronized with SymmetricKey.Usage */ CK_ULONG JSS_symkeyUsage[] = { CKA_ENCRYPT, /* 0 */ CKA_DECRYPT, /* 1 */ CKA_WRAP, /* 2 */ CKA_UNWRAP, /* 3 */ CKA_SIGN, /* 4 */ CKA_VERIFY, /* 5 */ 0UL }; jss-4.4.3/jss/org/mozilla/jss/crypto/Algorithm.h000066400000000000000000000031051326145000000215620ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* These headers must be included before this header: #include #include #include #include */ #ifndef JSS_ALGORITHM_H #define JSS_ALGORITHM_H PR_BEGIN_EXTERN_C typedef enum JSS_AlgType { PK11_MECH, /* CK_MECHANISM_TYPE */ SEC_OID_TAG /* SECOidTag */ } JSS_AlgType; typedef struct JSS_AlgInfoStr { unsigned long val; /* either a CK_MECHANISM_TYPE or a SECOidTag */ JSS_AlgType type; } JSS_AlgInfo; #define NUM_ALGS 65 extern JSS_AlgInfo JSS_AlgTable[]; extern CK_ULONG JSS_symkeyUsage[]; /*********************************************************************** * * J S S _ g e t O i d T a g F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * SECOidTag corresponding to this algorithm, or SEC_OID_UNKNOWN * if none was found. */ SECOidTag JSS_getOidTagFromAlg(JNIEnv *env, jobject alg); /*********************************************************************** * * J S S _ g e t P K 1 1 M e c h F r o m A l g * * INPUTS * alg * An org.mozilla.jss.Algorithm object. Must not be NULL. * RETURNS * CK_MECHANISM_TYPE corresponding to this algorithm, or * CKM_INVALID_MECHANISM if none was found. */ CK_MECHANISM_TYPE JSS_getPK11MechFromAlg(JNIEnv *env, jobject alg); PR_END_EXTERN_C #endif jss-4.4.3/jss/org/mozilla/jss/crypto/Algorithm.java000066400000000000000000000211421326145000000222550ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import java.security.NoSuchAlgorithmException; /** * Represents a cryptographic algorithm. * @see EncryptionAlgorithm * @see SignatureAlgorithm */ public class Algorithm { private Algorithm() { } /** * @param oidIndex Index of the oid that this algorithm represents. * @param name A String representation of the Algorithm. */ protected Algorithm(int oidIndex, String name) { this.oidIndex = oidIndex; this.name = name; } /** * @param oidIndex Index of the oid that this algorithm represents. * @param name A String representation of the Algorithm. * @param oid The object identifier for this Algorithm. */ protected Algorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid) { this(oidIndex, name); this.oid = oid; } protected Algorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, Class paramClass) { this(oidIndex, name, oid); if( paramClass == null ) { this.parameterClasses = new Class[0]; } else { this.parameterClasses = new Class[1]; this.parameterClasses[0] = paramClass; } } protected Algorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, Class []paramClasses) { this(oidIndex, name, oid); if( paramClasses != null ) { this.parameterClasses = paramClasses; } } /** * Returns a String representation of the algorithm. */ public String toString() { return name; } /** * Returns the object identifier for this algorithm. * @exception NoSuchAlgorithmException If no OID is registered for this * algorithm. */ public OBJECT_IDENTIFIER toOID() throws NoSuchAlgorithmException { if( oid == null ) { throw new NoSuchAlgorithmException(); } else { return oid; } } /** * The type of parameter that this algorithm expects. Returns * null if this algorithm does not take any parameters. * If the algorithm can accept more than one type of parameter, * this method returns only one of them. It is better to call * getParameterClasses(). * @deprecated Call getParameterClasses() instead. */ public Class getParameterClass() { if( parameterClasses.length == 0) { return null; } else { return parameterClasses[0]; } } /** * The types of parameter that this algorithm expects. Returns * null if this algorithm does not take any parameters. */ public Class[] getParameterClasses() { return (Class[]) parameterClasses.clone(); } /** * Returns true if the given Object can be used as a parameter * for this algorithm. *

If null is passed in, this method will return true * if this algorithm takes no parameters, and false * if this algorithm does take parameters. */ public boolean isValidParameterObject(Object o) { if( o == null ) { return (parameterClasses.length == 0); } if( parameterClasses.length == 0 ){ return false; } Class c = o.getClass(); for( int i = 0; i < parameterClasses.length; ++i) { if( c.equals( parameterClasses[i] ) ) { return true; } } return false; } /** * Index into the SECOidTag array in Algorithm.c. */ protected int oidIndex; String name; protected OBJECT_IDENTIFIER oid; private Class[] parameterClasses=new Class[0]; ////////////////////////////////////////////////////////////// // Algorithm OIDs ////////////////////////////////////////////////////////////// static final OBJECT_IDENTIFIER ANSI_X9_ALGORITHM = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10040, 4 } ); static final OBJECT_IDENTIFIER ANSI_X962_OID = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045 } ); // Algorithm indices. These must be kept in sync with the // algorithm array in Algorithm.c. protected static final short SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION=0; protected static final short SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION=1; protected static final short SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION=2; protected static final short SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST=3; protected static final short SEC_OID_PKCS1_RSA_ENCRYPTION=4; protected static final short CKM_RSA_PKCS_KEY_PAIR_GEN=5; protected static final short CKM_DSA_KEY_PAIR_GEN=6; protected static final short SEC_OID_ANSIX9_DSA_SIGNATURE=7; protected static final short SEC_OID_RC4=8; protected static final short SEC_OID_DES_ECB=9; protected static final short SEC_OID_DES_CBC=10; protected static final short CKM_DES_CBC_PAD=11; protected static final short CKM_DES3_ECB=12; protected static final short SEC_OID_DES_EDE3_CBC=13; protected static final short CKM_DES3_CBC_PAD=14; protected static final short CKM_DES_KEY_GEN=15; protected static final short CKM_DES3_KEY_GEN=16; protected static final short CKM_RC4_KEY_GEN=17; protected static final short SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC=18; protected static final short SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC=19; protected static final short SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC=20; protected static final short SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4=21; protected static final short SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4=22; protected static final short SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC=23; protected static final short SEC_OID_MD2=24; protected static final short SEC_OID_MD5=25; protected static final short SEC_OID_SHA1=26; protected static final short CKM_SHA_1_HMAC=27; protected static final short SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC=28; protected static final short SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC=29; protected static final short SEC_OID_RC2_CBC=30; protected static final short CKM_PBA_SHA1_WITH_SHA1_HMAC=31; // AES protected static final short CKM_AES_KEY_GEN=32; protected static final short CKM_AES_ECB=33; protected static final short CKM_AES_CBC=34; protected static final short CKM_AES_CBC_PAD=35; protected static final short CKM_RC2_CBC_PAD=36; protected static final short CKM_RC2_KEY_GEN=37; //FIPS 180-2 protected static final short SEC_OID_SHA256=38; protected static final short SEC_OID_SHA384=39; protected static final short SEC_OID_SHA512=40; protected static final short SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION=41; protected static final short SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION=42; protected static final short SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION=43; protected static final short SEC_OID_ANSIX962_EC_PUBLIC_KEY=44; protected static final short SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE=45; protected static final short CKM_EC_KEY_PAIR_GEN=46; protected static final short SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE=47; protected static final short SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE=48; protected static final short SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE=49; protected static final short SEC_OID_HMAC_SHA256=50; protected static final short SEC_OID_HMAC_SHA384=51; protected static final short SEC_OID_HMAC_SHA512=52; //PKCS5 V2 protected static final short SEC_OID_PKCS5_PBKDF2=53; protected static final short SEC_OID_PKCS5_PBES2=54; protected static final short SEC_OID_PKCS5_PBMAC1=55; protected static final short SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST=56; protected static final short CKM_NSS_AES_KEY_WRAP=57; protected static final short CKM_NSS_AES_KEY_WRAP_PAD=58; // AES Encryption Algorithms protected static final short SEC_OID_AES_128_ECB = 59; protected static final short SEC_OID_AES_128_CBC = 60; protected static final short SEC_OID_AES_192_ECB = 61; protected static final short SEC_OID_AES_192_CBC = 62; protected static final short SEC_OID_AES_256_ECB = 63; protected static final short SEC_OID_AES_256_CBC = 64; } jss-4.4.3/jss/org/mozilla/jss/crypto/AlreadyInitializedException.java000066400000000000000000000010621326145000000257540ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This exception is thrown if an initialization operation * is attempted on something that is already initialized. */ public class AlreadyInitializedException extends java.lang.Exception { public AlreadyInitializedException() {} public AlreadyInitializedException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/BadPaddingException.java000066400000000000000000000007431326145000000241670ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * @deprecated Use javax.crypto.BadPaddingException. */ public class BadPaddingException extends Exception { public BadPaddingException() { super(); } public BadPaddingException(String msg) { super(msg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/Cipher.java000066400000000000000000000161451326145000000215500ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.InvalidKeyException; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; import org.mozilla.jss.util.Assert; /** * A context for performing symmetric encryption and decryption. * First, the context must be initialized. Then, it can be updated * with input through zero or more calls to update. Finally, * doFinal is called to finalize the operation. Note that * it is not necessary to call update if all of the data is * available at once. In this case, all of the input can be processed with one * call to doFinal. */ public abstract class Cipher { /** * Initializes a encryption context with a symmetric key. */ public abstract void initEncrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Initializes a decryption context with a symmetric key. */ public abstract void initDecrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Initializes an encryption context with a symmetric key and * algorithm parameters. */ public abstract void initEncrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Initializes a decryption context with a symmetric key and * algorithm parameters. */ public abstract void initDecrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException; /** * Updates the encryption context with additional input. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @return Bytes of ciphertext (if encrypting) or plaintext (if decrypting). */ public abstract byte[] update(byte[] bytes) throws IllegalStateException, TokenException; /** * Updates the encryption context with additional plaintext. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @param offset The index in bytes at which to begin reading. * @param length The number of bytes from bytes to read. * @return Bytes of ciphertext (if encrypting) or plaintext (if decrypting). */ public abstract byte[] update(byte[] bytes, int offset, int length) throws IllegalStateException, TokenException; /** * Completes an cipher operation. This can be called directly after * the context is initialized, or update may be called * any number of times before calling final. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @return The last of the output. */ public abstract byte[] doFinal(byte[] bytes) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException; /** * Completes an cipher operation. * @param bytes Bytes of plaintext (if encrypting) or ciphertext (if * decrypting). * @param offset The index in bytes at which to begin reading. * @param length The number of bytes from bytes to read. * @return The last of the output. */ public abstract byte[] doFinal(byte[] bytes, int offset, int length) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException; /** * Completes an cipher operation. * @return The last of the output. */ public abstract byte[] doFinal() throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException; /** * Pads a byte array so that its length is a multiple of the given * blocksize. The method of padding is the one defined in the RSA * PKCS standards. If M is the length of the data and * B is the block size, the padding string consists of * B - (M mod B) octets, each having the value * B - (M mod B). * @param toBePadded The byte array to pad. * @param blockSize The block size of the encryption algorithm. Must be greater * than zero. * @see #unPad */ public static byte[] pad(byte[] toBePadded, int blockSize) { Assert._assert(blockSize > 0); // the padOctet is also the number of pad octets byte padOctet = (byte) (blockSize - (toBePadded.length % blockSize)); byte[] padded = new byte[toBePadded.length + padOctet]; System.arraycopy(toBePadded, 0, padded, 0, toBePadded.length); for(int i = toBePadded.length; i < padded.length; i++) { padded[i] = padOctet; } return padded; } /** * Un-pads a byte array that is padded with PKCS padding. * * @param blockSize The block size of the encryption algorithm. This * is only used for error checking: if the pad size is not * between 1 and blockSize, a BadPaddingException is thrown. * * @see #pad */ public static byte[] unPad(byte[] padded, int blockSize) throws BadPaddingException { if(padded.length == 0) { return new byte[0]; } if( padded.length < blockSize ) { throw new BadPaddingException("Length of padded array is less than"+ " one block"); } byte padOctet = padded[padded.length-1]; if(padOctet > blockSize) { throw new BadPaddingException("Padding octet ("+padOctet+") is "+ "larger than block size ("+blockSize+")"); } if(padOctet < 1) { throw new BadPaddingException("Padding octet is less than 1"); } byte[] unpadded = new byte[padded.length - padOctet]; System.arraycopy(padded, 0, unpadded, 0, unpadded.length); return unpadded; } /** * Un-pads a byte array that is padded with PKCS padding. Since * this version does not take block size as a parameter, it cannot * error check. * @see #pad */ public static byte[] unPad(byte[] padded) throws BadPaddingException { if(padded.length == 0) { return new byte[0]; } byte padOctet = padded[padded.length-1]; if(padOctet < 1) { throw new BadPaddingException("Padding octet is less than 1"); } else if(padOctet >= padded.length) { throw new BadPaddingException("Padding is larger than entire"+ " array"); } byte[] unpadded = new byte[padded.length - padOctet]; System.arraycopy(padded, 0, unpadded, 0, unpadded.length); return unpadded; } } jss-4.4.3/jss/org/mozilla/jss/crypto/CryptoStore.java000066400000000000000000000130731326145000000226300ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.*; import java.security.*; import java.security.cert.CertificateEncodingException; import java.io.Serializable; /** * This is an interface for a permanent repository of cryptographic objects, * such as keys, certs, and passwords. */ public interface CryptoStore { //////////////////////////////////////////////////////////// // Private Keys //////////////////////////////////////////////////////////// /** * Imports a raw private key into this token (permanently). * * @param key The private key. * @exception TokenException If the key cannot be imported to this token. * @exception KeyAlreadyImportedException If the key already exists on this token. */ public PrivateKey importPrivateKey( byte[] key, PrivateKey.Type type ) throws TokenException, KeyAlreadyImportedException; /** * Imports a raw private key into this token. * * @param key The private key. * @param temporary Whether the key should be temporary. * @exception TokenException If the key cannot be imported to this token. * @exception KeyAlreadyImportedException If the key already exists on this token. */ public PrivateKey importPrivateKey( byte[] key, PrivateKey.Type type, boolean temporary) throws TokenException, KeyAlreadyImportedException; /** * Returns all private keys stored on this token. * * @return An array of all private keys stored on this token. * @exception TokenException If an error occurs on the token while * gathering the keys. */ public PrivateKey[] getPrivateKeys() throws TokenException; /** * Returns all symmetric keys stored on this token. * * @return An array of all symmetric keys stored on this token. * @exception TokenException If an error occurs on the token while * gathering the keys. */ public SymmetricKey[] getSymmetricKeys() throws TokenException; /** * Deletes the given PrivateKey from the CryptoToken. * This is a very dangerous call: it deletes the key from the underlying * token. After calling this, the PrivateKey passed in must no longer * be used, or a TokenException will occur. * * @param key A PrivateKey to be permanently deleted. It must reside * on this token. * @exception NoSuchItemOnTokenException If the given private key does * not reside on this token. * @exception TokenException If an error occurs on the token while * deleting the key. */ public void deletePrivateKey(org.mozilla.jss.crypto.PrivateKey key) throws NoSuchItemOnTokenException, TokenException; /** * Get an encrypted private key for the given cert. * * @param cert Certificate of key to be exported * @param pbeAlg The PBEAlgorithm to use * @param pw The password to encrypt with * @param iteration Iteration count; default of 2000 if le 0 */ public byte[] getEncryptedPrivateKeyInfo(X509Certificate cert, PBEAlgorithm pbeAlg, Password pw, int iteration) throws CryptoManager.NotInitializedException, ObjectNotFoundException, TokenException; /** * Get an encrypted private key, with optional password * conversion. * * @param conv Password converter. If null, pw.getByteCopy() * will be used to get password bytes. * @param pw The password * @param alg The encryption algorithm * @param n Iteration count; default of 2000 if le 0 * @param k The private key */ public byte[] getEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, Algorithm alg, int n, PrivateKey k); /** * @param conv Password converter. If null, pw.getByteCopy() * will be used to get password bytes. * @param pw The password * @param nickname Nickname to use for private key * @param pubKey Public key corresponding to private key */ public void importEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, String nickname, PublicKey pubKey, byte[] epkiBytes); //////////////////////////////////////////////////////////// // Certs //////////////////////////////////////////////////////////// /** * Returns all user certificates stored on this token. A user certificate * is one that has a matching private key. * * @return An array of all user certificates present on this token. * @exception TokenException If an error occurs on the token while * gathering the certificates. */ public X509Certificate[] getCertificates() throws TokenException; /** * Deletes a certificate from a token. * * @param cert A certificate to be deleted from this token. The cert * must actually reside on this token. * @exception NoSuchItemOnTokenException If the given cert does not * reside on this token. * @exception TokenException If an error occurred on the token while * deleting the certificate. */ public void deleteCert(X509Certificate cert) throws NoSuchItemOnTokenException, TokenException; } jss-4.4.3/jss/org/mozilla/jss/crypto/CryptoToken.java000066400000000000000000000254511326145000000226170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.util.*; import java.security.*; /** * A CryptoToken performs cryptographic operations and stores * cryptographic items, such as keys and certs. It corresponds to a * Cryptographic Service Provider (CSP) in CDSA, and to a PKCS #11 token. *

Instances of CryptoToken are obtained from CryptoManager. * @see org.mozilla.jss.CryptoManager */ public interface CryptoToken { // // SERVICES // /** * Creates a Signature object, which can perform signing and signature * verification. Signing and verification cryptographic operations will * take place on this token. The signing key must be located on this * token. * * @param algorithm The algorithm used for the signing/verification. * @exception java.security.NoSuchAlgorithmException If the given * algorithm is not supported by this provider. */ public abstract org.mozilla.jss.crypto.Signature getSignatureContext(SignatureAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Creates a Digest object. Digesting cryptographic operations will * take place on this token. * * @param algorithm The algorithm used for digesting. * @exception java.security.NoSuchAlgorithmException If this provider * does not support the given algorithm. */ public abstract JSSMessageDigest getDigestContext(DigestAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, DigestException; // !!! MAC ??? /** * Creates a Cipher object, which can be used for encryption and * decryption. Cryptographic operations will take place on this token. * The keys used in the operations must be located on this token. * * @param algorithm The algorithm used for encryption/decryption. * @exception java.security.NoSuchAlgorithmException If this provider * does not support the given algorithm. */ public abstract Cipher getCipherContext(EncryptionAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; public abstract SymmetricKeyDeriver getSymmetricKeyDeriver() throws TokenException; public abstract KeyWrapper getKeyWrapper(KeyWrapAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Returns a Random Number Generator implemented on this token. * * @exception org.mozilla.jss.crypto.ServiceNotProvidedException If this token * does not perform random number generation */ /* public abstract SecureRandom getRandomGenerator() throws NotImplementedException, TokenException; */ // !!! Derive Keys ??? /** * Creates a KeyGenerator object, which can be used to generate * symmetric encryption keys. Any keys generated with this KeyGenerator * will be generated on this token. * * @param algorithm The algorithm that the keys will be used with. * @exception java.security.NoSuchAlgorithmException If this token does not * support the given algorithm. */ public abstract KeyGenerator getKeyGenerator(KeyGenAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Clones a SymmetricKey from a different token onto this token. * * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public SymmetricKey cloneKey(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException; /** * Creates a KeyPairGenerator object, which can be used to generate * key pairs. Any keypairs generated with this generator will be generated * on this token. * * @param algorithm The algorithm that the keys will be used with (RSA, * DSA, EC, etc.) * @exception java.security.NoSuchAlgorithmException If this token does * not support the given algorithm. */ public abstract KeyPairGenerator getKeyPairGenerator(KeyPairAlgorithm algorithm) throws java.security.NoSuchAlgorithmException, TokenException; /** * Generates a b64 encoded PKCS10 blob used for making cert * request. Begin/End brackets included. * @param subject subject dn of the certificate * @param keysize size of the key * @param keyType "rsa" or "dsa" * @param P The DSA prime parameter * @param Q The DSA sub-prime parameter * @param G The DSA base parameter * @return base64 encoded pkcs10 certificate request with * Begin/end brackets */ public abstract String generateCertRequest(String subject, int keysize, String keyType, byte[] P, byte[] Q, byte[] G) throws TokenException, InvalidParameterException, PQGParamGenException; /** * Determines whether this token supports the given algorithm. * * @param alg A JSS algorithm. Note that for Signature, a token may * fail to support a specific SignatureAlgorithm (such as * RSASignatureWithMD5Digest) even though it does support the * generic algorithm (RSASignature). In this case, the signature * operation will be performed on that token, but the digest * operation will be performed on the internal token. * @return true if the token supports the algorithm. */ public boolean doesAlgorithm(Algorithm alg); /** * Login to the token. If a token is logged in, it will not trigger * password callbacks. * * @param pwcb The password callback for this token. * @exception IncorrectPasswordException If the supplied password is * incorrect. * @see #setLoginMode * @see org.mozilla.jss.CryptoManager#setPasswordCallback */ public abstract void login(PasswordCallback pwcb) throws IncorrectPasswordException, TokenException; /** * Logout of the token. * */ public abstract void logout() throws TokenException; /** * Login once, never need to re-enter the password until you log out. */ public static final int ONE_TIME=0; /** * Need to re-login after a period of time. * @see org.mozilla.jss.crypto.CryptoToken#setLoginTimeoutMinutes */ public static final int TIMEOUT=1; /** * Need to provide a password before each crypto operation. */ public static final int EVERY_TIME=2; /** * Returns the login mode of this token: ONE_TIME, TIMEOUT, or * EVERY_TIME. The default is ONE_TIME. * @see #getLoginTimeoutMinutes * @exception TokenException If an error occurs on the token. */ public abstract int getLoginMode() throws TokenException; /** * Sets the login mode of this token. * * @param mode ONE_TIME, TIMEOUT, or EVERY_TIME * @exception TokenException If this mode is not supported by this token, * or an error occurs on the token. * @see #login * @see #setLoginTimeoutMinutes */ public abstract void setLoginMode(int mode) throws TokenException; /** * Returns the login timeout period. The timeout is only used if the * login mode is TIMEOUT. * * @see #getLoginMode * @exception TokenException If an error occurs on the token. */ public abstract int getLoginTimeoutMinutes() throws TokenException; /** * Sets the timeout period for logging in. This will only be used * if the login mode is TIMEOUT. * * @exception TokenException If timeouts are not supported by this * token, or an error occurs on the token. * @see #setLoginMode */ public abstract void setLoginTimeoutMinutes(int timeoutMinutes) throws TokenException; /** * Find out if the token is currently logged in. * * @see #login * @see #logout */ public boolean isLoggedIn() throws TokenException; /** * returns true if this token needs to be logged into before * it can be used. * * @see #login * @see #logout */ public boolean needsLogin() throws TokenException; /** * Initialize the password of this token. * * @param securityOfficerPW A callback to obtain the password of the * SecurityOfficer. Pass in a NullPasswordCallback if there is * no security officer password. Must not be null. * @param userPW A callback to obtain the new password for this token. * Must not be null. * @exception IncorrectPasswordException If the supplied security officer * password is incorrect. * @exception AlreadyInitializedException If the token only allows one * password initialization, and it has already occurred. * @exception TokenException If an error occurs on the token. */ public abstract void initPassword(PasswordCallback securityOfficerPW, PasswordCallback userPW) throws IncorrectPasswordException, AlreadyInitializedException, TokenException; /** * Determine whether the password has been initialized yet. Some tokens * (such as the Netscape Internal Key Token) don't allow initializing * the PIN more than once. * * @exception TokenException If an error occurs on the token. */ public abstract boolean passwordIsInitialized() throws TokenException; /** * Change the password of this token. * * @exception IncorrectPasswordException If the supplied old password is * incorrect. * @param oldpw A callback (which could be just a Password) to retrieve * the current password. * @param newpw A callback (which could be just a Password) to retrieve * the new password. */ public abstract void changePassword(PasswordCallback oldpw, PasswordCallback newpw) throws IncorrectPasswordException, TokenException; /** * Obtain the nickname, or label, of this token. * * @exception TokenException If an error occurs on the token. */ public abstract String getName() throws TokenException; /** * Get the CryptoStore interface to this token's objects. */ public abstract CryptoStore getCryptoStore(); /** * Deep comparison operation. Use this, rather than ==, to determine * whether two CryptoTokens are the same. */ public boolean equals(Object object); /** * Determines whether this token is currently present. * This could return false if the token is a smart card that was * removed from its slot. */ public boolean isPresent(); } jss-4.4.3/jss/org/mozilla/jss/crypto/DigestAlgorithm.java000066400000000000000000000055111326145000000234170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.util.Hashtable; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.asn1.*; public class DigestAlgorithm extends Algorithm { // The size in bytes of the output of this hash. private int outputSize; protected DigestAlgorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, int outputSize) { super(oidIndex, name, oid); this.outputSize = outputSize; // only store the first algorithm for a given oid. More than one // alg might share the same oid, such as from child classes. if( oid != null && oidMap.get(oid)==null ) { oidMap.put(oid, this); } } /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable(); public static DigestAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return (DigestAlgorithm) alg; } } /** * Returns the output size in bytes for this algorithm. */ public int getOutputSize() { return outputSize; } /** * The MD2 digest algorithm, from RSA. */ public static final DigestAlgorithm MD2 = new DigestAlgorithm (SEC_OID_MD2, "MD2", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(2), 16 ); /** * The MD5 digest algorithm, from RSA. */ public static final DigestAlgorithm MD5 = new DigestAlgorithm (SEC_OID_MD5, "MD5", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(5), 16 ); /** * The SHA-1 digest algorithm, from Uncle Sam. */ public static final DigestAlgorithm SHA1 = new DigestAlgorithm (SEC_OID_SHA1, "SHA-1", OBJECT_IDENTIFIER.ALGORITHM.subBranch(26), 20); /* * The SHA-256 digest Algorithm from FIPS 180-2 */ public static final DigestAlgorithm SHA256 = new DigestAlgorithm (SEC_OID_SHA256, "SHA-256", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(1), 32); /* * The SHA-384 digest Algorithm from FIPS 180-2 */ public static final DigestAlgorithm SHA384 = new DigestAlgorithm (SEC_OID_SHA384, "SHA-384", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(2), 48); /* * The SHA-512 digest Algorithm from FIPS 180-2 */ public static final DigestAlgorithm SHA512 = new DigestAlgorithm (SEC_OID_SHA512, "SHA-512", OBJECT_IDENTIFIER.HASH_ALGORITHM.subBranch(3), 64); } jss-4.4.3/jss/org/mozilla/jss/crypto/EncryptionAlgorithm.java000066400000000000000000000322751326145000000243410ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.asn1.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import java.util.*; /** * An algorithm for performing symmetric encryption. */ public class EncryptionAlgorithm extends Algorithm { public static class Mode { private String name; private static Hashtable nameHash = new Hashtable(); private Mode() { } private Mode(String name) { this.name = name; nameHash.put(name.toLowerCase(), this); } public static Mode fromString(String name) throws NoSuchAlgorithmException { Mode m = (Mode) nameHash.get(name.toLowerCase()); if( m == null ) { throw new NoSuchAlgorithmException( "Unrecognized mode \"" + name + "\""); } return m; } public String toString() { return name; } public static final Mode NONE = new Mode("NONE"); public static final Mode ECB = new Mode("ECB"); public static final Mode CBC = new Mode("CBC"); } public static class Alg { private String name; private static Hashtable nameHash = new Hashtable(); private Alg() { } private Alg(String name) { this.name = name; nameHash.put(name.toLowerCase(), this); } private static Alg fromString(String name) throws NoSuchAlgorithmException { Alg a = (Alg) nameHash.get(name.toLowerCase()); if( a == null ) { throw new NoSuchAlgorithmException("Unrecognized algorithm \"" + name + "\""); } return a; } public String toString() { return name; } public static final Alg RC4 = new Alg("RC4"); public static final Alg DES = new Alg("DES"); public static final Alg DESede = new Alg("DESede"); public static final Alg AES = new Alg("AES"); public static final Alg RC2 = new Alg("RC2"); } public static class Padding { private String name; private static Hashtable nameHash = new Hashtable(); private Padding() { } private Padding(String name) { this.name = name; nameHash.put(name.toLowerCase(), this); } public String toString() { return name; } public static Padding fromString(String name) throws NoSuchAlgorithmException { Padding p = (Padding) nameHash.get(name.toLowerCase()); if( p == null ) { throw new NoSuchAlgorithmException("Unrecognized Padding " + "type \"" + name + "\""); } return p; } public static final Padding NONE = new Padding("NoPadding"); public static final Padding PKCS5 = new Padding("PKCS5Padding"); } private static String makeName(Alg alg, Mode mode, Padding padding) { StringBuffer buf = new StringBuffer(); buf.append(alg.toString()); buf.append('/'); buf.append(mode.toString()); buf.append('/'); buf.append(padding.toString()); return buf.toString(); } protected EncryptionAlgorithm(int oidTag, Alg alg, Mode mode, Padding padding, Class paramClass, int blockSize, OBJECT_IDENTIFIER oid, int keyStrength) { super(oidTag, makeName(alg, mode, padding), oid, paramClass); this.alg = alg; this.mode = mode; this.padding = padding; this.blockSize = blockSize; if(oid!=null) { oidMap.put(oid, this); } if( name != null ) { nameMap.put(name.toLowerCase(), this); } this.keyStrength = keyStrength; algList.addElement(this); } protected EncryptionAlgorithm(int oidTag, Alg alg, Mode mode, Padding padding, Class []paramClasses, int blockSize, OBJECT_IDENTIFIER oid, int keyStrength) { super(oidTag, makeName(alg, mode, padding), oid, paramClasses); this.alg = alg; this.mode = mode; this.padding = padding; this.blockSize = blockSize; if(oid!=null) { oidMap.put(oid, this); } if( name != null ) { nameMap.put(name.toLowerCase(), this); } this.keyStrength = keyStrength; algList.addElement(this); } private int blockSize; private Alg alg; private Mode mode; private Padding padding; private int keyStrength; /** * Returns the base algorithm, without the parameters. For example, * the base algorithm of "AES/CBC/NoPadding" is "AES". */ public Alg getAlg() { return alg; } /** * Returns the mode of this algorithm. */ public Mode getMode() { return mode; } /** * Returns the padding type of this algorithm. */ public Padding getPadding() { return padding; } /** * Returns the key strength of this algorithm in bits. Algorithms that * use continuously variable key sizes (such as RC4) will return 0 to * indicate they can use any key size. */ public int getKeyStrength() { return keyStrength; } /////////////////////////////////////////////////////////////////////// // mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable(); private static Hashtable nameMap = new Hashtable(); private static Vector algList = new Vector(); public static EncryptionAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException("OID: " + oid.toString()); } else { return (EncryptionAlgorithm) alg; } } // Note: after we remove this deprecated method, we can remove // nameMap. /** * @deprecated This method is deprecated because algorithm strings * don't contain key length, which is necessary to distinguish between * AES algorithms. */ public static EncryptionAlgorithm fromString(String name) throws NoSuchAlgorithmException { Object alg = nameMap.get(name.toLowerCase()); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return (EncryptionAlgorithm) alg; } } public static EncryptionAlgorithm lookup(String algName, String modeName, String paddingName, int keyStrength) throws NoSuchAlgorithmException { int len = algList.size(); Alg alg = Alg.fromString(algName); Mode mode = Mode.fromString(modeName); Padding padding = Padding.fromString(paddingName); int i; for(i = 0; i < len; ++i ) { EncryptionAlgorithm cur = (EncryptionAlgorithm) algList.elementAt(i); if( cur.alg == alg && cur.mode == mode && cur.padding == padding ) { if( cur.keyStrength == 0 || cur.keyStrength == keyStrength ) { break; } } } if( i == len ) { throw new NoSuchAlgorithmException(algName + "/" + modeName + "/" + paddingName + " with key strength " + keyStrength + " not found"); } return (EncryptionAlgorithm) algList.elementAt(i); } /** * The blocksize of the algorithm in bytes. Stream algorithms (such as * RC4) have a blocksize of 1. */ public int getBlockSize() { return blockSize; } /** * Returns true if this algorithm performs padding. * @deprecated Call getPaddingType() instead. */ public boolean isPadded() { return ! Padding.NONE.equals(padding); } /** * Returns the type of padding for this algorithm. */ public Padding getPaddingType() { return padding; } private static Class[] IVParameterSpecClasses = null; static { IVParameterSpecClasses = new Class[2]; IVParameterSpecClasses[0] = IVParameterSpec.class; IVParameterSpecClasses[1] = IvParameterSpec.class; } /** * Returns the number of bytes that this algorithm expects in * its initialization vector. * * @return The size in bytes of the IV for this algorithm. A size of * 0 means this algorithm does not take an IV. */ public native int getIVLength(); public static final EncryptionAlgorithm RC4 = new EncryptionAlgorithm(SEC_OID_RC4, Alg.RC4, Mode.NONE, Padding.NONE, (Class)null, 1, OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(4), 0); public static final EncryptionAlgorithm DES_ECB = new EncryptionAlgorithm(SEC_OID_DES_ECB, Alg.DES, Mode.ECB, Padding.NONE, (Class)null, 8, OBJECT_IDENTIFIER.ALGORITHM.subBranch(6), 56); public static final EncryptionAlgorithm DES_CBC = new EncryptionAlgorithm(SEC_OID_DES_CBC, Alg.DES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 8, OBJECT_IDENTIFIER.ALGORITHM.subBranch(7), 56); public static final EncryptionAlgorithm DES_CBC_PAD = new EncryptionAlgorithm(CKM_DES_CBC_PAD, Alg.DES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 8, null, 56); // no oid public static final EncryptionAlgorithm DES3_ECB = new EncryptionAlgorithm(CKM_DES3_ECB, Alg.DESede, Mode.ECB, Padding.NONE, (Class)null, 8, null, 168); // no oid public static final EncryptionAlgorithm DES3_CBC = new EncryptionAlgorithm(SEC_OID_DES_EDE3_CBC, Alg.DESede, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 8, OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(7), 168); public static final EncryptionAlgorithm DES3_CBC_PAD = new EncryptionAlgorithm(CKM_DES3_CBC_PAD, Alg.DESede, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 8, null, 168); //no oid public static final EncryptionAlgorithm RC2_CBC = new EncryptionAlgorithm(SEC_OID_RC2_CBC, Alg.RC2, Mode.CBC, Padding.NONE, RC2ParameterSpec.class, 8, null, 0); // no oid, see comment below // Which algorithm should be associated with this OID, RC2_CBC or // RC2_CBC_PAD? NSS says RC2_CBC, but PKCS #5 v2.0 says RC2_CBC_PAD. // See NSS bug 202925. public static final EncryptionAlgorithm RC2_CBC_PAD = new EncryptionAlgorithm(CKM_RC2_CBC_PAD, Alg.RC2, Mode.CBC, Padding.PKCS5, RC2ParameterSpec.class, 8, OBJECT_IDENTIFIER.RSA_CIPHER.subBranch(2), 0); public static final OBJECT_IDENTIFIER AES_ROOT_OID = new OBJECT_IDENTIFIER( new long[] { 2, 16, 840, 1, 101, 3, 4, 1 } ); public static final EncryptionAlgorithm AES_128_ECB = new EncryptionAlgorithm(SEC_OID_AES_128_ECB, Alg.AES, Mode.ECB, Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(1), 128); public static final EncryptionAlgorithm AES_128_CBC = new EncryptionAlgorithm(SEC_OID_AES_128_CBC, Alg.AES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(2), 128); public static final EncryptionAlgorithm AES_128_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_128_CBC, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(2), 128); public static final EncryptionAlgorithm AES_192_ECB = new EncryptionAlgorithm(SEC_OID_AES_192_ECB, Alg.AES, Mode.ECB, Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(21), 192); public static final EncryptionAlgorithm AES_192_CBC = new EncryptionAlgorithm(SEC_OID_AES_192_CBC, Alg.AES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(22), 192); public static final EncryptionAlgorithm AES_192_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_192_CBC, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(22), 192); public static final EncryptionAlgorithm AES_256_ECB = new EncryptionAlgorithm(SEC_OID_AES_256_ECB, Alg.AES, Mode.ECB, Padding.NONE, (Class)null, 16, AES_ROOT_OID.subBranch(41), 256); public static final EncryptionAlgorithm AES_256_CBC = new EncryptionAlgorithm(SEC_OID_AES_256_CBC, Alg.AES, Mode.CBC, Padding.NONE, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(42), 256); public static final EncryptionAlgorithm AES_CBC_PAD = new EncryptionAlgorithm(CKM_AES_CBC_PAD, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, null, 256); // no oid public static final EncryptionAlgorithm AES_256_CBC_PAD = new EncryptionAlgorithm(SEC_OID_AES_256_CBC, Alg.AES, Mode.CBC, Padding.PKCS5, IVParameterSpecClasses, 16, AES_ROOT_OID.subBranch(42), 256); } jss-4.4.3/jss/org/mozilla/jss/crypto/HMACAlgorithm.java000066400000000000000000000044231326145000000227110ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.util.Hashtable; import org.mozilla.jss.asn1.*; import java.security.NoSuchAlgorithmException; /** * Algorithms for performing HMACs. These can be used to create * MessageDigests. */ public class HMACAlgorithm extends DigestAlgorithm { protected HMACAlgorithm(int oidIndex, String name, OBJECT_IDENTIFIER oid, int outputSize) { super(oidIndex, name, oid, outputSize); if( oid!=null && oidMap.get(oid)==null) { oidMap.put(oid, this); } } /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable(); /** * Looks up the HMAC algorithm with the given OID. * * @exception NoSuchAlgorithmException If no registered HMAC algorithm * has the given OID. */ public static HMACAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return (HMACAlgorithm) alg; } } /** * SHA-X HMAC. This is a Message Authentication Code that uses a * symmetric key together with SHA-X digesting to create a form of * signature. */ public static final HMACAlgorithm SHA1 = new HMACAlgorithm (CKM_SHA_1_HMAC, "SHA-1-HMAC", OBJECT_IDENTIFIER.ALGORITHM.subBranch(26), 20); public static final HMACAlgorithm SHA256 = new HMACAlgorithm (SEC_OID_HMAC_SHA256, "SHA-256-HMAC", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(9), 32); public static final HMACAlgorithm SHA384 = new HMACAlgorithm (SEC_OID_HMAC_SHA384, "SHA-384-HMAC", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(10), 48); public static final HMACAlgorithm SHA512 = new HMACAlgorithm (SEC_OID_HMAC_SHA512, "SHA-512-HMAC", OBJECT_IDENTIFIER.RSA_DIGEST.subBranch(11), 64); } jss-4.4.3/jss/org/mozilla/jss/crypto/IVParameterSpec.java000066400000000000000000000013121326145000000233160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.spec.AlgorithmParameterSpec; /** * An algorithm parameter that consists of an initialization vector (IV). */ public class IVParameterSpec implements AlgorithmParameterSpec { private byte[] iv; private IVParameterSpec() { } public IVParameterSpec(byte[] iv) { this.iv = iv; } /** * Returns a reference to an internal copy of the initialization vector. */ public byte[] getIV() { return iv; } } jss-4.4.3/jss/org/mozilla/jss/crypto/IllegalBlockSizeException.java000066400000000000000000000004531326145000000253670ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; public class IllegalBlockSizeException extends Exception { } jss-4.4.3/jss/org/mozilla/jss/crypto/InternalCertificate.java000066400000000000000000000047241326145000000242550ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * Certificates residing in the internal database. Their trust flags * can be viewed and modified. Other types of certificates do not * have trust flags. */ public interface InternalCertificate extends X509Certificate { //////////////////////////////////////////////////// // Trust manipulation //////////////////////////////////////////////////// public static final int VALID_PEER = (1<<0); public static final int TRUSTED_PEER = (1<<1); // CERTDB_TRUSTED public static final int VALID_CA = (1<<3); public static final int TRUSTED_CA = (1<<4); public static final int USER = (1<<6); public static final int TRUSTED_CLIENT_CA = (1<<7); /** * Set the SSL trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract void setSSLTrust(int trust); /** * Set the email (S/MIME) trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract void setEmailTrust(int trust); /** * Set the object signing trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract void setObjectSigningTrust(int trust); /** * Get the SSL trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract int getSSLTrust(); /** * Get the email (S/MIME) trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract int getEmailTrust(); /** * Get the object signing trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public abstract int getObjectSigningTrust(); } jss-4.4.3/jss/org/mozilla/jss/crypto/InvalidDERException.java000066400000000000000000000007311326145000000241300ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This exception is thrown when we encounter a bogus DER blob. */ public class InvalidDERException extends Exception { public InvalidDERException() { super(); } public InvalidDERException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/InvalidKeyFormatException.java000066400000000000000000000011031326145000000254110ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * An exception of this type is thrown if an encoded private key * cannot be decoded. */ public class InvalidKeyFormatException extends java.security.spec.InvalidKeySpecException { public InvalidKeyFormatException() { super(); } public InvalidKeyFormatException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/JSSMessageDigest.java000066400000000000000000000072361326145000000234430ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.DigestException; import java.security.InvalidKeyException; /** * A class for performing message digesting (hashing) and MAC operations. */ public abstract class JSSMessageDigest { /** * Initializes an HMAC digest with the given symmetric key. This also * has the effect of resetting the digest. * * @exception DigestException If this algorithm is not an HMAC algorithm. * @exception InvalidKeyException If the given key is not valid. */ public abstract void initHMAC(SymmetricKey key) throws DigestException, InvalidKeyException; /** * Updates the digest with a single byte of input. */ public void update(byte input) throws DigestException { byte[] in = { input }; update(in, 0, 1); } /** * Updates the digest with a portion of an array. * * @param input An array from which to update the digest. * @param offset The index in the array at which to start digesting. * @param len The number of bytes to digest. * @exception DigestException If an error occurs while digesting. */ public abstract void update(byte[] input, int offset, int len) throws DigestException; /** * Updates the digest with an array. * * @param input An array to feed to the digest. * @exception DigestException If an error occurs while digesting. */ public void update(byte[] input) throws DigestException { update(input, 0, input.length); } /** * Completes digestion. * * @return The, ahem, output of the digest operation. * @exception DigestException If an error occurs while digesting. */ public byte[] digest() throws DigestException { byte[] output = new byte[getOutputSize()]; digest(output, 0, output.length); return output; } /** * Completes digesting, storing the result into the provided array. * * @param buf The buffer in which to place the digest output. * @param offset The offset in the buffer at which to store the output. * @param len The amount of space available in the buffer for the * digest output. * @return The number of bytes actually stored into buf. * @exception DigestException If the provided space is too small for * the digest, or an error occurs with the digest. */ public abstract int digest(byte[] buf, int offset, int len) throws DigestException; /** * Provides final data to the digest, then completes it and returns the * output. * * @param input The digest's last meal. * @return The completed digest. * @exception DigestException If an error occurs while digesting. */ public byte[] digest(byte[] input) throws DigestException { update(input); return digest(); } /** * Resets this digest for further use. This clears all input and * output streams. If this is an HMAC digest, the HMAC key is not * cleared. */ public abstract void reset() throws DigestException; /** * Returns the algorithm that this digest uses. */ public abstract DigestAlgorithm getAlgorithm(); /** * Returns the length of the digest created by this digest's * digest algorithm. * * @return The size in bytes of the output of this digest. */ public int getOutputSize() { return getAlgorithm().getOutputSize(); } } jss-4.4.3/jss/org/mozilla/jss/crypto/JSSSecureRandom.java000066400000000000000000000012471326145000000233020ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * An interface for secure random numbers. */ public interface JSSSecureRandom { /** * Seed the RNG with the given seed bytes. */ public void setSeed(byte[] seed); /** * Seed the RNG with the eight bytes contained in seed. */ public void setSeed(long seed); /** * Retrieves random bytes and stores them in the given array. */ public void nextBytes(byte bytes[]); } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyAlreadyImportedException.java000066400000000000000000000010461326145000000257450ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This exception is thrown if the user tries to import a * key which is already in the specified token */ public class KeyAlreadyImportedException extends java.lang.Exception { public KeyAlreadyImportedException() {} public KeyAlreadyImportedException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyGenAlgorithm.java000066400000000000000000000110051326145000000233550ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import java.util.Hashtable; import java.security.NoSuchAlgorithmException; /** * Algorithms that can be used for generating symmetric keys. */ public class KeyGenAlgorithm extends Algorithm { protected static interface KeyStrengthValidator { public boolean isValidKeyStrength(int strength); } protected static class FixedKeyStrengthValidator implements KeyStrengthValidator { private int strength; public FixedKeyStrengthValidator(int strength) { this.strength = strength; } public boolean isValidKeyStrength(int strength) { return this.strength == strength; } } protected KeyGenAlgorithm(int oidTag, String name, KeyStrengthValidator keyStrengthValidator, OBJECT_IDENTIFIER oid, Class paramClass) { super(oidTag, name, oid, paramClass); this.keyStrengthValidator = keyStrengthValidator; if(oid!=null) { oidMap.put(oid, this); } } /////////////////////////////////////////////////////////////////////// // OIDs /////////////////////////////////////////////////////////////////////// private static final OBJECT_IDENTIFIER PKCS5 = OBJECT_IDENTIFIER.PKCS5; private static final OBJECT_IDENTIFIER PKCS12_PBE = OBJECT_IDENTIFIER.PKCS12.subBranch(1); /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// private static Hashtable oidMap = new Hashtable(); public static KeyGenAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(oid.toString()); } else { return (KeyGenAlgorithm) alg; } } private KeyStrengthValidator keyStrengthValidator; /** * Returns true if the given strength is valid for this * key generation algorithm. Note that PBE algorithms require * PBEParameterSpecs rather than strengths. It is the responsibility * of the caller to verify this. */ public boolean isValidStrength(int strength) { return keyStrengthValidator.isValidKeyStrength(strength); } ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm DES = new KeyGenAlgorithm(CKM_DES_KEY_GEN, "DES", new FixedKeyStrengthValidator(56), null, null); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm DES3 = new KeyGenAlgorithm(CKM_DES3_KEY_GEN, "DESede", new FixedKeyStrengthValidator(168), null, null); public static final KeyGenAlgorithm DESede = DES3; ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm RC4 = new KeyGenAlgorithm(CKM_RC4_KEY_GEN, "RC4", new KeyStrengthValidator() { public boolean isValidKeyStrength(int strength) { return true; } }, null, null); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm PBA_SHA1_HMAC = new KeyGenAlgorithm( CKM_PBA_SHA1_WITH_SHA1_HMAC, "PBA/SHA1/HMAC", new FixedKeyStrengthValidator(160), null, PBEKeyGenParams.class ); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm AES = new KeyGenAlgorithm(CKM_AES_KEY_GEN, "AES", new KeyStrengthValidator() { public boolean isValidKeyStrength(int strength) { return strength==128 || strength==192 || strength==256; } }, null, null); ////////////////////////////////////////////////////////////// public static final KeyGenAlgorithm RC2 = new KeyGenAlgorithm(CKM_RC2_KEY_GEN, "RC2", new KeyStrengthValidator() { public boolean isValidKeyStrength(int strength) { // 1 byte - 128 bytes return strength>=8 && strength <= (128*8); } }, null, null); } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyGenerator.java000066400000000000000000000103631326145000000227310ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.io.CharConversionException; /** * Generates symmetric keys for encryption and decryption. */ public interface KeyGenerator { /** * @param strength Key size in bits. Must be evenly divisible by 8. */ public void initialize(int strength) throws InvalidAlgorithmParameterException; public void initialize(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException; /** * @param usages The operations the key will be used for after it is * generated. You have to specify these so that the key can be properly * marked with the operations it supports. Some PKCS #11 tokens require * that a key be marked for an operation before it can perform that * operation. The default is SymmetricKey.Usage.SIGN and * SymmetricKey.Usage.ENCRYPT. */ public void setKeyUsages(SymmetricKey.Usage[] usages); /** * Tells the generator to generate temporary or permanent keys. * Temporary keys are not written permanently to the token. They * are destroyed by the garbage collector. If this method is not * called, the default is temporary keys. */ public void temporaryKeys(boolean temp); /** * Tells the generator to generate sensitive or insensitive keys. * Certain attributes of a sensitive key cannot be revealed in * plaintext outside the token. If this method is not called, the * default is token dependent. */ public void sensitiveKeys(boolean sensitive); /** * Generates a symmetric key. */ public SymmetricKey generate() throws IllegalStateException, TokenException, CharConversionException; /** * Generates an Initialization Vector using a PBE algorithm. * In order to call this method, the algorithm must be a PBE algorithm, * and the KeyGenerator must have been initialized with an instance * of PBEKeyGenParams. * * @return The initialization vector derived from the password and salt * using the PBE algorithm. * @exception IllegalStateException If the algorithm is not a PBE * algorithm, or the KeyGenerator has not been initialized with * an instance of PBEKeyGenParams. * @exception TokenException If an error occurs on the CryptoToken while * generating the IV. */ public byte[] generatePBE_IV() throws IllegalStateException, TokenException, CharConversionException; /** * Allows a SymmetricKey to be cloned on a different token. * * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public SymmetricKey clone(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException; /** * An interface for converting a password of Java characters into an array * of bytes. This conversion must be performed to provide a byte array * to the low-level crypto engine. The default conversion is UTF8. * Null-termination is not necessary, and indeed is usually incorrect, * since the password is passed to the crypto engine as a byte array, not * a C string. */ public static interface CharToByteConverter { /** * Converts a password of Java characters into a password of * bytes, using some encoding scheme. The input char array must * not be modified. */ public byte[] convert(char[] chars) throws CharConversionException; } /** * Sets the character to byte converter for passwords. The default * conversion is UTF8 with no null termination. */ public void setCharToByteConverter(CharToByteConverter charToByte); } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyPairAlgorithm.java000066400000000000000000000054601326145000000235470ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.NoSuchAlgorithmException; import java.util.Hashtable; /** * Algorithms that can be used for keypair generation. */ public class KeyPairAlgorithm extends Algorithm { protected KeyPairAlgorithm(int oidIndex, String name, Algorithm algFamily) { super(oidIndex, name); this.algFamily = algFamily; nameMap.put(name, this); } /** * Returns the algorithm family for a given key pair generation algorithm. * If a token supports a family and is writable, we can do keypair gen * on the token even if it doesn't support the keypair gen algorithm. * We do this by doing the keypair gen on the internal module and then * moving the key out to the other token. */ public Algorithm getAlgFamily() { return algFamily; } private static Hashtable nameMap = new Hashtable(); /** * Looks up a key pair generation algorithm from its name. The names * are those specified in the JCA spec. For example, "RSA" and "DSA". * * @throws NoSuchAlgorithmException If the name of the algorithm is not * recognized as a supported algorithm. */ public static KeyPairAlgorithm fromString(String algName) throws NoSuchAlgorithmException { KeyPairAlgorithm alg = (KeyPairAlgorithm)nameMap.get(algName); if( alg == null ) { throw new NoSuchAlgorithmException(); } return alg; } protected Algorithm algFamily; //////////////////////////////////////////////////////////////// // Key-Pair Generation Algorithms //////////////////////////////////////////////////////////////// public static final Algorithm RSAFamily = new Algorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA"); public static final Algorithm DSAFamily = new Algorithm(SEC_OID_ANSIX9_DSA_SIGNATURE, "DSA"); public static final Algorithm // To support both ECDSA and ECDH, it is best to provide two EC Families; // However, since there is no token that does only CKM_DERIVE to // date, we will just do ECDSA for now as it is sufficient enough today. // This fix will support tokens that do not do ECDH ECFamily = new Algorithm(SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, "EC"); public static final KeyPairAlgorithm RSA = new KeyPairAlgorithm(CKM_RSA_PKCS_KEY_PAIR_GEN, "RSA", RSAFamily); public static final KeyPairAlgorithm DSA = new KeyPairAlgorithm(CKM_DSA_KEY_PAIR_GEN, "DSA", DSAFamily); public static final KeyPairAlgorithm EC = new KeyPairAlgorithm(CKM_EC_KEY_PAIR_GEN, "EC", ECFamily); } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyPairGenerator.java000066400000000000000000000146471326145000000235560ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.*; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; /** * Generates RSA and DSA key pairs. Each CryptoToken provides a * KeyPairGenerator, which can be used to generate key pairs on that token. * A given token may not support all algorithms, and some tokens may not * support any key pair generation. If a token does not support key pair * generation, the Netscape internal token may do it instead. Call * keygenOnInternalToken to find out if this is happening. * * @see org.mozilla.jss.crypto.CryptoToken#getKeyPairGenerator */ public class KeyPairGenerator { /** * Creates a new key pair generator. KeyPairGenerators should * be obtained by calling CryptoToken.getKeyPairGenerator * instead of calling this constructor. * * @param algorithm The type of keys that the generator will be * used to generate. * @param engine The engine object that provides the implementation for * the class. */ public KeyPairGenerator(KeyPairAlgorithm algorithm, KeyPairGeneratorSpi engine) { this.algorithm = algorithm; this.engine = engine; } /** * Generates a new key pair. * * @return A new key pair. The keys reside on the CryptoToken that * provided this KeyPairGenerator. * @exception TokenException If an error occurs on the CryptoToken * in the process of generating the key pair. */ public java.security.KeyPair genKeyPair() throws TokenException { return engine.generateKeyPair(); } /** * @return The type of key that this generator generates. */ public KeyPairAlgorithm getAlgorithm() { return algorithm; } /** * Initializes the generator with algorithm-specific parameters. * The SecureRandom parameters is ignored. * * @param params Algorithm-specific parameters for the key pair generation. * @param random This parameter is ignored. NSS does not accept * an external source of random numbers. * @exception InvalidAlgorithmParameterException If the parameters are * inappropriate for the type of key pair that is being generated, * or they are not supported by this generator. * @see org.mozilla.jss.crypto.RSAParameterSpec * @see java.security.spec.DSAParameterSpec */ public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { engine.initialize(params, random); } /** * Initializes the generator with algorithm-specific parameters. * * @param params Algorithm-specific parameters for the key pair generation. * @exception InvalidAlgorithmParameterException If the parameters are * inappropriate for the type of key pair that is being generated, * or they are not supported by this generator. * @see org.mozilla.jss.crypto.RSAParameterSpec * @see java.security.spec.DSAParameterSpec */ public void initialize(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { engine.initialize(params, null); } /** * Initializes the generator with the strength of the keys. * The SecureRandom parameter is ignored. * * @param strength The strength of the keys that will be generated. * Usually this is the length of the key in bits. * @param random This parameter is ignored. NSS does not accept * an external source of random numbers. */ public void initialize(int strength, SecureRandom random) { engine.initialize(strength, random); } /** * Initializes the generator with the strength of the keys. * * @param strength The strength of the keys that will be generated. * Usually this is the length of the key in bits. */ public void initialize(int strength) { engine.initialize(strength, null); } /** * @return true if the keypair generation will take place on the * internal token rather than the current token. This will * happen if the token does not support keypair generation * but does support this algorithm and is writable. In this * case the keypair will be generated on the Netscape internal * token and then moved to this token. */ public boolean keygenOnInternalToken() { return engine.keygenOnInternalToken(); } /** * Tells the generator to generate temporary or permanent keypairs. * Temporary keys are not written permanently to the token. They * are destroyed by the garbage collector. If this method is not * called, the default is permanent keypairs. * @param temp */ public void temporaryPairs(boolean temp) { engine.temporaryPairs(temp); } /** * Tells the generator to generate sensitive or insensitive keypairs. * Certain attributes of a sensitive key cannot be revealed in * plaintext outside the token. If this method is not called, the * default depends on the temporaryPairs mode for backward * compatibility. The default is sensitive keypairs if the * temporaryPairs mode is false, or insensitive keypairs if the * temporaryPairs mode is true. * @param sensitive */ public void sensitivePairs(boolean sensitive) { engine.sensitivePairs(sensitive); } /** * Tells the generator to generate extractable or unextractable * keypairs. Extractable keys can be extracted from the token after * wrapping. If this method is not called, the default is token * dependent. * @param extractable */ public void extractablePairs(boolean extractable) { engine.extractablePairs(extractable); } public void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages, KeyPairGeneratorSpi.Usage[] usages_mask) { engine.setKeyPairUsages(usages,usages_mask); } public int getCurveCodeByName(String curveName) throws InvalidParameterException { return engine.getCurveCodeByName(curveName); } protected KeyPairAlgorithm algorithm; protected KeyPairGeneratorSpi engine; } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyPairGeneratorSpi.java000066400000000000000000000053021326145000000242160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.*; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; public abstract class KeyPairGeneratorSpi { public KeyPairGeneratorSpi() { } public abstract void initialize(int strength, SecureRandom random); public abstract void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException; public abstract KeyPair generateKeyPair() throws TokenException; public abstract int getCurveCodeByName(String curveName) throws InvalidParameterException; public abstract void temporaryPairs(boolean temp); public abstract void sensitivePairs(boolean sensitive); public abstract void extractablePairs(boolean extractable); public abstract boolean keygenOnInternalToken(); /** * In PKCS #11, each keypair can be marked with the operations it will * be used to perform. Some tokens require that a key be marked for * an operation before the key can be used to perform that operation; * other tokens don't care. NSS provides a way to specify a set of * flags and a corresponding mask for these flags. If a specific usage * is desired set the value for that usage. If it is not set, let NSS * behave in it's default fashion. If a behavior is desired, also set * that behavior in the mask as well as the flags. * */ public final static class Usage { private Usage() { } private Usage(int val) { this.val = val;} private int val; public int getVal() { return val; } // these enums must match the // opFlagForUsage listed in PK11KeyPairGenerator.java public static final Usage ENCRYPT = new Usage(0); public static final Usage DECRYPT = new Usage(1); public static final Usage SIGN = new Usage(2); public static final Usage SIGN_RECOVER = new Usage(3); public static final Usage VERIFY = new Usage(4); public static final Usage VERIFY_RECOVER = new Usage(5); public static final Usage WRAP = new Usage(6); public static final Usage UNWRAP = new Usage(7); public static final Usage DERIVE = new Usage(8); } /** * setKeyPairUsages * @param usages * @param usages_mask */ public abstract void setKeyPairUsages(KeyPairGeneratorSpi.Usage[] usages, KeyPairGeneratorSpi.Usage[] usages_mask); } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyWrapAlgorithm.java000066400000000000000000000100711326145000000235570ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.util.Hashtable; import java.security.NoSuchAlgorithmException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; /** * */ public class KeyWrapAlgorithm extends Algorithm { protected KeyWrapAlgorithm(int oidTag, String name, Class paramClass, boolean padded, int blockSize) { super(oidTag, name, null, paramClass); this.padded = padded; this.blockSize = blockSize; if( name != null ) { nameMap.put(name.toLowerCase(), this); } } protected KeyWrapAlgorithm(int oidTag, String name, Class []paramClasses, boolean padded, int blockSize) { super(oidTag, name, null, paramClasses); this.padded = padded; this.blockSize = blockSize; if( name != null ) { nameMap.put(name.toLowerCase(), this); } } private boolean padded; private int blockSize; private static Hashtable nameMap = new Hashtable(); public static KeyWrapAlgorithm fromString(String name) throws NoSuchAlgorithmException { Object alg = nameMap.get( name.toLowerCase() ); if( alg == null ) { throw new NoSuchAlgorithmException(); } else { return (KeyWrapAlgorithm) alg; } } public boolean isPadded() { return padded; } public int getBlockSize() { return blockSize; } private static Class[] IVParameterSpecClasses = null; static { IVParameterSpecClasses = new Class[2]; IVParameterSpecClasses[0] = IVParameterSpec.class; IVParameterSpecClasses[1] = IvParameterSpec.class; } public static final KeyWrapAlgorithm DES_ECB = new KeyWrapAlgorithm(SEC_OID_DES_ECB, "DES/ECB", (Class) null, false, 8); public static final KeyWrapAlgorithm DES_CBC = new KeyWrapAlgorithm(SEC_OID_DES_CBC, "DES/CBC", IVParameterSpecClasses, false, 8); public static final KeyWrapAlgorithm DES_CBC_PAD = new KeyWrapAlgorithm(CKM_DES_CBC_PAD, "DES/CBC/Pad", IVParameterSpecClasses, true, 8); public static final KeyWrapAlgorithm DES3_ECB = new KeyWrapAlgorithm(CKM_DES3_ECB, "DES3/ECB", (Class)null, false, 8); public static final KeyWrapAlgorithm DES3_CBC = new KeyWrapAlgorithm(SEC_OID_DES_EDE3_CBC, "DES3/CBC", IVParameterSpecClasses, false, 8); public static final KeyWrapAlgorithm DES3_CBC_PAD = new KeyWrapAlgorithm(CKM_DES3_CBC_PAD, "DES3/CBC/Pad", IVParameterSpecClasses, true, 8); public static final KeyWrapAlgorithm RSA = new KeyWrapAlgorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA", (Class) null, false, 0); public static final KeyWrapAlgorithm PLAINTEXT = new KeyWrapAlgorithm(0, "Plaintext", (Class) null, false, 0); public static final KeyWrapAlgorithm AES_ECB = new KeyWrapAlgorithm(CKM_AES_ECB, "AES/ECB/NoPadding", (Class) null, false, 16); public static final KeyWrapAlgorithm AES_CBC = new KeyWrapAlgorithm(CKM_AES_CBC, "AES/CBC/NoPadding", IVParameterSpecClasses, false, 16); public static final KeyWrapAlgorithm AES_CBC_PAD = new KeyWrapAlgorithm(CKM_AES_CBC_PAD, "AES/CBC/PKCS5Padding", IVParameterSpecClasses, true, 16); public static final KeyWrapAlgorithm RC2_CBC_PAD = new KeyWrapAlgorithm(CKM_RC2_CBC_PAD, "RC2/CBC/PKCS5Padding", RC2ParameterSpec.class, true, 8); public static final KeyWrapAlgorithm AES_KEY_WRAP = new KeyWrapAlgorithm(CKM_NSS_AES_KEY_WRAP, "AES KeyWrap", (Class) null, true, 8); public static final KeyWrapAlgorithm AES_KEY_WRAP_PAD = new KeyWrapAlgorithm(CKM_NSS_AES_KEY_WRAP_PAD, "AES KeyWrap/Padding", (Class) null, true, 8); } jss-4.4.3/jss/org/mozilla/jss/crypto/KeyWrapper.java000066400000000000000000000121571326145000000224260ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import java.security.InvalidKeyException; public interface KeyWrapper { public void initWrap(SymmetricKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; public void initWrap(PublicKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * For wrapping keys in plaintext. */ public void initWrap() throws InvalidKeyException, InvalidAlgorithmParameterException; public void initUnwrap(SymmetricKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; public void initUnwrap(PrivateKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException; /** * For plaintext-wrapped keys. */ public void initUnwrap() throws InvalidKeyException, InvalidAlgorithmParameterException; public byte[] wrap(PrivateKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException; public byte[] wrap(SymmetricKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException; /** * Unwraps a private key, creating a permanent private key object. * A permanent private key object resides on a token until it is * explicitly deleted from the token. * * @param publicKey Used to calculate the key identifier that must be stored * with the private key. Must be a RSAPublicKey or a * DSAPublicKey. * @exception InvalidKeyException If the type of the public key does not * match the type of the private key to be unwrapped. */ public PrivateKey unwrapPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException; /** * Unwraps a private key, creating a temporary private key object. * A temporary * private key is one that does not permanently reside on a token. * As soon as it is garbage-collected, it is gone forever. * * @param publicKey Used to calculate the key identifier that must be stored * with the private key. Must be a RSAPublicKey or a * DSAPublicKey. * @exception InvalidKeyException If the type of the public key does not * match the type of the private key to be unwrapped. */ public PrivateKey unwrapTemporaryPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException; /** * @param keyLength The expected length of the key in bytes. This is * only used for variable-length keys (RC4) and non-padding * algorithms. Otherwise, it can be set to anything(like 0). * @param usage The operation the key will be used for after it is * unwrapped. You have to specify this so that the key can be properly * marked with the operation it supports. Some PKCS #11 tokens require * that a key be marked for an operation before it can perform that * operation. */ public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; /** * Unwraps a key and allows it to be used for all operations. * @param keyLength The expected length of the key in bytes. This is * only used for variable-length keys (RC4) and non-padding * algorithms. Otherwise, it can be set to anything(like 0). */ public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; /** * Unwraps a key and allows it to be used for all operations. * @param keyLength The expected length of the key in bytes. This is * only used for variable-length keys (RC4) and non-padding * algorithms. Otherwise, it can be set to anything(like 0). */ public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, int keyLength) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException; } jss-4.4.3/jss/org/mozilla/jss/crypto/Makefile000066400000000000000000000035451326145000000211330ustar00rootroot00000000000000#! gmake # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/crypto/NoSuchItemOnTokenException.java000066400000000000000000000010411326145000000255160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * Thrown if a cryptographic item does not exist on the token it is * trying to be used on. */ public class NoSuchItemOnTokenException extends Exception { public NoSuchItemOnTokenException() {} public NoSuchItemOnTokenException( String message ) { super( message ); } } jss-4.4.3/jss/org/mozilla/jss/crypto/NoSuchPaddingException.java000066400000000000000000000006151326145000000246760ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This class is a stub for javax.crypto.NoSuchPaddingException until we * move to JDK 1.2. */ public class NoSuchPaddingException extends Exception { } jss-4.4.3/jss/org/mozilla/jss/crypto/ObjectNotFoundException.java000066400000000000000000000007471326145000000251010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This exception is thrown whenever something isn't implemented. */ public class ObjectNotFoundException extends Exception { public ObjectNotFoundException() { super(); } public ObjectNotFoundException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/PBEAlgorithm.java000066400000000000000000000126211326145000000226060ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import java.util.Hashtable; import java.security.NoSuchAlgorithmException; /** * Algorithms that can be used for generating symmetric keys from passwords. */ public class PBEAlgorithm extends KeyGenAlgorithm { private EncryptionAlgorithm encAlg; private int saltLength; protected PBEAlgorithm(int oidTag, String name, int validStrength, OBJECT_IDENTIFIER oid, EncryptionAlgorithm encAlg, int saltLength) { super(oidTag, name, new FixedKeyStrengthValidator(validStrength), oid, PBEKeyGenParams.class); this.encAlg = encAlg; this.saltLength = saltLength; } /** * Returns the EncryptionAlgorithm that should be used with keys * generated with this PBEAlgorithm. For example, * PBE_MD2_DES_CBC.getEncryptionAlg() returns * EncryptionAlgorithm.DES_CBC. */ public EncryptionAlgorithm getEncryptionAlg() { return encAlg; } /** * Returns the number of bytes of salt that should be supplied when * generating keys with this algorithm. * *

PKCS #5 algorithms require exactly 8 bytes of salt. PKCS #12 * algorithms take * a variable length, but recommend that the salt length be at least * as long as the output of the hash function. For SHA-1, the output * length is 20 bytes. */ public int getSaltLength() { return saltLength; } /////////////////////////////////////////////////////////////////////// // OIDs /////////////////////////////////////////////////////////////////////// private static final OBJECT_IDENTIFIER PKCS5 = OBJECT_IDENTIFIER.PKCS5; private static final OBJECT_IDENTIFIER PKCS12_PBE = OBJECT_IDENTIFIER.PKCS12.subBranch(1); /////////////////////////////////////////////////////////////////////// // OID mapping /////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// // PKCS 5 v2 public static final PBEAlgorithm PBE_PKCS5_PBKDF2 = new PBEAlgorithm( SEC_OID_PKCS5_PBKDF2, "PBKDF2", 128, PKCS5.subBranch(12), EncryptionAlgorithm.AES_128_CBC, 8 ); ////////////////////////////////////////////////////////////// // PKCS 5 v2 public static final PBEAlgorithm PBE_PKCS5_PBES2 = new PBEAlgorithm( SEC_OID_PKCS5_PBES2, "PBES2", 128, PKCS5.subBranch(13), EncryptionAlgorithm.AES_128_CBC, 8 ); ////////////////////////////////////////////////////////////// // PKCS 5 v2 public static final PBEAlgorithm PBE_PKCS5_PBMAC1 = new PBEAlgorithm( SEC_OID_PKCS5_PBMAC1, "PBMAC1", 128, PKCS5.subBranch(14), EncryptionAlgorithm.AES_128_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_MD2_DES_CBC = new PBEAlgorithm( SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC, "PBE/MD2/DES/CBC", 56, PKCS5.subBranch(1), EncryptionAlgorithm.DES_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_MD5_DES_CBC = new PBEAlgorithm( SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC, "PBE/MD5/DES/CBC", 56, PKCS5.subBranch(3), EncryptionAlgorithm.DES_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_DES_CBC = new PBEAlgorithm( SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC, "PBE/SHA1/DES/CBC", 56, PKCS5.subBranch(10), EncryptionAlgorithm.DES_CBC, 8 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC4_128 = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4, "PBE/SHA1/RC4-128", 128, PKCS12_PBE.subBranch(1), EncryptionAlgorithm.RC4, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC4_40 = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4, "PBE/SHA1/RC4-40", 40, PKCS12_PBE.subBranch(2), EncryptionAlgorithm.RC4, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_DES3_CBC = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC, "PBE/SHA1/DES3/CBC", 168, PKCS12_PBE.subBranch(3), EncryptionAlgorithm.DES3_CBC, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC2_128_CBC = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC, "PBE/SHA1/RC2-128", 128, PKCS12_PBE.subBranch(5), EncryptionAlgorithm.RC2_CBC, 20 ); ////////////////////////////////////////////////////////////// public static final PBEAlgorithm PBE_SHA1_RC2_40_CBC = new PBEAlgorithm( SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC, "PBE/SHA1/RC2-40", 40, PKCS12_PBE.subBranch(6), EncryptionAlgorithm.RC2_CBC, 20 ); } jss-4.4.3/jss/org/mozilla/jss/crypto/PBEKeyGenParams.java000066400000000000000000000105441326145000000232100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.KeySpec; import org.mozilla.jss.util.Password; public class PBEKeyGenParams implements AlgorithmParameterSpec, KeySpec { private Password pass; private byte[] salt; private int iterations; private EncryptionAlgorithm encryptionAlgorithm = EncryptionAlgorithm.DES3_CBC; private PBEKeyGenParams() { } static private final int DEFAULT_SALT_LENGTH = 8; static private final int DEFAULT_ITERATIONS = 1; /** * Creates PBE parameters. * * @param pass The password. It will be cloned, so the * caller is still responsible for clearing it. It must not be null. * @param salt The salt for the PBE algorithm. Will not be cloned. * Must not be null. It is the responsibility of the caller to * use the right salt length for the algorithm. Most algorithms * use 8 bytes of salt. * @param iterations The iteration count for the PBE algorithm. */ public PBEKeyGenParams(Password pass, byte[] salt, int iterations) { if(pass==null || salt==null) { throw new NullPointerException(); } this.pass = (Password) pass.clone(); this.salt = salt; this.iterations = iterations; } /** * Creates PBE parameters using default encryption algorithm * (DES3_EDE3_CBC). * * @param pass The password. It will be cloned, so the * caller is still responsible for clearing it. It must not be null. * @param salt The salt for the PBE algorithm. Will not be cloned. * Must not be null. It is the responsibility of the caller to * use the right salt length for the algorithm. Most algorithms * use 8 bytes of salt. * @param iterations The iteration count for the PBE algorithm. */ public PBEKeyGenParams(char[] pass, byte[] salt, int iterations) { if(pass==null || salt==null) { throw new NullPointerException(); } this.pass = new Password( (char[]) pass.clone() ); this.salt = salt; this.iterations = iterations; } /** * Creates PBE parameters using default encryption algorithm * (DES3_EDE3_CBC). * * @param pass The password. It will be cloned, so the * caller is still responsible for clearing it. It must not be null. * @param salt The salt for the PBE algorithm. Will not be cloned. * Must not be null. It is the responsibility of the caller to * use the right salt length for the algorithm. Most algorithms * use 8 bytes of salt. * @param iterations The iteration count for the PBE algorithm. * @param encAlg The encryption algorithm. This is used with SOME * PBE algorithms for determining the KDF output length. */ public PBEKeyGenParams( char[] pass, byte[] salt, int iterations, EncryptionAlgorithm encAlg) { if (pass == null || salt == null) { throw new NullPointerException(); } this.pass = new Password((char[]) pass.clone()); this.salt = salt; this.iterations = iterations; if (encAlg != null) this.encryptionAlgorithm = encAlg; } /** * Returns a reference to the password, not a copy. */ public Password getPassword() { return pass; } /** * Returns a reference to the salt. */ public byte[] getSalt() { return salt; } /** * Returns the iteration count. */ public int getIterations() { return iterations; } /** * The encryption algorithm is used with SOME PBE algorithms for * determining the KDF output length. */ public EncryptionAlgorithm getEncryptionAlgorithm() { return encryptionAlgorithm; } /** * Clears the password. This should be called when this object is no * longer needed so the password is not left around in memory. */ public void clear() { pass.clear(); } protected void finalize() throws Throwable { pass.clear(); } } jss-4.4.3/jss/org/mozilla/jss/crypto/PQGParamGenException.java000066400000000000000000000006101326145000000242450ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; public class PQGParamGenException extends Exception { public PQGParamGenException() {} public PQGParamGenException(String msg) { super(msg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/PQGParams.c000066400000000000000000000243441326145000000214320ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_crypto_PQGParams.h" #include #include #include #include #include /* for PQGParams */ #include #include #include #include #include static jobject generate(JNIEnv *env, jclass PQGParamsClass, jint keySize, jint seedBytes); /********************************************************************** * P Q G P a r a m s . g e n e r a t e ( keysize ) * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_crypto_PQGParams_generateNative__I (JNIEnv *env, jclass PQGParamsClass, jint keySize) { return generate(env, PQGParamsClass, keySize, 0); } /********************************************************************** * P Q G P a r a m s . g e n e r a t e ( keysize, seedBytes ) * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_crypto_PQGParams_generateNative__II (JNIEnv *env, jclass PQGParamsClass, jint keySize, jint seedBytes) { if(seedBytes < 20 || seedBytes > 255) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "Number of bytes in seed must be in range [20,255]"); return NULL; } return generate(env, PQGParamsClass, keySize, seedBytes); } #define ZERO_SECITEM(item) (item).data=NULL; (item).len=0; /********************************************************************** * * g e n e r a t e * * INPUTS * env * The JNI environment. * this * Reference to a Java PQGGenerator object. * keySize * The size of the key, which is actually the size of P in bits. * seedBytes * The length of the seed in bytes, or 0 to let the algorithm * figure it out. * RETURNS * A new PQGParams object. */ static jobject generate(JNIEnv *env, jclass PQGParamsClass, jint keySize, jint seedBytes) { int keySizeIndex; jobject newObject = NULL; SECStatus status; PQGParams *pParams=NULL; PQGVerify *pVfy=NULL; jbyteArray bytes; jclass BigIntegerClass; jmethodID BigIntegerConstructor; jmethodID PQGParamsConstructor; /*----PQG parameters and friends----*/ SECItem P; /* prime */ SECItem Q; /* subPrime */ SECItem G; /* base */ SECItem H; SECItem seed; unsigned int counter; /*----Java versions of the PQG parameters----*/ jobject jP; jobject jQ; jobject jG; jobject jH; jint jcounter; jobject jSeed; /* basic argument validation */ PR_ASSERT(env!=NULL && PQGParamsClass!=NULL); /* clear the SECItems so we can free them indiscriminately at the end */ ZERO_SECITEM(P); ZERO_SECITEM(Q); ZERO_SECITEM(G); ZERO_SECITEM(H); ZERO_SECITEM(seed); /*********************************************************************** * PK11_PQG_ParamGen doesn't take a key size, it takes an index that * points to a valid key size. */ keySizeIndex = PQG_PBITS_TO_INDEX(keySize); if(keySizeIndex == -1 || keySize<512 || keySize>1024) { JSS_throwMsg(env, INVALID_PARAMETER_EXCEPTION, "DSA key size must be a multiple of 64 between 512 " "and 1024, inclusive"); goto finish; } /*********************************************************************** * Do the actual parameter generation. */ if(seedBytes == 0) { status = PK11_PQG_ParamGen(keySizeIndex, &pParams, &pVfy); } else { status = PK11_PQG_ParamGenSeedLen(keySizeIndex, seedBytes, &pParams, &pVfy); } if(status != SECSuccess) { JSS_throw(env, PQG_PARAM_GEN_EXCEPTION); goto finish; } /********************************************************************** * NOTE: the new PQG parameters will be verified at the Java level. */ /********************************************************************** * Get ready for the BigIntegers */ BigIntegerClass = (*env)->FindClass(env, BIG_INTEGER_CLASS_NAME); if(BigIntegerClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } BigIntegerConstructor = (*env)->GetMethodID(env, BigIntegerClass, BIG_INTEGER_CONSTRUCTOR_NAME, BIG_INTEGER_CONSTRUCTOR_SIG); if(BigIntegerConstructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /*********************************************************************** * Convert the parameters to Java types. */ if( PK11_PQG_GetPrimeFromParams( pParams, &P) || PK11_PQG_GetSubPrimeFromParams( pParams, &Q) || PK11_PQG_GetBaseFromParams( pParams, &G) || PK11_PQG_GetHFromVerify( pVfy, &H) || PK11_PQG_GetSeedFromVerify( pVfy, &seed) ) { JSS_throw(env, PQG_PARAM_GEN_EXCEPTION); goto finish; } counter = PK11_PQG_GetCounterFromVerify(pVfy); /* * construct P */ bytes = JSS_OctetStringToByteArray(env, &P); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jP = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jP==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct Q */ bytes = JSS_OctetStringToByteArray(env, &Q); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jQ = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jQ==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct G */ bytes = JSS_OctetStringToByteArray(env, &G); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jG = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jG==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct seed */ bytes = JSS_OctetStringToByteArray(env, &seed); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jSeed = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jSeed==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct H */ bytes = JSS_OctetStringToByteArray(env, &H); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } jH = (*env)->NewObject(env, BigIntegerClass, BigIntegerConstructor, bytes); if(jH==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * construct counter */ jcounter = counter; /********************************************************************** * Construct the PQGParams object */ PQGParamsConstructor = (*env)->GetMethodID( env, PQGParamsClass, PQG_PARAMS_CONSTRUCTOR_NAME, PQG_PARAMS_CONSTRUCTOR_SIG); if(PQGParamsConstructor==NULL) { ASSERT_OUTOFMEM(env); goto finish; } newObject = (*env)->NewObject( env, PQGParamsClass, PQGParamsConstructor, jP, jQ, jG, jSeed, jcounter, jH); finish: if(pParams!=NULL) { PK11_PQG_DestroyParams(pParams); } if(pVfy!=NULL) { PK11_PQG_DestroyVerify(pVfy); } SECITEM_FreeItem(&P, PR_FALSE /*don't free P itself*/); SECITEM_FreeItem(&Q, PR_FALSE); SECITEM_FreeItem(&G, PR_FALSE); SECITEM_FreeItem(&H, PR_FALSE); SECITEM_FreeItem(&seed, PR_FALSE); return newObject; } /********************************************************************** * * P Q G P a r a m s . p a r a m s A r e V a l i d * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_crypto_PQGParams_paramsAreValidNative (JNIEnv *env, jobject this, jbyteArray jP, jbyteArray jQ, jbyteArray jG, jbyteArray jSeed, jint jCounter, jbyteArray jH) { jboolean valid=JNI_FALSE; PQGParams *pParams=NULL; PQGVerify *pVfy=NULL; SECStatus verifyResult; /*---PQG and verification params in C---*/ SECItem P; SECItem Q; SECItem G; SECItem seed; SECItem H; unsigned int counter; PR_ASSERT(env!=NULL && this!=NULL); /* clear the SECItems so we can free them indiscriminately later */ ZERO_SECITEM(P); ZERO_SECITEM(Q); ZERO_SECITEM(G); ZERO_SECITEM(seed); ZERO_SECITEM(H); /********************************************************************** * Extract the Java parameters */ if( JSS_ByteArrayToOctetString(env, jP, &P) || JSS_ByteArrayToOctetString(env, jQ, &Q) || JSS_ByteArrayToOctetString(env, jG, &G) || JSS_ByteArrayToOctetString(env, jSeed, &seed) || JSS_ByteArrayToOctetString(env, jH, &H) ) { goto finish; } counter = jCounter; /*********************************************************************** * Construct PQGParams and PQGVerify structures. */ pParams = PK11_PQG_NewParams(&P, &Q, &G); pVfy = PK11_PQG_NewVerify(counter, &seed, &H); if(pParams==NULL || pVfy==NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /*********************************************************************** * Perform the verification. */ if( PK11_PQG_VerifyParams(pParams, pVfy, &verifyResult) != SECSuccess) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } if(verifyResult == SECSuccess) { valid = JNI_TRUE; } finish: SECITEM_FreeItem(&P, PR_FALSE /*don't free P itself*/); SECITEM_FreeItem(&Q, PR_FALSE); SECITEM_FreeItem(&G, PR_FALSE); SECITEM_FreeItem(&seed, PR_FALSE); SECITEM_FreeItem(&H, PR_FALSE); PK11_PQG_DestroyParams(pParams); PK11_PQG_DestroyVerify(pVfy); return valid; } jss-4.4.3/jss/org/mozilla/jss/crypto/PQGParams.java000066400000000000000000000177461326145000000221410ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.math.BigInteger; import java.security.spec.DSAParameterSpec; import org.mozilla.jss.util.Assert; /** * PQG parameters for DSA key generation, along with the seed, counter, * and H values for verification. *

This class has two main purposes: * generating PQG parameters and verifying PQG parameters. To generate * PQG parameters, call one of the static generate methods. * They will return a new set of PQG parameters. To verify existing PQG * parameters, create a new PQGParams object with the * constructor and call paramsAreValid on the object. * *

It is necessary to call CryptoManager.initialize before * using this class. * */ public class PQGParams extends DSAParameterSpec { /** * Creates a PQGParams object from a set of pre-computed DSA * parameters. * * @param P The DSA prime parameter. * @param Q The DSA sub-prime parameter. * @param G The DSA base parameter. * @param seed The Seed used to calculate P, Q, and G. * @param counter The Counter (C) used to calculate P, Q, and G. * @param H The H value used to generate P, Q, and G. */ public PQGParams(BigInteger P, BigInteger Q, BigInteger G, BigInteger seed, int counter, BigInteger H) { super(P, Q, G); this.seed = seed; this.counter = counter; this.H = H; } /** * Generates P, Q, and G parameters for DSA key generation. Also * provides the seed, counter, and H values for verification of the * P, Q, and G. The parameters are generated and then verified * before being returned. The length of the Seed will equal the * length of P. * * It is necessary to call one of the * CryptoManager.initialize functions before calling * this method. * * @param keySize The size of P in bits. Keys generated by these P, * Q, and G values will have this length. Valid key sizes * are multiples of 64 in the closed interval [512,1024]. * This also dictates the length of H and Seed. * @return A new set of P, Q, and G parameters, along with the Seed, * Counter, and H values used to generate them. * @exception java.security.InvalidParameterException If the keySize * is outside the bounds described by the DSA key pair * generation algorithm. * @exception org.mozilla.jss.crypto.PQGParamGenException If an error * occurs during the generation process. * @see org.mozilla.jss.CryptoManager#initialize */ public static PQGParams generate(int keySize) throws java.security.InvalidParameterException, PQGParamGenException { PQGParams pqg = generateNative(keySize); if( ! pqg.paramsAreValid() ) { throw new PQGParamGenException( "Generated parameters did not verify correctly"); } return pqg; } /** * Does the actual work of generation, but does not verify. */ private static native PQGParams generateNative(int keySize) throws java.security.InvalidParameterException, PQGParamGenException; /** * Generates P, Q, and G parameters for DSA key generation. Also * provides the seed, counter, and H values for verification of the * P, Q, and G. The parameters are generated and then verified * before being returned. * * It is necessary to call one of the * CryptoManager.initialize functions before calling * this method. * * @param keySize The size of P in bits. Keys generated by these P, * Q, and G values will have this length. Valid key sizes * are multiples of 64 in the closed interval [512,1024]. * This also dictates the length of H. * @param seedBytes The number of bytes in the Seed value used to * generate P, Q, and G. seedBytes must be * from the closed interval [20,255]. * @return A new set of P, Q, and G parameters, along with the Seed, * Counter, and H values used to generate them. * @exception java.security.InvalidParameterException If the keySize * or number of seed bytes is outside the bounds described by the * DSA key pair generation algorithm. * @exception org.mozilla.jss.crypto.PQGParamGenException If an error * occurs during the generation process. * @see org.mozilla.jss.CryptoManager#initialize */ public static PQGParams generate(int keySize, int seedBytes) throws java.security.InvalidParameterException, PQGParamGenException { PQGParams pqg = generateNative(keySize, seedBytes); if( ! pqg.paramsAreValid() ) { throw new PQGParamGenException( "Generated parameters did not verify correctly"); } return pqg; } /** * Does the actual work of generation, but does not verify. */ private static native PQGParams generateNative(int keySize, int seedBytes) throws java.security.InvalidParameterException, PQGParamGenException; /** * Produces an unsigned byte-array representation of a BigInteger. * *

BigInteger adds an extra sign bit to the beginning of its byte * array representation. In some cases this will cause the size * of the byte array to increase, which may be unacceptable for some * applications. This function returns a minimal byte array representing * the BigInteger without extra sign bits. * * @return An unsigned, big-endian byte array representation * of a BigInteger. */ public static byte[] BigIntegerToUnsignedByteArray(BigInteger big) { byte[] ret; // big must not be negative Assert._assert(big.signum() != -1); // bitLength is the size of the data without the sign bit. If // it exactly fills an integral number of bytes, that means a whole // new byte will have to be added to accomodate the sign bit. In // this case we need to remove the first byte. if(big.bitLength() % 8 == 0) { byte[] array = big.toByteArray(); // The first byte should just be sign bits Assert._assert( array[0] == 0 ); ret = new byte[array.length-1]; System.arraycopy(array, 1, ret, 0, ret.length); } else { ret = big.toByteArray(); } return ret; } /** * Verifies the PQG parameters using the seed, counter, and H values. * @return true if the parameters verified correctly, false if they * did not verify. */ public boolean paramsAreValid() { return paramsAreValidNative(BigIntegerToUnsignedByteArray( getP() ), BigIntegerToUnsignedByteArray( getQ() ), BigIntegerToUnsignedByteArray( getG() ), BigIntegerToUnsignedByteArray( seed ), counter, BigIntegerToUnsignedByteArray( H )); } private native boolean paramsAreValidNative(byte[] P, byte[] Q, byte[]G, byte[] seed, int counter, byte[] H); /** * @return The Seed used to generate P, Q, and G. */ public BigInteger getSeed() { return seed; } /** * @return The Counter (C) used to generate P, Q, and G. */ public int getCounter() { return counter; } /** * @return The H value used to generate P, Q, and G. */ public BigInteger getH() { return H; } private BigInteger seed; private int counter; private BigInteger H; } jss-4.4.3/jss/org/mozilla/jss/crypto/PrivateKey.java000066400000000000000000000075001326145000000224140ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import java.util.Hashtable; import org.mozilla.jss.util.Assert; import java.security.NoSuchAlgorithmException; /** * Private Keys used by JSS. All the private keys handled by JSS are * of this type, which is a subtype of java.security.PrivateKey. */ public interface PrivateKey extends java.security.PrivateKey { public static final Type RSA = Type.RSA; public static final Type DSA = Type.DSA; public static final Type EC = Type.EC; public static final Type DiffieHellman = Type.DiffieHellman; /** * Returns the type (RSA or DSA) of this private key. */ public Type getType(); /** * Returns the unique ID of this key. Unique IDs can be used to match * certificates to keys. * * @see org.mozilla.jss.crypto.TokenCertificate#getUniqueID * @deprecated This ID is based on an implementation that might change. * If this functionality is required, it should be provided in * another way, such as a function that directly matches a cert and * key. */ public byte[] getUniqueID() throws TokenException; /** * Returns the size, in bits, of the modulus of an RSA key. * Returns -1 for other types of keys. */ public int getStrength(); /** * Returns the CryptoToken that owns this private key. Cryptographic * operations with this key may only be performed on the token that * owns the key. */ public CryptoToken getOwningToken(); public static final class Type { private OBJECT_IDENTIFIER oid; private String name; private int pkcs11Type; private Type() { } private Type(OBJECT_IDENTIFIER oid, String name, int pkcs11Type) { this.oid = oid; this.name = name; Object old = oidMap.put(oid, this); this.pkcs11Type = pkcs11Type; Assert._assert( old == null ); } private static Hashtable oidMap = new Hashtable(); public static Type fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object obj = oidMap.get(oid); if( obj == null ) { throw new NoSuchAlgorithmException(); } return (Type) obj; } /** * Returns a string representation of the algorithm, such as * "RSA", "DSA", or "EC". */ public String toString() { return name; } public OBJECT_IDENTIFIER toOID() { return oid; } public int getPKCS11Type() { return pkcs11Type; } // OID for DiffieHellman, from RFC 2459 7.3.2. public static OBJECT_IDENTIFIER DH_OID = new OBJECT_IDENTIFIER( new long[] {1, 2, 840, 10046, 2, 1} ); // From PKCS #11 private static int CKK_RSA = 0x0; private static int CKK_DSA = 0x1; private static int CKK_DH = 0x2; private static int CKK_EC = 0x3; private static int CKK_X9_42_DH = 0x4; private static int CKK_KEA = 0x5; public static final Type RSA = new Type( OBJECT_IDENTIFIER.PKCS1.subBranch(1), "RSA", CKK_RSA ); public static final Type DSA = new Type( Algorithm.ANSI_X9_ALGORITHM.subBranch(1), "DSA", CKK_DSA); public static final Type EC = new Type( Algorithm.ANSI_X962_OID.subBranch(2).subBranch(1), "EC", CKK_EC); public static final Type DiffieHellman = new Type( DH_OID, "DiffieHellman", CKK_DH ); } } jss-4.4.3/jss/org/mozilla/jss/crypto/RSAParameterSpec.java000066400000000000000000000022731326145000000234340ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.spec.AlgorithmParameterSpec; import java.math.BigInteger; /** * This class specifies the parameters used for generating an RSA key pair. */ public class RSAParameterSpec implements AlgorithmParameterSpec { /** * Creates a new RSAParameterSpec with the specified parameter values. * @param keySize The size of the modulus in bits. * @param publicExponent The public exponent e. Common values * are 3, 17, and 65537. 65537 is recommended. */ public RSAParameterSpec(int keySize, BigInteger publicExponent) { this.keySize = keySize; this.publicExponent = publicExponent; } /** * Returns the size of the modulus in bits. */ public int getKeySize() { return keySize; } /** * Returns the public exponent e. */ public BigInteger getPublicExponent() { return publicExponent; } private int keySize; private BigInteger publicExponent; } jss-4.4.3/jss/org/mozilla/jss/crypto/SecretDecoderRing.c000066400000000000000000000037141326145000000231700ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_crypto_SecretDecoderRing.h" #include #include #include #include #include typedef enum {SDR_ENCRYPT, SDR_DECRYPT} SDROp; static jbyteArray doSDR(JNIEnv *env, jobject this, jbyteArray inputBA, SDROp optype) { SECStatus status; jbyteArray outputBA = NULL; SECItem keyID = {siBuffer, NULL, 0}; SECItem *input= NULL; SECItem output = {siBuffer, NULL, 0}; /* convert input to SECItem */ if( inputBA == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } input = JSS_ByteArrayToSECItem(env, inputBA); if( input == NULL) { /* exception was thrown */ goto finish; } /* perform the operation*/ if( optype == SDR_ENCRYPT ) { status = PK11SDR_Encrypt(&keyID, input, &output, NULL /*cx*/); } else { PR_ASSERT( optype == SDR_DECRYPT); status = PK11SDR_Decrypt(input, &output, NULL /*cx*/); } if(status != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Operation failed"); goto finish; } /* convert output to byte array */ outputBA = JSS_SECItemToByteArray(env, &output); finish: if( input != NULL) { SECITEM_FreeItem(input, PR_TRUE /* freeit */); } SECITEM_FreeItem(&output, PR_FALSE /*freeit*/); return outputBA; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_crypto_SecretDecoderRing_encrypt( JNIEnv *env, jobject this, jbyteArray plaintextBA) { return doSDR(env, this, plaintextBA, SDR_ENCRYPT); } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_crypto_SecretDecoderRing_decrypt( JNIEnv *env, jobject this, jbyteArray ciphertextBA) { return doSDR(env, this, ciphertextBA, SDR_DECRYPT); } jss-4.4.3/jss/org/mozilla/jss/crypto/SecretDecoderRing.java000066400000000000000000000053671326145000000236750ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.io.UnsupportedEncodingException; /** * This is a special-purpose interface for NSS. It is used for encrypting * data with a secret key stored in the NSS key database (which is in turn * protected with a password). It thus provides a quick, convenient way * to encrypt stuff your application wants to keep around for its own use: * for example, the list of web passwords stored in the web browser. * *

A dedicated key is used to encrypt all SecretDecoderRing data. * The same key is used for all SDR data, and not for any other data. * This key will be generated the first time it is needed. * *

The cipher used is DES3-EDE (Triple-DES) in CBC mode. The ciphertext * is DER-encoded in the following ASN.1 data structure: *

 *    SEQUENCE {
 *      keyid       OCTET STRING,
 *      alg         AlgorithmIdentifier,
 *      ciphertext  OCTET STRING }
 * 
* *

You must set the password on the Internal Key Storage Token * (aka software token, key3.db) before you use the SecretDecoderRing. */ public class SecretDecoderRing { public static final String encodingFormat = "UTF-8"; /** * Encrypts the given plaintext with the Secret Decoder Ring key stored * in the NSS key database. */ public native byte[] encrypt(byte[] plaintext) throws TokenException; /** * Encrypts the given plaintext string with the Secret Decoder Ring key * stored in the NSS key database. */ public byte[] encrypt(String plaintext) throws TokenException { try { return encrypt(plaintext.getBytes(encodingFormat)); } catch(UnsupportedEncodingException e) { // this shouldn't happen, because we use a universally-supported // charset throw new RuntimeException(e.getMessage()); } } /** * Decrypts the given ciphertext with the Secret Decoder Ring key stored * in the NSS key database. */ public native byte[] decrypt(byte[] ciphertext) throws TokenException; /** * Decrypts the given ciphertext with the Secret Decoder Ring key stored * in the NSS key database, returning the original plaintext string. */ public String decryptToString(byte[] ciphertext) throws TokenException { try { return new String(decrypt(ciphertext), encodingFormat); } catch(UnsupportedEncodingException e) { // this shouldn't happen, because we use a universally-supported // charset throw new RuntimeException(e.getMessage()); } } } jss-4.4.3/jss/org/mozilla/jss/crypto/SecretKeyFacade.java000066400000000000000000000011701326145000000233100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; public class SecretKeyFacade implements javax.crypto.SecretKey { public SymmetricKey key; public SecretKeyFacade(SymmetricKey symk) { key = symk; } public String getAlgorithm() { return key.getAlgorithm(); } public byte[] getEncoded() { return key.getEncoded(); } public String getFormat() { return key.getFormat(); } } jss-4.4.3/jss/org/mozilla/jss/crypto/ShortBufferException.java000066400000000000000000000006201326145000000244350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This class is a placeholder for javax.crypto.ShortBufferException until * we move to JDK 1.2. */ public class ShortBufferException extends Exception { } jss-4.4.3/jss/org/mozilla/jss/crypto/Signature.java000066400000000000000000000134261326145000000222760ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.util.*; import java.security.*; import java.security.spec.AlgorithmParameterSpec; /** * A class for producing and verifying digital signatures. * Instances of this class can be obtain from CryptoTokens. * * @see org.mozilla.jss.crypto.CryptoToken#getSignatureContext */ public class Signature { protected Signature() { } Signature(SignatureAlgorithm algorithm, SignatureSpi engine) { this.algorithm = algorithm; this.engine = engine; } /** * This is not supported yet. */ public Provider getProvider() { Assert.notYetImplemented("Signature.getProvider"); return null; } /** * Supplying sources of randoms is not supported yet. public void initSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException, TokenException { engine.engineInitSign(privateKey, random); } */ /** * Initialize the signature context for signing. * @param privateKey The private key with which to sign. * @exception InvalidKeyException If the key is the wrong type for the * algorithm or does not exist on the token of this signature * context. * @exception TokenException If an error occurred on the token. */ public void initSign(PrivateKey privateKey) throws InvalidKeyException, TokenException { engine.engineInitSign(privateKey); } /** * Initialize the signature context for verifying. * @param publicKey The public key with which to verify the signature. * @exception InvalidKeyException If the key is the wrong type for the * algorithm. * @exception TokenException If an error occurs on the token. */ public void initVerify(PublicKey publicKey) throws InvalidKeyException, TokenException { engine.engineInitVerify(publicKey); } /** * Set parameters for the signing algorithm. This is currently not * supported or needed. * @param params Parameters for the signing algorithm. * @exception InvalidAlgorithmParameterException If there is something wrong * with the parameters. * @exception TokenException If an error occurs on the token. */ public void setParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException, TokenException { engine.engineSetParameter(params); } /** * Finish a signing operation and return the signature. * @exception SignatureException If an error occurs with the signing * operation. * @exception TokenException If an error occurs on the token. * @return The signature. */ public byte[] sign() throws SignatureException, TokenException { return engine.engineSign(); } /** * Finish a signing operation and store the signature in the provided * buffer. * @param outbuf Buffer to hold the signature * @param offset Offset in buffer at which to store signature. * @param len Number of bytes of buffer available for signature. * @return int The number of bytes placed into outbuf. * @exception SignatureException If an error occurred while signing, or * len was insufficient to contain the signature. * @exception TokenException If an error occurred on the token. */ public int sign(byte[] outbuf, int offset, int len) throws SignatureException, TokenException { return engine.engineSign(outbuf, offset, len); } /** * Finish a verification operation. * @param signature The signature to be verified. * @return true if the signature is valid, false if it is invalid. * @exception SignatureException If an error occurred with the verification * operation * @exception TokenException If an error occurred on the token. */ public boolean verify(byte[] signature) throws SignatureException, TokenException { return engine.engineVerify(signature); } /** * Provide more data for a signature or verification operation. * @param b A byte to be signed or verified. * @exception SignatureException If an error occurs in the * signature/verifcation. * @exception TokenException If an error occurs on the token. */ public void update(byte b) throws SignatureException, TokenException { engine.engineUpdate(b); } /** * Provide more data for a signature or verification operation. * @param data An array of bytes to be signed or verified. * @exception SignatureException If an error occurs in the * signature/verifcation. * @exception TokenException If an error occurs on the token. */ public void update(byte[] data) throws SignatureException, TokenException { engine.engineUpdate(data, 0, data.length); } /** * Provide more data for a signature or verification operation. * @param data An array of bytes, some of which will be signed or verified. * @param off The beginning offset of the bytes to be signed/verified. * @param len The number of bytes to be signed/verified. * @exception SignatureException If an error occurs in the * signature/verification. * @exception TokenException If an error occurs on the token. */ public void update(byte[] data, int off, int len) throws SignatureException, TokenException { engine.engineUpdate(data, off, len); } /** * Returns the name of the algorithm to be used for signing. */ public String getAlgorithm() { return algorithm.toString(); } /** * Returns the algorithm to be used for signing. */ public SignatureAlgorithm getAlgorithmID() { return algorithm; } /** * Cloning is not supported yet */ protected Object clone() throws CloneNotSupportedException { // no cloning for now throw new CloneNotSupportedException(); } protected SignatureAlgorithm algorithm; protected SignatureSpi engine; } jss-4.4.3/jss/org/mozilla/jss/crypto/SignatureAlgorithm.java000066400000000000000000000164501326145000000241450ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import java.util.Hashtable; import java.security.NoSuchAlgorithmException; /** * Algorithms that can be used for signing. */ public class SignatureAlgorithm extends Algorithm { private static Hashtable oidMap = new Hashtable(); protected SignatureAlgorithm(int oidIndex, String name, SignatureAlgorithm signingAlg, DigestAlgorithm digestAlg, OBJECT_IDENTIFIER oid) { super(oidIndex, name, oid); if(signingAlg == null) { this.signingAlg = this; } else { this.signingAlg = signingAlg; } this.digestAlg = digestAlg; oidMap.put(oid, this); } /** * Looks up the signature algorithm with the given OID. * @exception NoSuchAlgorithmException If no algorithm is found with this * OID. */ public static SignatureAlgorithm fromOID(OBJECT_IDENTIFIER oid) throws NoSuchAlgorithmException { Object alg = oidMap.get(oid); if( alg == null ) { throw new NoSuchAlgorithmException(); } return (SignatureAlgorithm) alg; } /** * The raw encryption portion of the signature algorithm. For example, * SignatureAlgorithm.RSASignatureWithMD2Digest.getSigningAlg == * SignatureAlgorithm.RSASignature. */ public Algorithm getSigningAlg() { return signingAlg; } public SignatureAlgorithm getRawAlg() { return signingAlg; } private SignatureAlgorithm signingAlg; /** * The digest portion of the signature algorithm. */ public DigestAlgorithm getDigestAlg() throws NoSuchAlgorithmException { if( digestAlg == null ) { throw new NoSuchAlgorithmException(); } return digestAlg; } private DigestAlgorithm digestAlg; ////////////////////////////////////////////////////////////////////// // Signature Algorithms ////////////////////////////////////////////////////////////////////// /********************************************************************** * Raw RSA signing. This algorithm does not do any hashing, it merely * encrypts its input, which should be a hash. */ public static final SignatureAlgorithm RSASignature = new SignatureAlgorithm(SEC_OID_PKCS1_RSA_ENCRYPTION, "RSA", null, null, OBJECT_IDENTIFIER.PKCS1.subBranch(1) ); /********************************************************************** * Raw DSA signing. This algorithm does not do any hashing, it merely * operates on its input, which should be a hash. */ public static final SignatureAlgorithm DSASignature = new SignatureAlgorithm(SEC_OID_ANSIX9_DSA_SIGNATURE, "DSA", null, null, ANSI_X9_ALGORITHM.subBranch(1) ); /********************************************************************** * Raw EC signing. This algorithm does not do any hashing, it merely * operates on its input, which should be a hash. */ public static final SignatureAlgorithm ECSignature = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST, "EC", null, null, ANSI_X962_OID.subBranch(2).subBranch(1) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithMD2Digest = new SignatureAlgorithm(SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, "RSASignatureWithMD2Digest", RSASignature, DigestAlgorithm.MD2, OBJECT_IDENTIFIER.PKCS1.subBranch(2) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithMD5Digest = new SignatureAlgorithm(SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, "RSASignatureWithMD5Digest", RSASignature, DigestAlgorithm.MD5, OBJECT_IDENTIFIER.PKCS1.subBranch(4) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA1Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA1Digest", RSASignature, DigestAlgorithm.SHA1, OBJECT_IDENTIFIER.PKCS1.subBranch(5) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm DSASignatureWithSHA1Digest = new SignatureAlgorithm(SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST, "DSASignatureWithSHA1Digest", DSASignature, DigestAlgorithm.SHA1, ANSI_X9_ALGORITHM.subBranch(3) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA1Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE, "ECSignatureWithSHA1Digest", ECSignature, DigestAlgorithm.SHA1, ANSI_X962_OID.subBranch(4).subBranch(1) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA256Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, "ECSignatureWithSHA256Digest", ECSignature, DigestAlgorithm.SHA256, ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(2) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA384Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE, "ECSignatureWithSHA384Digest", ECSignature, DigestAlgorithm.SHA384, ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(3) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm ECSignatureWithSHA512Digest = new SignatureAlgorithm(SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE, "ECSignatureWithSHA512Digest", ECSignature, DigestAlgorithm.SHA512, ANSI_X962_OID.subBranch(4).subBranch(3).subBranch(4) ); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA256Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA256Digest", RSASignature, DigestAlgorithm.SHA256, OBJECT_IDENTIFIER.PKCS1.subBranch(11)); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA384Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA384Digest", RSASignature, DigestAlgorithm.SHA384, OBJECT_IDENTIFIER.PKCS1.subBranch(12)); ////////////////////////////////////////////////////////////////////// public static final SignatureAlgorithm RSASignatureWithSHA512Digest = new SignatureAlgorithm(SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION, "RSASignatureWithSHA512Digest", RSASignature, DigestAlgorithm.SHA512, OBJECT_IDENTIFIER.PKCS1.subBranch(13)); } jss-4.4.3/jss/org/mozilla/jss/crypto/SignatureSpi.java000066400000000000000000000026501326145000000227470ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.*; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; /** * You don't need to use this unless you are hacking JSS. */ public abstract class SignatureSpi { public abstract void engineInitVerify(PublicKey publicKey) throws InvalidKeyException, TokenException; public abstract void engineInitSign(PrivateKey privateKey) throws InvalidKeyException, TokenException; public abstract void engineInitSign(PrivateKey privateKey, SecureRandom random) throws InvalidKeyException, TokenException; public abstract void engineUpdate(byte b) throws SignatureException, TokenException; public abstract void engineUpdate(byte[] b, int off, int len) throws SignatureException, TokenException; public abstract byte[] engineSign() throws SignatureException, TokenException; public abstract int engineSign(byte[] outbuf, int offset, int len) throws SignatureException, TokenException; public abstract boolean engineVerify(byte[] sigBytes) throws SignatureException, TokenException; public abstract void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException, TokenException; } jss-4.4.3/jss/org/mozilla/jss/crypto/SymmetricKey.java000066400000000000000000000075531326145000000227660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.util.Hashtable; import java.security.NoSuchAlgorithmException; public interface SymmetricKey { public static final Type DES = Type.DES; public static final Type DES3 = Type.DES3; public static final Type RC4 = Type.RC4; public static final Type RC2 = Type.RC2; public static final Type SHA1_HMAC = Type.SHA1_HMAC; public static final Type AES = Type.AES; public Type getType(); public CryptoToken getOwningToken(); public int getStrength(); public int getLength(); public byte[] getKeyData() throws NotExtractableException; public static class NotExtractableException extends Exception { public NotExtractableException() { super(); } public NotExtractableException(String mesg) { super(mesg); } } String getAlgorithm(); byte[] getEncoded(); String getFormat(); String getNickName(); void setNickName(String nickName); public final static class Type { // all names converted to lowercase for case insensitivity private static Hashtable nameMap = new Hashtable(); private String name; private KeyGenAlgorithm keyGenAlg; private Type() { } private Type(String name, KeyGenAlgorithm keyGenAlg) { this.name = name; this.keyGenAlg = keyGenAlg; nameMap.put(name.toLowerCase(), this); } public static final Type DES = new Type("DES", KeyGenAlgorithm.DES); public static final Type DES3 = new Type("DESede", KeyGenAlgorithm.DES3); public static final Type DESede = DES3; public static final Type RC4 = new Type("RC4", KeyGenAlgorithm.RC4); public static final Type RC2 = new Type("RC2", KeyGenAlgorithm.RC2); public static final Type SHA1_HMAC = new Type("SHA1_HMAC", KeyGenAlgorithm.PBA_SHA1_HMAC); public static final Type AES = new Type("AES", KeyGenAlgorithm.AES); public String toString() { return name; } public KeyGenAlgorithm getKeyGenAlg() throws NoSuchAlgorithmException { if( keyGenAlg == null ) { throw new NoSuchAlgorithmException(name); } return keyGenAlg; } public static Type fromName(String name) throws NoSuchAlgorithmException { Object type = nameMap.get(name.toLowerCase()); if( type == null ) { throw new NoSuchAlgorithmException(); } else { return (Type) type; } } } /** * In PKCS #11, each key can be marked with the operations it will * be used to perform. Some tokens require that a key be marked for * an operation before the key can be used to perform that operation; * other tokens don't care. * *

When you unwrap a symmetric key, you must specify which one of these * operations it will be used to perform. */ public final static class Usage { private Usage() { } private Usage(int val) { this.val = val;} private int val; public int getVal() { return val; } // these enums must match the JSS_symkeyUsage list in Algorithm.c // and the opFlagForUsage list in PK11KeyGenerator.java public static final Usage ENCRYPT = new Usage(0); public static final Usage DECRYPT = new Usage(1); public static final Usage WRAP = new Usage(2); public static final Usage UNWRAP = new Usage(3); public static final Usage SIGN = new Usage(4); public static final Usage VERIFY = new Usage(5); } } jss-4.4.3/jss/org/mozilla/jss/crypto/SymmetricKeyDeriver.java000066400000000000000000000063071326145000000243030ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.security.PublicKey; import java.security.InvalidKeyException; public interface SymmetricKeyDeriver { /* Use with the encrypt type mechanisms Example: initDerive( symKey, (PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA) 4354L, derivationData, null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16); */ public abstract void initDerive(SymmetricKey baseKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException; /* Use with key extraction and key concatanation mechanisms Example: param: byte array that has the bit position of where to extract initDerive( derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8); initDerive( baseSymKey,secondarySymKey, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0); */ public abstract void initDerive(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException; public abstract SymmetricKey derive() throws TokenException; } jss-4.4.3/jss/org/mozilla/jss/crypto/TokenCertificate.java000066400000000000000000000023411326145000000235520ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * An X509 Certificate that lives on a PKCS #11 token. * Many of the X509Certificates returned by JSS calls are actually * TokenCertificates. * To find out if an X509Certificate is a TokenCertificate, use * instanceof. */ public interface TokenCertificate extends X509Certificate { /** * Returns the unique ID of this key. Unique IDs can be used to match * certificates to keys. * * @see org.mozilla.jss.crypto.PrivateKey#getUniqueID * @deprecated This ID is based on an implementation that might change. * If this functionality is required, it should be provided in * another way, such as a function that directly matches a cert and * key. */ public abstract byte[] getUniqueID(); /** * Returns the CryptoToken that owns this certificate. Cryptographic * operations with this key may only be performed on the token that * owns the key. */ public abstract CryptoToken getOwningToken(); } jss-4.4.3/jss/org/mozilla/jss/crypto/TokenException.java000066400000000000000000000012221326145000000232630ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This class indicates that an unknown error occurred on a CryptoToken. * The nature of CryptoTokens makes such unpredictable errors possible. * For example, a smartcard could be yanked out of its slot in the middle * of a cryptographic operation. */ public class TokenException extends Exception { public TokenException() { super(); } public TokenException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/TokenRuntimeException.java000066400000000000000000000012561326145000000246360ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This class indicates that an unknown error occurred on a CryptoToken. * The nature of CryptoTokens makes such unpredictable errors possible. * For example, a smartcard could be yanked out of its slot in the middle * of a cryptographic operation. */ public class TokenRuntimeException extends RuntimeException { public TokenRuntimeException() { super(); } public TokenRuntimeException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/crypto/TokenSupplier.java000066400000000000000000000014111326145000000231300ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * An interface that allows providers to access CryptoManager without actually * knowing about CryptoManager. This is necessary to prevent cyclic * dependencies. CryptoManager knows about the providers, so the providers * can't know about CryptoManager. Instead, CryptoManager implements * this interface. */ public interface TokenSupplier { public CryptoToken getInternalCryptoToken(); public JSSSecureRandom getSecureRNG(); public CryptoToken getThreadToken(); public void setThreadToken(CryptoToken token); } jss-4.4.3/jss/org/mozilla/jss/crypto/TokenSupplierManager.java000066400000000000000000000016441326145000000244330ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * The org.mozilla.jss.provider package comes before CryptoManager in * the dependency list, so this class is used to allow them to access * CryptoManager sneakily. When CryptoManager initializes, it registers * itself as a token supplier with setTokenSupplier. Then * the providers call getTokenSupplier when they need to use * CryptoManager. CryptoManager implements the TokenSupplier interface. */ public class TokenSupplierManager { static private TokenSupplier supplier; static public void setTokenSupplier(TokenSupplier ts) { supplier = ts; } static public TokenSupplier getTokenSupplier() { return supplier; } } jss-4.4.3/jss/org/mozilla/jss/crypto/Tunnel.java000066400000000000000000000011271326145000000215750ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; /** * This is a private JSS class that allows the pkcs11 package access * to some of the * package methods in the crypto package. A friend declaration would * have been ideal. */ public class Tunnel { protected static Signature ConstructSignature( SignatureAlgorithm alg, SignatureSpi engine) { return new Signature(alg, engine); } } jss-4.4.3/jss/org/mozilla/jss/crypto/X509Certificate.java000066400000000000000000000025711326145000000231440ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.crypto; import java.security.Principal; import java.math.BigInteger; /** * Certificates handled by JSS. All certificates handled by JSS are * of this type. */ public interface X509Certificate { /** * Returns the DER encoding of this certificate. */ public byte[] getEncoded() throws java.security.cert.CertificateEncodingException; /** * Returns the possibly-null nickname of this certificate. */ public abstract String getNickname(); /** * Extracts the Public Key from this certificate. */ public abstract java.security.PublicKey getPublicKey(); /** * Returns the RFC 1485 ASCII encoding of the Subject Name. */ public abstract Principal getSubjectDN(); /** * Returns the RFC 1485 ASCII encoding of the issuer's Subject Name. */ public abstract Principal getIssuerDN(); /** * Returns the serial number of this certificate. */ public abstract BigInteger getSerialNumber(); /** * @return the version number of this X.509 certificate. * 0 means v1, 1 means v2, 2 means v3. */ public abstract int getVersion(); } jss-4.4.3/jss/org/mozilla/jss/crypto/config.mk000066400000000000000000000004201326145000000212560ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/crypto/manifest.mn000066400000000000000000000011611326145000000216250ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 REQUIRES = nspr20 nss PACKAGE = org/mozilla/jss/crypto PRIVATE_EXPORTS = \ Algorithm.h \ $(NULL) CSRCS = Algorithm.c \ PQGParams.c \ SecretDecoderRing.c \ $(NULL) LIBRARY_NAME = jsscrypto jss-4.4.3/jss/org/mozilla/jss/crypto/package.html000066400000000000000000000004751326145000000217530ustar00rootroot00000000000000 Generic cryptographic operations, such as signing and key pair generation. jss-4.4.3/jss/org/mozilla/jss/manifest.mn000066400000000000000000000011171326145000000203060ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../.. NS_USE_JDK = 1 MODULE = jss REQUIRES = nspr20 nss DIRS = \ util \ crypto \ SecretDecoderRing \ pkcs11 \ asn1 \ ssl \ provider \ $(NULL) PACKAGE = org/mozilla/jss CSRCS = \ CryptoManager.c \ PK11Finder.c \ $(NULL) LIBRARY_NAME = jssmanage jss-4.4.3/jss/org/mozilla/jss/package.html000066400000000000000000000004541326145000000204300ustar00rootroot00000000000000 Configuration and top-level operations of the JSS system. jss-4.4.3/jss/org/mozilla/jss/pkcs10/000077500000000000000000000000001326145000000172455ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkcs10/CertificationRequest.java000066400000000000000000000260061326145000000242500ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs10; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import java.security.cert.CertificateException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.SignatureException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.security.PublicKey; import java.security.KeyPair; import java.util.Date; import java.util.Calendar; import java.io.BufferedInputStream; import java.io.FileInputStream; /** * A pkcs10 signed CertificationRequest. */ public class CertificationRequest implements ASN1Value { private CertificationRequestInfo info; private byte[] infoEncoding; private byte[] signature; private AlgorithmIdentifier algId; SEQUENCE sequence; private CertificationRequest() { } CertificationRequest(CertificationRequestInfo info, //byte[] infoEncoding, AlgorithmIdentifier algId, byte[] signature) throws IOException { this.info = info; //this.infoEncoding = infoEncoding; this.algId = algId; this.signature = signature; // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Creates and signs an X.509 CertificationRequest. * @param info A CertificationRequestInfo (TBSCertificationRequest), * which specifies * the actual information of the CertificationRequest. * @param privKey The private key with which to sign the certificate. * @param signingAlg The algorithm to use to sign the CertificationRequest. * It must match the algorithm specified in the CertificationRequestInfo. * @exception IOException If an error occurred while encoding the * CertificationRequest. * @exception CryptoManager.NotInitializedException Because this * operation involves cryptography (signing), CryptoManager must * be initialized before calling it. * @exception TokenException If an error occurs on a PKCS #11 token. * @exception NoSuchAlgorithmException If the OID for the signing algorithm * cannot be located. * @exception CertificateException If the signing algorithm specified * as a parameter does not match the one in the CertificationRequest info. * @exception InvalidKeyException If the key does not match the signing * algorithm. * @exception SignatureException If an error occurs while signing the * CertificationRequest. */ public CertificationRequest(CertificationRequestInfo info, java.security.PrivateKey privKey, SignatureAlgorithm signingAlg) throws IOException, CryptoManager.NotInitializedException, TokenException, NoSuchAlgorithmException, CertificateException, InvalidKeyException, SignatureException { // make sure key is a Ninja private key if( !(privKey instanceof PrivateKey) ) { throw new InvalidKeyException("Private Key is does not belong to"+ " this provider"); } PrivateKey priv = (PrivateKey)privKey; // create algId if(signingAlg.getSigningAlg() == SignatureAlgorithm.RSASignature) { algId = new AlgorithmIdentifier( signingAlg.toOID(), null ); } else { algId = new AlgorithmIdentifier( signingAlg.toOID() ); } // encode the cert info this.info = info; infoEncoding = ASN1Util.encode(info); // sign the info encoding CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = priv.getOwningToken(); Signature sig = token.getSignatureContext(signingAlg); sig.initSign(priv); sig.update(infoEncoding); signature = sig.sign(); // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Verifies the signature on this CertificationRequest. Does not indicate * that the CertificationRequest is valid at any specific time. */ public void verify() throws InvalidKeyException, CryptoManager.NotInitializedException, NoSuchAlgorithmException, CertificateException, TokenException, SignatureException, InvalidKeyFormatException { verify( info.getSubjectPublicKeyInfo().toPublicKey() ); } /** * Verifies the signature on this CertificationRequest, using the given public key. * Does not indicate the CertificationRequest is valid at any specific time. */ public void verify(PublicKey key) throws InvalidKeyException, CryptoManager.NotInitializedException, NoSuchAlgorithmException, CertificateException, TokenException, SignatureException { CryptoManager cm = CryptoManager.getInstance(); verify(key, cm.getInternalCryptoToken()); } /** * Verifies the signature on this CertificationRequest, using the given public * key and CryptoToken. Does not indicate the CertificationRequest is valid at * any specific time. */ public void verify(PublicKey key, CryptoToken token) throws NoSuchAlgorithmException, CertificateException, TokenException, SignatureException, InvalidKeyException { Signature sig = token.getSignatureContext( SignatureAlgorithm.fromOID( algId.getOID() ) ); sig.initVerify(key); sig.update(infoEncoding); if( ! sig.verify(signature) ) { throw new CertificateException("Signature is invalid"); } } /** * Returns the information (TBSCertificationRequest) contained in this CertificationRequest. */ public CertificationRequestInfo getInfo() { return info; } private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( CertificationRequestInfo.getTemplate() ); //seqt.addElement( new ANY.Template() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); //ANY infoAny = (ANY)seq.elementAt(0); //byte[] infoEncoding = infoAny.getEncoded(); /*CertificationRequestInfo info = (CertificationRequestInfo) infoAny.decodeWith( CertificationRequestInfo.getTemplate() ); */ CertificationRequestInfo info = (CertificationRequestInfo) seq.elementAt(0); // although signature is a bit string, all algorithms we use // will produce an octet string. BIT_STRING bs = (BIT_STRING) seq.elementAt(2); if( bs.getPadCount() != 0 ) { throw new InvalidBERException("signature does not fall into"+ " an integral number of bytes"); } byte[] signature = bs.getBits(); return new CertificationRequest( info, //infoEncoding, (AlgorithmIdentifier) seq.elementAt(1), signature ); } } public static void main(String argv[]) { try { if(argv.length > 2 || argv.length < 1) { System.out.println("Usage: CertificationRequest []"); System.exit(0); } CryptoManager.initialize( argv[0] ); CryptoManager cm = CryptoManager.getInstance(); // read in a cert BufferedInputStream bis = new BufferedInputStream( new FileInputStream(argv[1]) ); CertificationRequest cert = (CertificationRequest) CertificationRequest.getTemplate().decode(bis); CertificationRequestInfo info = cert.getInfo(); info.print(System.out); //X509CertificationRequest hardcore = cm.findCertByNickname("Hardcore"); //PublicKey key = hardcore.getPublicKey(); cert.verify(); System.out.println("verified"); FileOutputStream fos = new FileOutputStream("certinfo.der"); info.encode(fos); fos.close(); // make a new public key CryptoToken token = cm.getInternalKeyStorageToken(); KeyPairGenerator kpg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpg.initialize(512); System.out.println("Generating a new key pair..."); KeyPair kp = kpg.genKeyPair(); System.out.println("Generated key pair"); // set the CertificationRequest's public key info.setSubjectPublicKeyInfo(kp.getPublic()); // make new Name Name name = new Name(); name.addCommonName("asldkj"); name.addCountryName("US"); name.addOrganizationName("Some Corp"); name.addOrganizationalUnitName("Some Org Unit"); name.addLocalityName("Silicon Valley"); name.addStateOrProvinceName("California"); info.setSubject(name); System.out.println("About to create a new cert request..."); // create a new cert requestfrom this certReqinfo CertificationRequest genCert = new CertificationRequest(info, kp.getPrivate(), SignatureAlgorithm.RSASignatureWithMD5Digest); System.out.println("Created new cert request"); genCert.verify(); System.out.println("Cert verifies!"); fos = new FileOutputStream("gencert.der"); genCert.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs10/CertificationRequestInfo.java000066400000000000000000000122441326145000000250630ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs10; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.*; import java.security.cert.CertificateException; import java.security.PublicKey; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import java.io.InputStream; import java.io.PrintStream; import java.io.OutputStream; import java.io.IOException; /** * A TBSCertificationRequest (to-be-signed CertificationRequest), * the actual information in * a CertificationRequest apart from the signature. */ public class CertificationRequestInfo implements ASN1Value { private INTEGER version = new INTEGER(0); private Name subject; private SubjectPublicKeyInfo subjectPublicKeyInfo; private SET attributes; /** * Creates a CertificationRequestInfo with the required fields. */ public CertificationRequestInfo(INTEGER version, Name subject, SubjectPublicKeyInfo subjectPublicKeyInfo, SET attributes) { setVersion(version); setSubject(subject); setSubjectPublicKeyInfo(subjectPublicKeyInfo); setAttributes(attributes); } public void setVersion(INTEGER version) { verifyNotNull(version); this.version = version; } public INTEGER getVersion() { return version; } public void setSubject(Name subject) { verifyNotNull(subject); this.subject = subject; } public Name getSubject() { return subject; } public void setSubjectPublicKeyInfo( SubjectPublicKeyInfo subjectPublicKeyInfo) { verifyNotNull(subjectPublicKeyInfo); this.subjectPublicKeyInfo = subjectPublicKeyInfo; } /** * Extracts the SubjectPublicKeyInfo from the given public key and * stores it in the CertificationRequestInfo. * * @exception InvalidBERException If an error occurs decoding the * the information extracted from the public key. */ public void setSubjectPublicKeyInfo( PublicKey pubk ) throws InvalidBERException, IOException { verifyNotNull(pubk); setSubjectPublicKeyInfo( new SubjectPublicKeyInfo(pubk) ); } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } public void setAttributes(SET attributes) { //verifyNotNull(attributes); this.attributes = attributes; } public SET getAttributes() { return attributes; } private void verifyNotNull(Object obj) { if( obj == null ) { throw new NullPointerException(); } } static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(version ); seq.addElement(subject); seq.addElement(subjectPublicKeyInfo); seq.addElement(new Tag(0), attributes); seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public void print(PrintStream ps) throws IOException, InvalidBERException { ps.println("CertificationRequestInfo:"); ps.println("Version: "+version); ps.println("Subject: "+subject.getRFC1485()); } /** * Template class for decoding a CertificationRequestInfo. */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); //version seqt.addElement(Name.getTemplate()); //subject seqt.addElement(SubjectPublicKeyInfo.getTemplate()); seqt.addElement(Tag.get(0), new SET.OF_Template(Attribute.getTemplate())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); CertificationRequestInfo cinfo = new CertificationRequestInfo( (INTEGER) seq.elementAt(0), // version (Name) seq.elementAt(1), // subject (SubjectPublicKeyInfo) seq.elementAt(2), (SET) seq.elementAt(3) ); return cinfo; } catch( Exception e ) { throw new InvalidBERException(e.getMessage()); } } } } jss-4.4.3/jss/org/mozilla/jss/pkcs10/Makefile000066400000000000000000000035731326145000000207150ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### #include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### #include rules.mk jss-4.4.3/jss/org/mozilla/jss/pkcs10/manifest.mn000066400000000000000000000017641326145000000214170ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 PACKAGE = org/mozilla/jss/pkcs10 # These are meant to be used within Ninja only. PRIVATE_EXPORTS = \ $(NULL) JNI_GEN = \ $(NULL) CLASSES = \ CertificationRequest \ CertificationRequestInfo \ $(NULL) PRIVATE_CLASSES = \ $(NULL) JSRCS = \ CertificationRequest.java \ CertificationRequestInfo.java \ $(NULL) PRIVATE_JSRCS = CSRCS = \ $(NULL) jss-4.4.3/jss/org/mozilla/jss/pkcs10/package.html000066400000000000000000000004271326145000000215310ustar00rootroot00000000000000 Encoding and decoding pkcs10 request jss-4.4.3/jss/org/mozilla/jss/pkcs11/000077500000000000000000000000001326145000000172465ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkcs11/CipherContextProxy.java000066400000000000000000000010431326145000000237300ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.util.NativeProxy; final class CipherContextProxy extends NativeProxy { public CipherContextProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/KeyProxy.java000066400000000000000000000007151326145000000217060ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; abstract class KeyProxy extends org.mozilla.jss.util.NativeProxy { protected KeyProxy(byte[] pointer) { super(pointer); } protected void finalize() throws Throwable { super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/KeyType.java000066400000000000000000000212631326145000000215070ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.HMACAlgorithm; import java.util.Hashtable; import org.mozilla.jss.util.*; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.EncryptionAlgorithm; /** * PKCS #11 Key Types * These are the possible types for keys in the * wrapper library. * Key types are implemented as flyweights. * * Although the KeyType class is public, it should * be considered private. We made the KeyType class * public so that we can force it to load during * CryptoManager.initialize(), before we install JSS * as a provider. **/ public final class KeyType { protected KeyType() {} protected KeyType(Algorithm[] algs, String name) { int i; Assert._assert(algs!=null); algorithms = (Algorithm[]) algs.clone(); // Register this key as the key type for each of its algorithms for(i=0; i < algorithms.length; i++) { Assert._assert(! algHash.containsKey(algorithms[i]) ); algHash.put(algorithms[i], this); } this.name = name; } /** * Returns an array of algorithms supported by this key type. */ public Algorithm[] supportedAlgorithms() { return algorithms; } /** * Returns the KeyType corresponding to the given Algorithm. If there * is no KeyType registered for this algorithm, a NoSuchAlgorithmException * is thrown. */ static public KeyType getKeyTypeFromAlgorithm(Algorithm alg) throws NoSuchAlgorithmException { Assert._assert(alg!=null); Object obj = algHash.get(alg); if(obj == null) { throw new NoSuchAlgorithmException(); } Assert._assert( obj instanceof KeyType ); return (KeyType) obj; } public String toString() { return name; } ////////////////////////////////////////////////////////////// // Instance Data ////////////////////////////////////////////////////////////// // An array of algorithms supported by this key type protected Algorithm[] algorithms; protected String name; ////////////////////////////////////////////////////////////// // Class Data ////////////////////////////////////////////////////////////// // A hash table associating a key type with each algorithm static protected Hashtable algHash; static { algHash = new Hashtable(); } ////////////////////////////////////////////////////////////// // Key Types ////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////// static public final KeyType NULL = new KeyType(new Algorithm[0], "NULL"); ////////////////////////////////////////////////////////////// static public final KeyType RSA = new KeyType (new Algorithm[] { SignatureAlgorithm.RSASignature, SignatureAlgorithm.RSASignatureWithMD2Digest, SignatureAlgorithm.RSASignatureWithMD5Digest, SignatureAlgorithm.RSASignatureWithSHA1Digest, SignatureAlgorithm.RSASignatureWithSHA256Digest, SignatureAlgorithm.RSASignatureWithSHA384Digest, SignatureAlgorithm.RSASignatureWithSHA512Digest, KeyWrapAlgorithm.RSA }, "RSA" ); ////////////////////////////////////////////////////////////// static public final KeyType DSA = new KeyType(new Algorithm[] { SignatureAlgorithm.DSASignature, SignatureAlgorithm.DSASignatureWithSHA1Digest }, "DSA" ); ////////////////////////////////////////////////////////////// static public final KeyType EC = new KeyType(new Algorithm[] { SignatureAlgorithm.ECSignature, SignatureAlgorithm.ECSignatureWithSHA1Digest, SignatureAlgorithm.ECSignatureWithSHA256Digest, SignatureAlgorithm.ECSignatureWithSHA384Digest, SignatureAlgorithm.ECSignatureWithSHA512Digest }, "EC" ); ////////////////////////////////////////////////////////////// /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * This is just a placeholder for backward compatibility. */ static public final KeyType FORTEZZA = new KeyType(new Algorithm[0], "FORTEZZA"); ////////////////////////////////////////////////////////////// static public final KeyType DH = new KeyType(new Algorithm[0], "DH"); ////////////////////////////////////////////////////////////// static public final KeyType KEA = new KeyType(new Algorithm[0], "KEA"); ////////////////////////////////////////////////////////////// static public final KeyType DES = new KeyType(new Algorithm[] { KeyWrapAlgorithm.DES_ECB, KeyWrapAlgorithm.DES_CBC, KeyWrapAlgorithm.DES_CBC_PAD, EncryptionAlgorithm.DES_ECB, EncryptionAlgorithm.DES_CBC, EncryptionAlgorithm.DES_CBC_PAD }, "DES" ); ////////////////////////////////////////////////////////////// static public final KeyType DES3 = new KeyType(new Algorithm[] { KeyWrapAlgorithm.DES3_ECB, KeyWrapAlgorithm.DES3_CBC, KeyWrapAlgorithm.DES3_CBC_PAD, EncryptionAlgorithm.DES3_ECB, EncryptionAlgorithm.DES3_CBC, EncryptionAlgorithm.DES3_CBC_PAD }, "DESede" ); ////////////////////////////////////////////////////////////// static public final KeyType AES = new KeyType(new Algorithm[] { KeyWrapAlgorithm.AES_ECB, KeyWrapAlgorithm.AES_CBC, KeyWrapAlgorithm.AES_CBC_PAD, KeyWrapAlgorithm.AES_KEY_WRAP, KeyWrapAlgorithm.AES_KEY_WRAP_PAD, EncryptionAlgorithm.AES_128_ECB, EncryptionAlgorithm.AES_128_CBC, EncryptionAlgorithm.AES_192_ECB, EncryptionAlgorithm.AES_192_CBC, EncryptionAlgorithm.AES_256_ECB, EncryptionAlgorithm.AES_256_CBC, EncryptionAlgorithm.AES_CBC_PAD, EncryptionAlgorithm.AES_128_CBC_PAD, EncryptionAlgorithm.AES_192_CBC_PAD, EncryptionAlgorithm.AES_256_CBC_PAD }, "AES" ); ////////////////////////////////////////////////////////////// static public final KeyType RC4 = new KeyType(new Algorithm[] { EncryptionAlgorithm.RC4 }, "RC4" ); ////////////////////////////////////////////////////////////// static public final KeyType RC2 = new KeyType(new Algorithm[] { EncryptionAlgorithm.RC2_CBC, EncryptionAlgorithm.RC2_CBC_PAD }, "RC2" ); ////////////////////////////////////////////////////////////// static public final KeyType SHA1_HMAC = new KeyType(new Algorithm[] { HMACAlgorithm.SHA1 }, "SHA1_HMAC" ); static public final KeyType GENERIC_SECRET = new KeyType(new Algorithm[] { }, "GENERIC_SECRET"); } jss-4.4.3/jss/org/mozilla/jss/pkcs11/Makefile000066400000000000000000000035521326145000000207130ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/pkcs11/ModuleProxy.java000066400000000000000000000010061326145000000223750ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.util.*; final class ModuleProxy extends NativeProxy { ModuleProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Cert.c000066400000000000000000000455371326145000000207220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_CertProxy.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include /* * Class: org_mozilla_jss_pkcs11_PK11Cert * Method: getEncoded * Signature: ()[B */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getEncoded (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; CERTCertificate *cert; SECItem *derCert; jbyteArray derArray=NULL; jbyte *pByte; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); PR_ASSERT(env!=NULL && this!=NULL); /* * extract the DER cert from the CERTCertificate* */ if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(cert != NULL); derCert = &cert->derCert; /* the SECItem type does not have to be siDERCertBuffer */ if(derCert->data==NULL || derCert->len<1) { JSS_throw(env, CERTIFICATE_ENCODING_EXCEPTION); goto finish; } /* * Copy the DER data to a new Java byte array */ derArray = (*env)->NewByteArray(env, derCert->len); if(derArray==NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } pByte = (*env)->GetByteArrayElements(env, derArray, NULL); if(pByte==NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } memcpy(pByte, derCert->data, derCert->len); (*env)->ReleaseByteArrayElements(env, derArray, pByte, 0); finish: PR_DetachThread(); return derArray; } /* * Class: org_mozilla_jss_pkcs11_PK11Cert * Method: getVersion * Signature: ()I */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getVersion (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; CERTCertificate *cert; long lVersion = 0; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); PR_ASSERT(env!=NULL && this!=NULL); /* * Get the version from the CERTCertificate * */ if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(cert!=NULL); if(cert->version.data==NULL || cert->version.len<=0) { /* default value is 0 */ lVersion = 0; goto finish; } lVersion = DER_GetInteger(&cert->version); /* jint is 2s complement 32 bits. The max value is 0111...111. */ PR_ASSERT( (lVersion >= 0L) && (lVersion < (long)0x7fffffff) ); finish: PR_DetachThread(); return (jint) lVersion; } /****************************************************************** * * C e r t P r o x y . g e t P u b l i c K e y * * Extracts the SECKEYPublicKey from the CERTCertificate, wraps it * in a Java wrapper, and returns it. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getPublicKey (JNIEnv *env, jobject this) { CERTCertificate *cert; SECKEYPublicKey *pubk=NULL; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; jobject pubKey=NULL; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } pubk = CERT_ExtractPublicKey(cert); if(pubk==NULL) { PR_ASSERT( PR_GetError() == SEC_ERROR_NO_MEMORY); JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } pubKey = JSS_PK11_wrapPubKey(env, &pubk); if(pubKey == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } finish: if(pubk!=NULL) { SECKEY_DestroyPublicKey(pubk); } PR_DetachThread(); return pubKey; } /****************************************************************** * * C e r t P r o x y . r e l e a s e N a t i v e R e s o u r c e s * * Calls CERT_DestroyCertificate on the underlying CERTCertificate. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_CertProxy_releaseNativeResources (JNIEnv *env, jobject this) { CERTCertificate *cert; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); /* Get the CERTCertificate structure */ if(JSS_getPtrFromProxy(env, this, (void**)&cert) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } PR_ASSERT(cert != NULL); CERT_DestroyCertificate(cert); finish: PR_DetachThread(); } /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t P t r * * Given a Certificate object, extracts the CERTCertificate* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a CERTCertificate* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertPtr(JNIEnv *env, jobject certObject, CERTCertificate **ptr) { PR_ASSERT(env!=NULL && certObject!=NULL && ptr!=NULL); /* Get the pointer from the cert proxy */ return JSS_getPtrFromProxyOwner(env, certObject, CERT_PROXY_FIELD, CERT_PROXY_SIG, (void**)ptr); } /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t S l o t P t r * * Given a Certificate object, extracts the PK11SlotInfo* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a PK11SlotInfo* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertSlotPtr(JNIEnv *env, jobject certObject, PK11SlotInfo **ptr) { PR_ASSERT(env!=NULL && certObject!=NULL && ptr!=NULL); /* Get the pointer from the token proxy */ return JSS_getPtrFromProxyOwner(env, certObject, PK11TOKEN_PROXY_FIELD, PK11TOKEN_PROXY_SIG, (void**)ptr); } /* * This is a shady way of deciding if the cert is a user cert. * Hopefully it will work. What we used to do was check for cert->slot. */ #define isUserCert(cert) \ ( ((cert)->trust->sslFlags & CERTDB_USER) || \ ((cert)->trust->emailFlags & CERTDB_USER) || \ ((cert)->trust->objectSigningFlags & CERTDB_USER) ) /**************************************************************** * * f i n d S l o t B y T o k e n N a m e A n d C e r t * * Find the slot containing the token with the given name * and cert. */ static PK11SlotInfo * findSlotByTokenNameAndCert(char *name, CERTCertificate *cert) { PK11SlotList *list; PK11SlotListElement *le; PK11SlotInfo *slot = NULL; list = PK11_GetAllTokens(CKM_INVALID_MECHANISM, PR_FALSE, PR_FALSE, NULL); if(list == NULL) { return NULL; } for(le = list->head; le; le = le->next) { if( (PORT_Strcmp(PK11_GetTokenName(le->slot),name) == 0) && (PK11_FindCertInSlot(le->slot,cert,NULL) != CK_INVALID_HANDLE)) { slot = PK11_ReferenceSlot(le->slot); break; } } PK11_FreeSlotList(list); if(slot == NULL) { PORT_SetError(SEC_ERROR_NO_TOKEN); } return slot; } /************************************************************************* * * J S S _ P K 1 1 _ f i n d C e r t A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertificate * JSS_PK11_findCertAndSlotFromNickname(char *nickname, void *wincx, PK11SlotInfo **ppSlot) { CERTCertificate *cert; cert = PK11_FindCertFromNickname(nickname, wincx); if(cert == NULL) { return NULL; } if( PORT_Strchr(nickname, ':')) { char* tokenname = PORT_Strdup(nickname); char* colon = PORT_Strchr(tokenname, ':'); *colon = '\0'; *ppSlot = findSlotByTokenNameAndCert(tokenname, cert); PORT_Free(tokenname); if(*ppSlot == NULL) { /* The token containing the cert was just removed. */ CERT_DestroyCertificate(cert); return NULL; } } else { *ppSlot = PK11_GetInternalKeySlot(); } return cert; } /*************************************************************************** * * J S S _ P K 1 1 _ f i n d C e r t s A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertsFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertList * JSS_PK11_findCertsAndSlotFromNickname(char *nickname, void *wincx, PK11SlotInfo **ppSlot) { CERTCertList *certList; certList = PK11_FindCertsFromNickname(nickname, wincx); if(certList == NULL) { return NULL; } if( PORT_Strchr(nickname, ':')) { char* tokenname = PORT_Strdup(nickname); char* colon = PORT_Strchr(tokenname, ':'); CERTCertListNode *head = CERT_LIST_HEAD(certList); *colon = '\0'; *ppSlot = findSlotByTokenNameAndCert(tokenname, head->cert); PORT_Free(tokenname); if(*ppSlot == NULL) { /* The token containing the certs was just removed. */ CERT_DestroyCertList(certList); return NULL; } } else { *ppSlot = PK11_GetInternalKeySlot(); } return certList; } /*********************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t A n d N i c k n a m e * * Builds a Certificate wrapper around a CERTCertificate, a * PK11SlotInfo, and a nickname. * cert: Will be eaten and erased whether the wrap was successful or not. * slot: Will be eaten and erased whether the wrap was successful or not. * nickname: the cert instance's nickname * returns: a new PK11Cert wrapping the CERTCertificate, PK11SlotInfo, * and nickname, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlotAndNickname(JNIEnv *env, CERTCertificate **cert, PK11SlotInfo **slot, const char *nickname) { jclass certClass; jmethodID constructor; jbyteArray certPtr; jbyteArray slotPtr; jstring jnickname = NULL; jobject Cert=NULL; PR_ASSERT(env!=NULL && cert!=NULL && *cert!=NULL && slot!=NULL); certPtr = JSS_ptrToByteArray(env, *cert); slotPtr = JSS_ptrToByteArray(env, *slot); if (nickname) { jnickname = (*env)->NewStringUTF(env, nickname); } certClass = (*env)->FindClass(env, INTERNAL_TOKEN_CERT_CLASS_NAME); if(certClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, certClass, PLAIN_CONSTRUCTOR, CERT_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* Call the constructor */ Cert = (*env)->NewObject(env, certClass, constructor, certPtr, slotPtr, jnickname); if(Cert==NULL) { goto finish; } finish: if(Cert==NULL) { CERT_DestroyCertificate(*cert); if(*slot!=NULL) { PK11_FreeSlot(*slot); } } *cert = NULL; *slot = NULL; return Cert; } /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t * * Builds a Certificate wrapper around a CERTCertificate and a * PK11SlotInfo. * cert: Will be eaten and erased whether the wrap was successful or not. * slot: Will be eaten and erased whether the wrap was successful or not. * returns: a new PK11Cert wrapping the CERTCertificate and PK11SlotInfo, * or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlot(JNIEnv *env, CERTCertificate **cert, PK11SlotInfo **slot) { return JSS_PK11_wrapCertAndSlotAndNickname(env, cert, slot, (*cert)->nickname); } /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t * * Builds a Certificate wrapper around a CERTCertificate. * cert: Will be eaten and erased whether the wrap was successful or not. * returns: a new PK11Cert wrapping the CERTCertificate, or NULL if an * exception was thrown. * * Use JSS_PK11_wrapCertAndSlot instead if it is important for the PK11Cert * object to have the correct slot pointer or the slot pointer is readily * available. */ jobject JSS_PK11_wrapCert(JNIEnv *env, CERTCertificate **cert) { PK11SlotInfo *slot = (*cert)->slot; if(slot != NULL) { slot = PK11_ReferenceSlot(slot); } return JSS_PK11_wrapCertAndSlot(env, cert, &slot); } /********************************************************************** * PK11Cert.getOwningToken */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getOwningToken (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jobject token = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* get the C PK11SlotInfo structure */ if( JSS_PK11_getCertSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); /* wrap the slot in a Java PK11Token */ token = JSS_PK11_wrapPK11Token(env, &slot); if(token == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: return token; } /* * workaround for bug 100791: misspelled function prototypes in pk11func.h */ SECItem* PK11_GetLowLevelKeyIDForCert(PK11SlotInfo*,CERTCertificate*,void*); /********************************************************************** * PK11Cert.getUniqueID */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getUniqueID (JNIEnv *env, jobject this) { CERTCertificate *cert; SECItem *id = NULL; jbyteArray byteArray=NULL; PR_ASSERT(env!=NULL && this!=NULL); /************************************************** * Get the CERTCertificate structure **************************************************/ if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { goto finish; } /*************************************************** * Get the id ***************************************************/ id = PK11_GetLowLevelKeyIDForCert(NULL /*slot*/, cert, NULL/*pinarg*/); if( id == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } /*************************************************** * Write the id to a new byte array ***************************************************/ byteArray = (*env)->NewByteArray(env, id->len); if(byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, byteArray, 0, id->len, (jbyte*)id->data); if( (*env)->ExceptionOccurred(env) != NULL) { PR_ASSERT(PR_FALSE); goto finish; } finish: if( id != NULL ) { SECITEM_FreeItem(id, PR_TRUE /*freeit*/); } return byteArray; } /********************************************************************** * This is what used to be PK11Cert.getNickname. Kept merely to * satisfy the symbol export file jss.def. */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getNickname (JNIEnv *env, jobject this) { PR_NOT_REACHED("a stub function"); return NULL; } /********************************************************************** * PK11Cert.setTrust */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_setTrust (JNIEnv *env, jobject this, jint type, jint newTrust) { CERTCertificate *cert; CERTCertTrust trust; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return; } if( CERT_GetCertTrust( cert, &trust ) != SECSuccess) { /* cert doesn't have any trust yet, so initialize to 0 */ memset(&trust, 0, sizeof(trust)); } switch(type) { case 0: /* SSL */ trust.sslFlags = newTrust; break; case 1: /* email */ trust.emailFlags = newTrust; break; case 2: /* object signing */ trust.objectSigningFlags = newTrust; break; default: PR_ASSERT(PR_FALSE); return; } if( CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust) != SECSuccess) { PR_ASSERT(PR_FALSE); return; } return; } /********************************************************************** * PK11Cert.getTrust */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getTrust (JNIEnv *env, jobject this, jint type) { CERTCertificate *cert; CERTCertTrust trust; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return 0; } if( CERT_GetCertTrust( cert, &trust ) != SECSuccess) { PR_ASSERT(PR_FALSE); return 0; } switch(type) { case 0: /* SSL */ return trust.sslFlags; case 1: /* email */ return trust.emailFlags; case 2: /* object signing */ return trust.objectSigningFlags; default: PR_ASSERT(PR_FALSE); return 0; } } /********************************************************************** * PK11Cert.getSerialNumberByteArray */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getSerialNumberByteArray (JNIEnv *env, jobject this) { CERTCertificate *cert; if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return NULL; } PR_ASSERT(cert->serialNumber.len > 0); PR_ASSERT(cert->serialNumber.data != NULL); return JSS_OctetStringToByteArray(env, &cert->serialNumber); } /********************************************************************** * PK11Cert.getSubjectDNString */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getSubjectDNString (JNIEnv *env, jobject this) { CERTCertificate *cert; char *ascii; if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return NULL; } ascii = CERT_NameToAscii(&cert->subject); if( ascii ) { return (*env)->NewStringUTF(env, ascii); } else { return NULL; } } /********************************************************************** * PK11Cert.getIssuerDNString */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Cert_getIssuerDNString (JNIEnv *env, jobject this) { CERTCertificate *cert; char *ascii; if( JSS_PK11_getCertPtr(env, this, &cert) != PR_SUCCESS) { return NULL; } ascii = CERT_NameToAscii(&cert->issuer); if( ascii ) { return (*env)->NewStringUTF(env, ascii); } else { return NULL; } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Cert.java000066400000000000000000000077431326145000000214160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import java.security.*; import java.security.cert.*; import java.util.*; import java.math.BigInteger; public class PK11Cert implements org.mozilla.jss.crypto.X509Certificate { public native byte[] getEncoded() throws CertificateEncodingException; //public native byte[] getUniqueID(); public String getNickname() { return nickname; } /** * A class that implements Principal with a String. */ protected static class StringPrincipal implements Principal { public StringPrincipal(String str) { this.str = str; } public boolean equals(Object other) { if( ! (other instanceof StringPrincipal) ) { return false; } return getName().equals( ((StringPrincipal)other).getName() ); } public String getName() { return str; } public int hashCode() { return str.hashCode(); } public String toString() { return str; } protected String str; } public Principal getSubjectDN() { return new StringPrincipal( getSubjectDNString() ); } public Principal getIssuerDN() { return new StringPrincipal( getIssuerDNString() ); } public BigInteger getSerialNumber() { return new BigInteger( getSerialNumberByteArray() ); } protected native byte[] getSerialNumberByteArray(); protected native String getSubjectDNString(); protected native String getIssuerDNString(); public native java.security.PublicKey getPublicKey(); public native int getVersion(); /////////////////////////////////////////////////////////////////////// // PKCS #11 Cert stuff. Must only be called on certs that have // an associated slot. /////////////////////////////////////////////////////////////////////// protected native byte[] getUniqueID(); protected native CryptoToken getOwningToken(); /////////////////////////////////////////////////////////////////////// // Trust Management. Must only be called on certs that live in the // internal database. /////////////////////////////////////////////////////////////////////// /** * Sets the trust flags for this cert. * * @param type SSL, EMAIL, or OBJECT_SIGNING. * @param trust The trust flags for this type of trust. */ protected native void setTrust(int type, int trust); /** * Gets the trust flags for this cert. * * @param type SSL, EMAIL, or OBJECT_SIGNING. * @return The trust flags for this type of trust. */ protected native int getTrust(int type); ///////////////////////////////////////////////////////////// // Construction ///////////////////////////////////////////////////////////// //PK11Cert(CertProxy proxy) { // Assert._assert(proxy!=null); // this.certProxy = proxy; //} PK11Cert(byte[] certPtr, byte[] slotPtr, String nickname) { Assert._assert(certPtr!=null); Assert._assert(slotPtr!=null); certProxy = new CertProxy(certPtr); tokenProxy = new TokenProxy(slotPtr); this.nickname = nickname; } ///////////////////////////////////////////////////////////// // private data ///////////////////////////////////////////////////////////// protected CertProxy certProxy; protected TokenProxy tokenProxy; protected String nickname; } class CertProxy extends org.mozilla.jss.util.NativeProxy { public CertProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { Debug.trace(Debug.OBNOXIOUS, "finalizing a certificate"); super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Cipher.c000066400000000000000000000223061326145000000212240ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Cipher.h" #include #include #include #include #include /* JSS includes */ #include #include #include #include #include /*********************************************************************** * * PK11Cipher.initContext */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_initContext (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj, jobject algObj, jbyteArray ivBA, jboolean padded) { return Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits ( env, clazz, encrypt, keyObj, algObj, ivBA, 0, padded); } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_initContextWithKeyBits (JNIEnv *env, jclass clazz, jboolean encrypt, jobject keyObj, jobject algObj, jbyteArray ivBA, jint keyBits, jboolean padded) { CK_MECHANISM_TYPE mech; PK11SymKey *key=NULL; SECItem *param=NULL; SECItem *iv=NULL; PK11Context *context=NULL; CK_ATTRIBUTE_TYPE op; jobject contextObj = NULL; PR_ASSERT(env!=NULL && clazz!=NULL && keyObj!=NULL && algObj!=NULL); /* get mechanism */ mech = JSS_getPK11MechFromAlg(env, algObj); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to resolve algorithm to" " PKCS #11 mechanism"); goto finish; } if (padded) mech = PK11_GetPadMechanism(mech); /* get operation type */ if( encrypt ) { op = CKA_ENCRYPT; } else { op = CKA_DECRYPT; } /* get key */ if( JSS_PK11_getSymKeyPtr(env, keyObj, &key) != PR_SUCCESS) { goto finish; } /* get param, if there is one */ if( ivBA != NULL ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { /* exception was thrown */ goto finish; } } param = PK11_ParamFromIV(mech, iv); /* * Set RC2 effective key length. */ if( mech == CKM_RC2_CBC || mech == CKM_RC2_CBC_PAD ) { ((CK_RC2_CBC_PARAMS*)param->data)->ulEffectiveBits = keyBits; } /* create crypto context */ context = PK11_CreateContextBySymKey(mech, op, key, param); if(context == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to generate crypto context"); goto finish; } /* wrap crypto context. This sets context to NULL. */ contextObj = JSS_PK11_wrapCipherContextProxy(env, &context); finish: if( param != NULL ) { SECITEM_FreeItem(param, PR_TRUE /*freeit*/); } if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*freeit*/); } if(context != NULL) { /* if the function succeeded, context would be NULL */ PK11_DestroyContext(context, PR_TRUE /*freeit*/); } PR_ASSERT( contextObj || (*env)->ExceptionOccurred(env) ); return contextObj; } /*********************************************************************** * * PK11Cipher.updateContext */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_updateContext (JNIEnv *env, jclass clazz, jobject contextObj, jbyteArray inputBA, jint blockSize) { PK11Context *context=NULL; jbyte *inbuf=NULL; unsigned int inlen; unsigned char *outbuf=NULL; unsigned int outlen; jbyteArray outArray=NULL; PR_ASSERT(env!=NULL && clazz!=NULL && contextObj!=NULL && inputBA!=NULL); /* get the context */ if( JSS_PK11_getCipherContext(env, contextObj, &context) != PR_SUCCESS) { goto finish; } /* extract input from byte array */ inlen = (*env)->GetArrayLength(env, inputBA); PR_ASSERT(inlen >= 0); inbuf = (*env)->GetByteArrayElements(env, inputBA, NULL); if(inbuf == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* create output buffer */ outlen = inlen + blockSize; /* this will hold the output */ outbuf = PR_Malloc(outlen); if(outbuf == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* do the operation */ if( PK11_CipherOp(context, outbuf, (int*)&outlen, outlen, (unsigned char*)inbuf, inlen) != SECSuccess) { JSS_throwMsgPrErrArg( env, TOKEN_EXCEPTION, "Cipher context update failed", PR_GetError()); goto finish; } PR_ASSERT(outlen >= 0); /* convert output buffer to byte array */ outArray = (*env)->NewByteArray(env, outlen); if(outArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, outArray, 0, outlen, (jbyte*)outbuf); finish: if(inbuf) { (*env)->ReleaseByteArrayElements(env, inputBA, inbuf, JNI_ABORT); } if(outbuf) { PR_Free(outbuf); } return outArray; } /*********************************************************************** * * PK11Cipher.finalizeContext * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Cipher_finalizeContext (JNIEnv *env, jclass clazz, jobject contextObj, jint blockSize, jboolean padded) { PK11Context *context=NULL; unsigned char *outBuf = NULL; unsigned int outLen, newOutLen; jobject outBA=NULL; SECStatus status; PR_ASSERT(env!=NULL && contextObj!=NULL); /* get context */ if( JSS_PK11_getCipherContext(env, contextObj, &context) != PR_SUCCESS) { goto finish; } /* create output buffer */ outLen = blockSize; /* maximum amount needed */ outBuf = PR_Malloc(outLen); if(outBuf == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* perform the finalization */ status = PK11_DigestFinal(context, outBuf, &newOutLen, outLen); if( (status != SECSuccess) ) { JSS_throwMsgPrErrArg( env, TOKEN_EXCEPTION, "Cipher context finalization failed", PR_GetError()); goto finish; } /* convert output buffer to byte array */ PR_ASSERT(newOutLen >= 0); outBA = (*env)->NewByteArray(env, newOutLen); if(outBA == NULL) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, outBA, 0, newOutLen, (jbyte*)outBuf); finish: if(outBuf) { PR_Free(outBuf); } PR_ASSERT( outBA || (*env)->ExceptionOccurred(env) ); return outBA; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t C i p h e r C o n t e x t * * Extracts the PK11Context from a CipherContextProxy. * * proxy * A CipherContextProxy. * * pContext * Address of a PK11Context*, which will be filled with the pointer * extracted from the CipherContextProxy. * * RETURNS * PR_SUCCESS for success, or PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCipherContext(JNIEnv *env, jobject proxy, PK11Context **pContext) { PR_ASSERT(env!=NULL && proxy!=NULL && pContext!=NULL); return JSS_getPtrFromProxy(env, proxy, (void**)pContext); } /*********************************************************************** * * J S S _ P K 1 1 _ m a k e C i p h e r C o n t e x t P r o x y * * Wraps a PK11Context in a CipherContextProxy. * * context * address of a pointer to a PK11Context, which must not be NULL. * It will be eaten by the wrapper and set to NULL, even if the * function returns NULL. * * RETURNS * A new CipherContextProxy, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCipherContextProxy(JNIEnv *env, PK11Context **context) { jbyteArray pointer=NULL; jclass proxyClass; jmethodID constructor; jobject contextObj=NULL; PR_ASSERT( env!=NULL && context!=NULL && *context!=NULL ); /* convert pointer to byte array */ pointer = JSS_ptrToByteArray(env, *context); /* * Lookup the class and constructor */ proxyClass = (*env)->FindClass(env, CIPHER_CONTEXT_PROXY_CLASS_NAME); if(proxyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID(env, proxyClass, PLAIN_CONSTRUCTOR, CIPHER_CONTEXT_PROXY_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* call the constructor */ contextObj = (*env)->NewObject(env, proxyClass, constructor, pointer); finish: if(contextObj == NULL) { /* didn't work, so free resources */ PK11_DestroyContext( (PK11Context*)*context, PR_TRUE /*freeit*/ ); } *context=NULL; PR_ASSERT( contextObj || (*env)->ExceptionOccurred(env) ); return contextObj; } /*********************************************************************** * * CipherContextProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_CipherContextProxy_releaseNativeResources (JNIEnv *env, jobject this) { PK11Context *context; if( JSS_PK11_getCipherContext(env, this, &context) == PR_SUCCESS ) { PK11_DestroyContext(context, PR_TRUE /*freeit*/); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Cipher.java000066400000000000000000000204301326145000000217170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.NativeProxy; import java.security.InvalidKeyException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.util.Assert; import java.security.NoSuchAlgorithmException; import javax.crypto.spec.*; final class PK11Cipher extends org.mozilla.jss.crypto.Cipher { // set once in the constructor private PK11Token token; // set once in the constructor private EncryptionAlgorithm algorithm; // set with initXXX() private AlgorithmParameterSpec parameters=null; // set with initXXX() private SymmetricKey key=null; // set with initXXX() private byte[] IV=null; // set with initXXX() private CipherContextProxy contextProxy = null; // modified by various operations private int state=UNINITIALIZED; // States private static final int UNINITIALIZED=0; private static final int ENCRYPT=1; private static final int DECRYPT=2; private PK11Cipher() { } PK11Cipher(PK11Token token, EncryptionAlgorithm algorithm) { this.token = token; this.algorithm = algorithm; } public void initEncrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { initEncrypt(key, null); } public void initDecrypt(SymmetricKey key) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { initDecrypt(key, null); } private static byte[] getIVFromParams(AlgorithmParameterSpec params) { byte[] IV = null; if( params instanceof IVParameterSpec ) { IV = ((IVParameterSpec)params).getIV(); } else if( params instanceof IvParameterSpec ) { IV = ((IvParameterSpec)params).getIV(); } else if( params instanceof RC2ParameterSpec ) { IV = ((RC2ParameterSpec)params).getIV(); } return IV; } public void initEncrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { reset(); checkKey(key); checkParams(parameters); IV = getIVFromParams(parameters); this.key = key; this.parameters = parameters; state = ENCRYPT; if( parameters instanceof RC2ParameterSpec ) { contextProxy = initContextWithKeyBits( true, key, algorithm, IV, ((RC2ParameterSpec)parameters).getEffectiveKeyBits(), algorithm.isPadded()); } else { contextProxy = initContext( true, key, algorithm, IV, algorithm.isPadded()); } } public void initDecrypt(SymmetricKey key, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException, TokenException { reset(); checkKey(key); checkParams(parameters); IV = getIVFromParams(parameters); this.key = key; this.parameters = parameters; state = DECRYPT; if( parameters instanceof RC2ParameterSpec ) { contextProxy = initContextWithKeyBits( false, key, algorithm, IV, ((RC2ParameterSpec)parameters).getEffectiveKeyBits(), algorithm.isPadded()); } else { contextProxy = initContext( false, key, algorithm, IV, algorithm.isPadded()); } } public byte[] update(byte[] bytes) throws IllegalStateException, TokenException { if( state == UNINITIALIZED ) { throw new IllegalStateException(); } return updateContext( contextProxy, bytes, algorithm.getBlockSize()); } public byte[] update(byte[] bytes, int offset, int length) throws IllegalStateException, TokenException { byte[] sub = new byte[length]; System.arraycopy( bytes, offset, sub, 0, length ); return update(sub); } public byte[] doFinal(byte[] bytes) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException { if( state == UNINITIALIZED ) { throw new IllegalStateException(); } byte[] first = update(bytes); byte[] last = finalizeContext(contextProxy, algorithm.getBlockSize(), algorithm.isPadded() ); byte[] combined = new byte[ first.length+last.length ]; System.arraycopy(first, 0, combined, 0, first.length); System.arraycopy(last, 0, combined, first.length, last.length); return combined; } public byte[] doFinal(byte[] bytes, int offset, int length) throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException { byte[] sub = new byte[length]; System.arraycopy(bytes, offset, sub, 0, length); return doFinal(sub); } public byte[] doFinal() throws IllegalStateException, IllegalBlockSizeException, BadPaddingException, TokenException { if( state == UNINITIALIZED ) { throw new IllegalStateException(); } return finalizeContext(contextProxy, algorithm.getBlockSize(), algorithm.isPadded() ); } private static native CipherContextProxy initContext(boolean encrypt, SymmetricKey key, EncryptionAlgorithm alg, byte[] IV, boolean padded) throws TokenException; // This version accepts the number of effective key bits for RC2 CBC. private static native CipherContextProxy initContextWithKeyBits(boolean encrypt, SymmetricKey key, EncryptionAlgorithm alg, byte[] IV, int keyBits, boolean padded) throws TokenException; private static native byte[] updateContext( CipherContextProxy context, byte[] input, int blocksize ) throws TokenException; private static native byte[] finalizeContext( CipherContextProxy context, int blocksize, boolean padded) throws TokenException, IllegalBlockSizeException, BadPaddingException; private void reset() { parameters = null; key = null; IV = null; state = UNINITIALIZED; contextProxy = null; } /** * Matches the params against those expected by the algorithm. */ private void checkParams(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { if( ! algorithm.isValidParameterObject(params) ) { String name = "null"; if( params != null ) { name = params.getClass().getName(); } throw new InvalidAlgorithmParameterException(algorithm + " cannot use a " + name + " parameter"); } } /** * Checks for null, makes sure the key lives on the correct token, * makes sure it is a PKCS #11 key, makes sure it's the right type * for this algorithm. */ private void checkKey(SymmetricKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } if( ! key.getOwningToken().equals(token) ) { throw new InvalidKeyException("Key does not reside on the "+ "current token"); } if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } try { KeyType keyType = ((PK11SymKey) key).getKeyType(); if ( keyType != KeyType.GENERIC_SECRET && keyType != KeyType.getKeyTypeFromAlgorithm(algorithm) ) { throw new InvalidKeyException("Key is not the right type for"+ " this algorithm: " + ((PK11SymKey)key).getKeyType() + ":" + KeyType.getKeyTypeFromAlgorithm(algorithm) +";"); } } catch( NoSuchAlgorithmException e ) { Assert.notReached("Unknown algorithm"); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11DSAPrivateKey.java000066400000000000000000000017251326145000000231260ustar00rootroot00000000000000package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.security.interfaces.DSAParams; import java.security.interfaces.DSAPrivateKey; class PK11DSAPrivateKey extends PK11PrivKey implements DSAPrivateKey { private PK11DSAPrivateKey() { super(null); } protected PK11DSAPrivateKey(byte[] pointer) { super(pointer); } public PrivateKey.Type getType() { return PrivateKey.Type.DSA; } /** * If this fails, we just return null, since no exceptions are allowed. */ public DSAParams getParams() { try { return getDSAParams(); } catch(TokenException te) { return null; } } /** * Not implemented. NSS doesn't support extracting private key material * like this. */ public BigInteger getX() { return null; } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11DSAPublicKey.java000066400000000000000000000026131326145000000227270ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.util.Assert; import java.security.interfaces.DSAPublicKey; import java.security.interfaces.DSAParams; import java.security.spec.DSAParameterSpec; import java.math.BigInteger; public final class PK11DSAPublicKey extends PK11PubKey implements DSAPublicKey { public PK11DSAPublicKey(byte[] pointer) { super(pointer); } public DSAParams getParams() { try { BigInteger P = new BigInteger( getPByteArray() ); BigInteger Q = new BigInteger( getQByteArray() ); BigInteger G = new BigInteger( getGByteArray() ); return new DSAParameterSpec(P, Q, G); } catch(NumberFormatException e) { Assert.notReached("Unable to decode DSA parameters"); return null; } } public BigInteger getY() { try { return new BigInteger( getYByteArray() ); } catch(NumberFormatException e) { Assert.notReached("Unable to decode DSA public value"); return null; } } private native byte[] getPByteArray(); private native byte[] getQByteArray(); private native byte[] getGByteArray(); private native byte[] getYByteArray(); } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11ECPrivateKey.java000066400000000000000000000020221326145000000227750ustar00rootroot00000000000000package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.util.Assert; import java.math.BigInteger; // requires JAVA 1.5 //import java.security.interfaces.ECPrivateKey; class PK11ECPrivateKey // extends PK11PrivKey implements ECPrivateKey extends PK11PrivKey { private PK11ECPrivateKey() { super(null); } protected PK11ECPrivateKey(byte[] pointer) { super(pointer); } public PrivateKey.Type getType() { return PrivateKey.Type.EC; } /** * If this fails, we just return null, since no exceptions are allowed. */ // requires JAVA 1.5 // public ECParams getParams() { // try { // return getECParams(); // } catch(TokenException te) { // return null; // } // } /** * Not implemented. NSS doesn't support extracting private key material * like this. */ // requires JAVA 1.5 // public BigInteger getW() { // return null; // } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11ECPublicKey.java000066400000000000000000000027671326145000000226210ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.util.Assert; // Requires JAVA 1.5 //import java.security.interfaces.ECPublicKey; import java.math.BigInteger; // // Requires JAVA 1.5 //public final class PK11ECPublicKey extends PK11PubKey implements ECPublicKey { public final class PK11ECPublicKey extends PK11PubKey { public PK11ECPublicKey(byte[] pointer) { super(pointer); } // // Requires JAVA 1.5 // public ECParams getCurve() { // try { // return new BigInteger( getCurveByteArray() ); // } catch(NumberFormatException e) { // Assert.notReached("Unable to decode DSA parameters"); // return null; // } // } // public BigInteger getCurve() { try { return new BigInteger( getCurveByteArray() ); } catch(NumberFormatException e) { Assert.notReached("Unable to decode EC curve"); return null; } } public byte[] getCurveBA() { return getCurveByteArray(); } public BigInteger getW() { try { return new BigInteger( getWByteArray() ); } catch(NumberFormatException e) { Assert.notReached("Unable to decode EC public value"); return null; } } private native byte[] getCurveByteArray(); private native byte[] getWByteArray(); } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11InternalCert.java000066400000000000000000000057011326145000000231030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import java.security.*; import java.security.cert.*; import java.util.*; import java.math.BigInteger; /** * A certificate that lives in the internal cert database. */ public class PK11InternalCert extends PK11Cert implements InternalCertificate { /////////////////////////////////////////////////////////////////////// // Trust Management. This is all package stuff because it can only // be called from PK11InternalCert. /////////////////////////////////////////////////////////////////////// public static final int SSL = 0; public static final int EMAIL = 1; public static final int OBJECT_SIGNING=2; /** * Set the SSL trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public void setSSLTrust(int trust) { super.setTrust(SSL, trust); } /** * Set the email (S/MIME) trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public void setEmailTrust(int trust) { super.setTrust(EMAIL, trust); } /** * Set the object signing trust flags for this certificate. * * @param trust A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public void setObjectSigningTrust(int trust) { super.setTrust(OBJECT_SIGNING, trust); } /** * Get the SSL trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public int getSSLTrust() { return super.getTrust(SSL); } /** * Get the email (S/MIME) trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public int getEmailTrust() { return super.getTrust(EMAIL); } /** * Get the object signing trust flags for this certificate. * * @return A bitwise OR of the trust flags VALID_PEER, VALID_CA, * TRUSTED_CA, USER, and TRUSTED_CLIENT_CA. */ public int getObjectSigningTrust() { return super.getTrust(OBJECT_SIGNING); } ///////////////////////////////////////////////////////////// // Construction ///////////////////////////////////////////////////////////// PK11InternalCert(byte[] certPtr, byte[] slotPtr, String nickname) { super(certPtr, slotPtr, nickname); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11InternalTokenCert.java000066400000000000000000000014701326145000000241030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; /** * A certificate that lives on the internal token. It has database information * (like trust flags) but also PKCS #11 information (like unique ID). */ public final class PK11InternalTokenCert extends PK11InternalCert implements TokenCertificate { public byte[] getUniqueID() { return super.getUniqueID(); } public CryptoToken getOwningToken() { return super.getOwningToken(); } PK11InternalTokenCert(byte[] certPtr, byte[] slotPtr, String nickname) { super(certPtr, slotPtr, nickname); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Key.java000066400000000000000000000037421326145000000212440ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.IOException; import java.util.Hashtable; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.crypto.SignatureAlgorithm; abstract class PK11Key { ////////////////////////////////////////////////////////// // Public Interface /////////////////////////////////////////////////////////// /** * Subclasses that support encoding can overload this method. */ public byte[] getEncoded() { return null; } /** * Subclasses that support encoding can overload this method. */ public String getFormat() { return null; } ///////////////////////////////////////////////////////////// // Construction ///////////////////////////////////////////////////////////// protected PK11Key() {} ///////////////////////////////////////////////////////////// // Implementation ///////////////////////////////////////////////////////////// // **HACK** // Override serialization methods so that we don't get serialized, // even though we are supposed to support it as an implementation of Key. private void writeObject(ObjectOutputStream out) throws IOException { Assert._assert(false, "PKCS#11 Key is not really serializable"); } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { Assert._assert(false, "PKCS#11 Key is not really serializable"); } ///////////////////////////////////////////////////////////// // Members ///////////////////////////////////////////////////////////// protected KeyProxy keyProxy; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.c000066400000000000000000000314701326145000000224130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11KeyGenerator.h" #include #include #include #include #include #include /* for hand-generating SHA-1 PBA HMAC key */ #include #include "jssutil.h" #include "pk11util.h" #include #include #include #include #include /*********************************************************************** * * PK11KeyGenerator.generateNormal * * Generates a non-PBE symmetric key on a token. * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generateNormal (JNIEnv *env, jclass clazz, jobject token, jobject alg, jint strength, jint opFlags, jboolean temporary, jint sensitive) { PK11SlotInfo *slot=NULL; PK11SymKey *skey=NULL; CK_MECHANISM_TYPE mech; PK11AttrFlags attrFlags=0; jobject keyObj=NULL; PR_ASSERT( env!=NULL && clazz!=NULL && token!=NULL && alg!=NULL ); /* Get the slot */ if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS ) { goto finish; } /* Get the algorithm info */ mech = JSS_getPK11MechFromAlg(env, alg); PR_ASSERT(mech != CKM_INVALID_MECHANISM); if(!temporary) { attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE); } if(sensitive==1) { attrFlags |= PK11_ATTR_SENSITIVE; } else if(sensitive==0) { attrFlags |= PK11_ATTR_INSENSITIVE; } /* generate the key */ skey = PK11_TokenKeyGenWithFlags(slot, mech, NULL /*param*/, strength/8 /*in bytes*/, NULL /*keyid*/, opFlags, attrFlags, NULL /*wincx*/ ); if(skey==NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "KeyGen failed on token"); goto finish; } /* wrap the key. This sets skey to NULL. */ keyObj = JSS_PK11_wrapSymKey(env, &skey); finish: if(skey!=NULL) { /* will only be non-NULL if keygen succeeded but wrapSymKey failed */ PK11_FreeSymKey(skey); } return keyObj; } /* We do the translation in Java now, but I'll leave this here just in case */ #if 0 /*********************************************************************** * * C o p y P a s s w o r d T o S E C I t e m * * pass * A Java Password object. * * RETURNS * A new SECItem containing a copy of the bytes in the password, * or NULL iff an exception occurred. Be sure to zero it when * you free it. */ static SECItem* CopyPasswordToSECItem(JNIEnv *env, jobject pass) { jclass passClass=NULL; jmethodID byteCopyMethod=NULL; jbyteArray pwArray=NULL; jbyte *bytes=NULL; SECItem *item=NULL; int numBytes=0; PR_ASSERT(env!=NULL && pass!=NULL); /* get password class and method */ passClass = (*env)->GetObjectClass(env, pass); if(passClass == NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password class"); ASSERT_OUTOFMEM(env); goto finish; } byteCopyMethod = (*env)->GetMethodID( env, passClass, PW_GET_BYTE_COPY_NAME, PW_GET_BYTE_COPY_SIG); if(byteCopyMethod==NULL) { JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password manipulation" " methods from native implementation"); ASSERT_OUTOFMEM(env); goto finish; } /* copy to a byte array */ pwArray = (*env)->CallObjectMethod(env, pass, byteCopyMethod); if(pwArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } numBytes = (*env)->GetArrayLength(env, pwArray); /* copy from the byte array to a jbyte array */ bytes = (*env)->GetByteArrayElements(env, pwArray, NULL); if(bytes == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* copy from the jbyte array to a new SECItem */ item = PR_NEW(SECItem); /* last byte is null termination */ PR_ASSERT( bytes[numBytes-1] == 0 ); item->len = numBytes - 1; item->data = PR_Malloc(item->len); if(item->data==NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } memcpy(item->data, bytes, item->len); finish: if(bytes!=NULL) { /* clear the password */ PR_ASSERT(numBytes > 0); memset(bytes, 0, numBytes); (*env)->ReleaseByteArrayElements(env, pwArray, bytes, 0); } else { PR_ASSERT(pwArray!=NULL); } return item; } #endif static void FUNCTION_MAY_NOT_BE_USED print_secitem(SECItem *item) { int i; int online; if(item==NULL) { return; } for(i=0, online=0; i < item->len; i++, online++) { if(online > 25) { printf("\n"); online = 0; } printf("%.2x ", item->data[i]); } } /*********************************************************************** * * c o n s t r u c t S H A 1 P B A K e y * * Constructs a PBE key using CKM_PBA_SHA1_WITH_SHA1_HMAC. This should * be supported by NSS automatically, but isn't (bug #336587). * * RETURNS * A symmetric key from the given password, salt, and iteration count, * or NULL if an exception was thrown. * THROWS * TokenException if an error occurs. */ static PK11SymKey* constructSHA1PBAKey(JNIEnv *env, PK11SlotInfo *slot, SECItem *pwitem, SECItem *salt, int iterationCount) { PK11SymKey *key=NULL; unsigned char ivData[8]; SECItem mechItem; CK_PBE_PARAMS pbe_params; if( pwitem == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "constructSHA1PAKey:" " pwitem NULL"); goto finish; } if( salt == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "constructSHA1PAKey:" " salt NULL"); goto finish; } pbe_params.pInitVector = ivData; pbe_params.pPassword = pwitem->data; pbe_params.ulPasswordLen = pwitem->len; pbe_params.pSalt = salt->data; pbe_params.ulSaltLen = salt->len; pbe_params.ulIteration = iterationCount; mechItem.data = (unsigned char *) &pbe_params; mechItem.len = sizeof(pbe_params); key = PK11_RawPBEKeyGen(slot, CKM_PBA_SHA1_WITH_SHA1_HMAC, &mechItem, pwitem, PR_FALSE, NULL); if( key == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "PK11_RawPBEKeyGen:" " failed to generate key"); goto finish; } finish: return key; } /*********************************************************************** * * PK11KeyGenerator.generatePBE * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE( JNIEnv *env, jclass clazz, jobject token, jobject alg, jobject encAlg, jbyteArray passBA, jbyteArray saltBA, jint iterationCount) { PK11SlotInfo *slot=NULL; PK11SymKey *skey=NULL; SECOidTag oidTag; SECAlgorithmID *algid=NULL; SECItem *salt=NULL; SECItem *pwitem=NULL; jobject keyObj=NULL; CK_MECHANISM_TYPE mech=CKM_INVALID_MECHANISM; PR_ASSERT(env!=NULL && clazz!=NULL && token!=NULL && alg!=NULL && passBA!=NULL && saltBA!=NULL); /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { goto finish; } /* convert salt to SECItem */ salt = JSS_ByteArrayToSECItem(env, saltBA); if(salt == NULL) { goto finish; } /* convert password to SECItem */ pwitem = JSS_ByteArrayToSECItem(env, passBA); if(pwitem==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* print_secitem(pwitem); */ mech = JSS_getPK11MechFromAlg(env, alg); if( mech == CKM_PBA_SHA1_WITH_SHA1_HMAC ) { /* special case, construct key by hand. Bug #336587 */ skey = constructSHA1PBAKey(env, slot, pwitem, salt, iterationCount); if( skey==NULL ) { /* exception was thrown */ goto finish; } } else { /* get the algorithm info */ oidTag = JSS_getOidTagFromAlg(env, alg); PR_ASSERT(oidTag != SEC_OID_UNKNOWN); SECOidTag encAlgOidTag = JSS_getOidTagFromAlg(env, encAlg); PR_ASSERT(encAlgOidTag != SEC_OID_UNKNOWN); /* create algid */ algid = PK11_CreatePBEV2AlgorithmID( oidTag, encAlgOidTag, SEC_OID_HMAC_SHA1, 0, iterationCount, salt); if( algid == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to process PBE parameters"); goto finish; } /* generate the key */ skey = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE /*faulty3DES*/, NULL /*wincx*/); if( skey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to generate PBE key"); goto finish; } } /* wrap the key. This sets skey to NULL. */ keyObj = JSS_PK11_wrapSymKey(env, &skey); finish: if(algid) { SECOID_DestroyAlgorithmID(algid, PR_TRUE /*freeit*/); } if(salt) { SECITEM_FreeItem(salt, PR_TRUE /*freeit*/); } if(pwitem) { SECITEM_ZfreeItem(pwitem, PR_TRUE /*freeit*/); } if(skey) { /* skey will be NULL if everything worked */ PK11_FreeSymKey(skey); } return keyObj; } /*********************************************************************** * * PK11KeyGenerator.generatePBE_IV * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_generatePBE_1IV (JNIEnv *env, jclass clazz, jobject alg, jbyteArray passBA, jbyteArray saltBA, jint iterationCount) { SECOidTag oidTag; SECAlgorithmID *algid=NULL; SECItem *salt=NULL; SECItem *pwitem=NULL; SECItem *ivItem=NULL; jbyteArray ivBA=NULL; PR_ASSERT(env!=NULL && clazz!=NULL && alg!=NULL && passBA!=NULL && saltBA!=NULL); /* get the algorithm info */ oidTag = JSS_getOidTagFromAlg(env, alg); PR_ASSERT(oidTag != SEC_OID_UNKNOWN); /* convert salt to SECItem */ salt = JSS_ByteArrayToSECItem(env, saltBA); if(salt == NULL) { goto finish; } /* create algid */ algid = PK11_CreatePBEAlgorithmID(oidTag, iterationCount, salt); if( algid == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to process PBE parameters"); goto finish; } /* convert password to SECItem */ pwitem = JSS_ByteArrayToSECItem(env, passBA); if(pwitem==NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* generate the IV */ ivItem = SEC_PKCS5GetIV(algid, pwitem, PR_FALSE /*faulty3DES*/); if(ivItem==NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to generate PBE " "initialization vector"); goto finish; } /* convert IV to byte array */ ivBA = JSS_SECItemToByteArray(env, ivItem); finish: if(algid) { SECOID_DestroyAlgorithmID(algid, PR_TRUE /*freeit*/); } if(salt) { SECITEM_FreeItem(salt, PR_TRUE /*freeit*/); } if(pwitem) { SECITEM_ZfreeItem(pwitem, PR_TRUE /*freeit*/); } if(ivItem) { SECITEM_FreeItem(ivItem, PR_TRUE /*freeit*/); } return ivBA; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyGenerator_nativeClone (JNIEnv *env, jclass clazz, jobject tokenObj, jobject toBeClonedObj) { PK11SlotInfo *slot=NULL; PK11SymKey *toBeCloned=NULL; PK11SymKey *clone=NULL; SECStatus rv; jobject cloneObj=NULL; PR_ASSERT(env!=NULL && tokenObj!=NULL && toBeClonedObj!=NULL); /* get slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get toBeCloned */ if( JSS_PK11_getSymKeyPtr(env, toBeClonedObj, &toBeCloned) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* extract the key value */ rv = PK11_ExtractKeyValue(toBeCloned); if( rv != SECSuccess ) { JSS_throw(env, NOT_EXTRACTABLE_EXCEPTION); goto finish; } clone = PK11_ImportSymKey( slot, PK11_GetMechanism(toBeCloned), PK11_OriginGenerated, /* we don't know this, but it doesn't matter */ CKA_ENCRYPT, /* !!! Actually we want to enable all operations */ PK11_GetKeyData(toBeCloned), NULL /* wincx */ ); if( clone == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to create new symmetric" " key object"); goto finish; } /* wrap the new key in a Java object */ cloneObj = JSS_PK11_wrapSymKey(env, &clone); finish: if( clone!=NULL ) { /* clone would be NULL if we completed successfully */ PK11_FreeSymKey(clone); } return cloneObj; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11KeyGenerator.java000066400000000000000000000254361326145000000231170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import java.security.InvalidKeyException; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.util.Password; import org.mozilla.jss.util.UTF8Converter; import java.io.CharConversionException; public final class PK11KeyGenerator implements KeyGenerator { // opFlag constants: each of these flags specifies a crypto operation // the key will support. Their values must match the same-named C // preprocessor macros defined in the PKCS #11 header pkcs11t.h. private static final int CKF_ENCRYPT = 0x00000100; private static final int CKF_DECRYPT = 0x00000200; private static final int CKF_SIGN = 0x00000800; private static final int CKF_VERIFY = 0x00002000; private static final int CKF_WRAP = 0x00020000; private static final int CKF_UNWRAP = 0x00040000; // A table for mapping SymmetricKey.Usage to opFlag. This must be // synchronized with SymmetricKey.Usage. private static final int opFlagForUsage[] = { CKF_ENCRYPT, /* 0 */ CKF_DECRYPT, /* 1 */ CKF_WRAP, /* 2 */ CKF_UNWRAP, /* 3 */ CKF_SIGN, /* 4 */ CKF_VERIFY /* 5 */ }; // The token this key will be generated on. private PK11Token token; // The algorithm to use to generate the key private KeyGenAlgorithm algorithm; // The strength of the key to be generated in bits. A value of 0 means // that the strength has not been set. This is OK for most algorithms. private int strength=0; // The parameters for this algorithm. May be null for some algorithms. private AlgorithmParameterSpec parameters; // The crypto operations the key will support. It is the logical OR // of the opFlag constants, each specifying a supported operation. private int opFlags = CKF_SIGN | CKF_ENCRYPT; // Whether the key will be temporary or permanent private boolean temporaryKeyMode = true; // Whether the key will be sensitive or insensitive // 1: sensitive // 0: insensitive // -1: unspecified (token dependent) private int sensitiveKeyMode = -1; // Used to convert Java Password into a byte[]. private KeyGenerator.CharToByteConverter charToByte; private PK11KeyGenerator() { } // package private constructor PK11KeyGenerator(PK11Token token, KeyGenAlgorithm algorithm) { if( token==null || algorithm==null ) { throw new NullPointerException(); } this.token = token; this.algorithm = algorithm; charToByte = new KeyGenerator.CharToByteConverter() { public byte[] convert(char[] chars) throws CharConversionException { return UTF8Converter.UnicodeToUTF8(chars); } }; } /** * Sets the character to byte converter for passwords. The default * conversion is UTF8 with no null termination. */ public void setCharToByteConverter( KeyGenerator.CharToByteConverter charToByte) { if( charToByte==null ) { throw new IllegalArgumentException("CharToByteConverter is null"); } this.charToByte = charToByte; } /** * @param strength Key size in bits. Must be evenly divisible by 8. */ public void initialize(int strength) throws InvalidAlgorithmParameterException { // if this algorithm only accepts PBE key gen params, it can't // use a strength Class[] paramClasses = algorithm.getParameterClasses(); if( paramClasses.length == 1 && paramClasses[0].equals(PBEKeyGenParams.class) ) { throw new InvalidAlgorithmParameterException("PBE keygen "+ "algorithms require PBEKeyGenParams "); } // validate the strength for our algorithm if( ! algorithm.isValidStrength(strength) ) { throw new InvalidAlgorithmParameterException(strength+ " is not a valid strength for "+algorithm); } if( strength % 8 != 0 ) { throw new InvalidAlgorithmParameterException( "Key strength must be divisible by 8"); } this.strength = strength; } public void initialize(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException { if( ! algorithm.isValidParameterObject(parameters) ) { String name = "null"; if( parameters != null ) { name = parameters.getClass().getName(); } throw new InvalidAlgorithmParameterException( algorithm + " cannot use a " + name + " parameter"); } this.parameters = parameters; } public void setKeyUsages(SymmetricKey.Usage[] usages) { this.opFlags = 0; for( int i = 0; i < usages.length; i++ ) { if( usages[i] != null ) { this.opFlags |= opFlagForUsage[usages[i].getVal()]; } } } public void temporaryKeys(boolean temp) { this.temporaryKeyMode = temp; } public void sensitiveKeys(boolean sensitive) { this.sensitiveKeyMode = sensitive ? 1 : 0; } /** * Generates the key. This is the public interface, the actual * work is done by native methods. */ public SymmetricKey generate() throws IllegalStateException, TokenException, CharConversionException { Class[] paramClasses = algorithm.getParameterClasses(); if( paramClasses.length == 1 && paramClasses[0].equals(PBEKeyGenParams.class) ) { if(parameters==null || !(parameters instanceof PBEKeyGenParams)) { throw new IllegalStateException( "PBE keygen algorithms require PBEKeyGenParams"); } PBEKeyGenParams kgp = (PBEKeyGenParams)parameters; byte[] pwbytes=null; try { pwbytes = charToByte.convert( kgp.getPassword().getChars() ); return generatePBE( token, algorithm, kgp.getEncryptionAlgorithm(), pwbytes, kgp.getSalt(), kgp.getIterations()); } finally { if( pwbytes!=null ) { Password.wipeBytes(pwbytes); } } } else { return generateNormal(token, algorithm, strength, opFlags, temporaryKeyMode, sensitiveKeyMode); } } /** * Generates an Initialization Vector using a PBE algorithm. * In order to call this method, the algorithm must be a PBE algorithm, * and the KeyGenerator must have been initialized with an instance * of PBEKeyGenParams. * * @return The initialization vector derived from the password and salt * using the PBE algorithm. */ public byte[] generatePBE_IV() throws TokenException, CharConversionException { Class[] paramClasses = algorithm.getParameterClasses(); if( paramClasses.length == 1 && paramClasses[0].equals(PBEKeyGenParams.class) ) { if(parameters==null || !(parameters instanceof PBEKeyGenParams)) { throw new IllegalStateException( "PBE keygen algorithms require PBEKeyGenParams"); } PBEKeyGenParams kgp = (PBEKeyGenParams)parameters; byte[] pwbytes=null; try { pwbytes = charToByte.convert(kgp.getPassword().getChars()); return generatePBE_IV(algorithm, pwbytes, kgp.getSalt(), kgp.getIterations() ); } finally { if(pwbytes!=null) { Password.wipeBytes(pwbytes); } } } else { throw new IllegalStateException( "IV generation can only be performed by PBE algorithms"); } } /** * A native method to generate an IV using a PBE algorithm. * None of the parameters should be NULL. */ private static native byte[] generatePBE_IV(KeyGenAlgorithm alg, byte[] password, byte[] salt, int iterations) throws TokenException; /** * Allows a SymmetricKey to be cloned on a different token. * * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public SymmetricKey clone(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException { return clone(key, token); } /** * Allows a SymmetricKey to be cloned on a different token. * * @param key The key to clone. * @param token The token on which to clone the key. * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public static SymmetricKey clone(SymmetricKey key, PK11Token token) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException { if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } return nativeClone(token, key); } private static native SymmetricKey nativeClone(PK11Token token, SymmetricKey toBeCloned) throws SymmetricKey.NotExtractableException, TokenException; /** * A native method to generate a non-PBE key. * @param token The token where the key generation happens * @param algorithm The algorithm to use * @param strength The key size in bits, should be 0 for fixed-length * key algorithms. * @param opFlags The crypto operations the key will support * @param temporary Whether the key will be temporary or permanent */ private static native SymmetricKey generateNormal(PK11Token token, KeyGenAlgorithm algorithm, int strength, int opFlags, boolean temporary, int sensitive) throws TokenException; /** * A native method to generate a PBE key. None of the parameters should * be null. */ private static native SymmetricKey generatePBE( PK11Token token, KeyGenAlgorithm algorithm, EncryptionAlgorithm encAlg, byte[] pass, byte[] salt, int iterationCount) throws TokenException; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.c000066400000000000000000000363221326145000000232300ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11KeyPairGenerator.h" #include #include #include #include #include #include #include #include #include #include /*********************************************************************** * * k e y s T o K e y P a i r * * Turns a SECKEYPrivateKey and a SECKEYPublicKey into a Java KeyPair * object. * * INPUTS * pPrivk * Address of a SECKEYPrivateKey* which will be consumed by the * KeyPair. The pointer will be set to NULL. It is not necessary * to free this private key if the function exits successfully. * pPubk * Address of a SECKEYPublicKey* which will be consumed by this * KeyPair. The pointer will be set to NULL. It is not necessary * to free this public key if the function exits successfully. */ static jobject keysToKeyPair(JNIEnv *env, SECKEYPrivateKey **pPrivk, SECKEYPublicKey **pPubk) { jobject privateKey; jobject publicKey; jobject keyPair=NULL; jclass keyPairClass; jmethodID keyPairConstructor; /************************************************** * wrap the keys in Java objects *************************************************/ publicKey = JSS_PK11_wrapPubKey(env, pPubk); privateKey = JSS_PK11_wrapPrivKey(env, pPrivk); if(publicKey==NULL || privateKey==NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /************************************************** * encapsulate the keys in a keypair *************************************************/ keyPairClass = (*env)->FindClass(env, KEY_PAIR_CLASS_NAME); if(keyPairClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyPairConstructor = (*env)->GetMethodID( env, keyPairClass, KEY_PAIR_CONSTRUCTOR_NAME, KEY_PAIR_CONSTRUCTOR_SIG); if(keyPairConstructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyPair = (*env)->NewObject(env, keyPairClass, keyPairConstructor, publicKey, privateKey); if(keyPair == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: return keyPair; } int PK11_NumberObjectsFor(PK11SlotInfo*, CK_ATTRIBUTE*, int); SECStatus JSS_PK11_generateKeyPairWithOpFlags(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, void *params, PRBool temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { PK11AttrFlags attrFlags = 0; *privk=NULL; *pubk=NULL; PR_ASSERT(env!=NULL && slot!=NULL); /************************************************** * login to the token if necessary *************************************************/ if( PK11_Authenticate(slot, PR_TRUE /*loadcerts*/, NULL) != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "unable to login to token"); goto finish; } /************************************************** * generate the key pair on the token *************************************************/ if( temporary ) { attrFlags |= PK11_ATTR_SESSION; } else { attrFlags |= PK11_ATTR_TOKEN; } if( extractable == 1 ) { attrFlags |= PK11_ATTR_EXTRACTABLE; } else if( extractable == 0 ) { attrFlags |= PK11_ATTR_UNEXTRACTABLE; } /* * The default of sensitive is set this way to be backward * compatible. */ if( sensitive == -1 ) { sensitive = !temporary; } /* * The PRIVATE/PUBLIC attributes are set this way to be backward * compatible with the original PK11_GenerateKeyPair call. */ if( sensitive ) { attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE); } else { attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC); } *privk = PK11_GenerateKeyPairWithOpFlags(slot, mechanism, params, pubk, attrFlags, (CK_FLAGS) op_flags, (CK_FLAGS) op_flags_mask /* the ones we don't want*/, NULL /* default PW callback */ ); if( *privk == NULL ) { int errLength; char *errBuf; char *msgBuf; errLength = PR_GetErrorTextLength(); if(errLength > 0) { errBuf = PR_Malloc(errLength); if(errBuf == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } PR_GetErrorText(errBuf); } msgBuf = PR_smprintf("Keypair Generation failed on token with error: %d : %s", PR_GetError(), errLength>0? errBuf : ""); if(errLength>0) { PR_Free(errBuf); } JSS_throwMsg(env, TOKEN_EXCEPTION, msgBuf); PR_Free(msgBuf); goto finish; } return SECSuccess; finish: if(*privk!=NULL) { SECKEY_DestroyPrivateKey(*privk); *privk = NULL; } if(*pubk!=NULL) { SECKEY_DestroyPublicKey(*pubk); *pubk = NULL; } return SECFailure; } /* * make a common key gen function for both this file and PK11Token.c */ SECStatus JSS_PK11_generateKeyPair(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, void *params, PRBool temporary, jint sensitive, jint extractable) { return JSS_PK11_generateKeyPairWithOpFlags(env, mechanism, slot, pubk, privk, params, temporary, sensitive, extractable, 0, 0); } /********************************************************************** * Local generic helpers */ static jobject PK11KeyPairGeneratorWithOpFlags(JNIEnv *env, jobject this, jobject token, CK_MECHANISM_TYPE mechanism, void *params, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { PK11SlotInfo* slot; SECKEYPrivateKey *privk=NULL; SECKEYPublicKey *pubk=NULL; jobject keyPair=NULL; SECStatus rv; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL); /************************************************** * get the slot pointer *************************************************/ if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); rv = JSS_PK11_generateKeyPairWithOpFlags(env, mechanism, slot, &pubk, &privk, params, temporary, sensitive, extractable, op_flags, op_flags_mask); if (rv != SECSuccess) { goto finish; } /************************************************** * wrap in a Java KeyPair object *************************************************/ keyPair = keysToKeyPair(env, &privk, &pubk); if(keyPair == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } finish: if(privk!=NULL) { SECKEY_DestroyPrivateKey(privk); } if(pubk!=NULL) { SECKEY_DestroyPublicKey(pubk); } return keyPair; } static jobject PK11KeyPairGenerator(JNIEnv *env, jobject this, jobject token, CK_MECHANISM_TYPE mechanism, void *params, jboolean temporary, jint sensitive, jint extractable) { return PK11KeyPairGeneratorWithOpFlags(env, this, token, mechanism, params, temporary, sensitive, extractable, 0, 0); } /********************************************************************** * PK11KeyPairGenerator.generateRSAKeyPair */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPair (JNIEnv *env, jobject this, jobject token, jint keySize, jlong publicExponent, jboolean temporary, jint sensitive, jint extractable) { PK11RSAGenParams params; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL); /************************************************** * setup parameters *************************************************/ params.keySizeInBits = keySize; params.pe = publicExponent; return PK11KeyPairGenerator(env, this, token, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶ms, temporary, sensitive, extractable); } /********************************************************************** * PK11KeyPairGenerator.generateRSAKeyPairWithOpFlags */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateRSAKeyPairWithOpFlags (JNIEnv *env, jobject this, jobject token, jint keySize, jlong publicExponent, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { PK11RSAGenParams params; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL); /************************************************** * setup parameters *************************************************/ params.keySizeInBits = keySize; params.pe = publicExponent; return PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_RSA_PKCS_KEY_PAIR_GEN, ¶ms, temporary, sensitive, extractable, op_flags, op_flags_mask); } #define ZERO_SECITEM(item) {(item).len=0; (item).data=NULL;} /********************************************************************** * * PK11KeyPairGenerator.generateDSAKeyPair * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPair (JNIEnv *env, jobject this, jobject token, jbyteArray P, jbyteArray Q, jbyteArray G, jboolean temporary, jint sensitive, jint extractable) { SECItem p, q, g; PQGParams *params=NULL; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && P!=NULL && Q!=NULL && G!=NULL); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(p); ZERO_SECITEM(q); ZERO_SECITEM(g); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, P, &p) || JSS_ByteArrayToOctetString(env, Q, &q) || JSS_ByteArrayToOctetString(env, G, &g) ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } params = PK11_PQG_NewParams(&p, &q, &g); if(params == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } keyPair = PK11KeyPairGenerator(env, this, token, CKM_DSA_KEY_PAIR_GEN, params, temporary, sensitive, extractable); finish: SECITEM_FreeItem(&p, PR_FALSE); SECITEM_FreeItem(&q, PR_FALSE); SECITEM_FreeItem(&g, PR_FALSE); PK11_PQG_DestroyParams(params); return keyPair; } /********************************************************************** * * PK11KeyPairGenerator.generateDSAKeyPair * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags (JNIEnv *env, jobject this, jobject token, jbyteArray P, jbyteArray Q, jbyteArray G, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { SECItem p, q, g; PQGParams *params=NULL; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && P!=NULL && Q!=NULL && G!=NULL); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(p); ZERO_SECITEM(q); ZERO_SECITEM(g); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, P, &p) || JSS_ByteArrayToOctetString(env, Q, &q) || JSS_ByteArrayToOctetString(env, G, &g) ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } params = PK11_PQG_NewParams(&p, &q, &g); if(params == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } keyPair = PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_DSA_KEY_PAIR_GEN, params, temporary, sensitive, extractable, op_flags, op_flags_mask); finish: SECITEM_FreeItem(&p, PR_FALSE); SECITEM_FreeItem(&q, PR_FALSE); SECITEM_FreeItem(&g, PR_FALSE); PK11_PQG_DestroyParams(params); return keyPair; } void DumpItem(SECItem *item) { unsigned char *data = item->data; int i; for (i=0; i < item->len; i++) { printf(" %02x",data[i]); } printf(" : %8p %d\n", data, item->len); } /********************************************************************** * * PK11KeyPairGenerator.generateECKeyPair * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPair (JNIEnv *env, jobject this, jobject token, jbyteArray Curve, jboolean temporary, jint sensitive, jint extractable) { SECItem curve; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && Curve!=NULL ); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(curve); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, Curve, &curve)) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } keyPair = PK11KeyPairGenerator(env, this, token, CKM_EC_KEY_PAIR_GEN, &curve, temporary, sensitive, extractable); finish: SECITEM_FreeItem(&curve, PR_FALSE); return keyPair; } /********************************************************************** * * PK11KeyPairGenerator.generateECKeyPairWithOpFlags * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateECKeyPairWithOpFlags (JNIEnv *env, jobject this, jobject token, jbyteArray Curve, jboolean temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask) { SECItem curve; jobject keyPair=NULL; PR_ASSERT(env!=NULL && this!=NULL && token!=NULL && Curve!=NULL ); /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(curve); /************************************************** * Setup the parameters *************************************************/ if( JSS_ByteArrayToOctetString(env, Curve, &curve)) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } keyPair = PK11KeyPairGeneratorWithOpFlags(env, this, token, CKM_EC_KEY_PAIR_GEN, &curve, temporary, sensitive, extractable, op_flags, op_flags_mask); finish: SECITEM_FreeItem(&curve, PR_FALSE); return keyPair; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11KeyPairGenerator.java000066400000000000000000001421111326145000000237210ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import org.mozilla.jss.asn1.*; import java.math.BigInteger; import java.security.*; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.DSAParameterSpec; import java.util.Hashtable; /** * A Key Pair Generator implemented using PKCS #11. * * @see org.mozilla.jss.crypto.PQGParams */ public final class PK11KeyPairGenerator extends org.mozilla.jss.crypto.KeyPairGeneratorSpi { // curve code for getting the actual EC curve private enum ECCurve_Code { // NIST, SEC2 Prime curves secp521r1 , // == nistp521 nistp521 , secp384r1 , // == nistp384 nistp384 , secp256r1 , // == nistp256 nistp256 , secp256k1 , secp224r1 , // == nistp224 nistp224 , secp224k1 , secp192r1 , // == nistp192 nistp192 , secp192k1 , secp160r2 , secp160r1 , secp160k1 , secp128r2 , secp128r1 , secp112r2 , secp112r1 , // NIST, SEC2 Binary curves sect571r1 , // == nistb571 nistb571 , sect571k1 , // == nistk571 nistk571 , sect409r1 , // == nistb409 nistb409 , sect409k1 , // == nistk409 nistk409 , sect283r1 , // == nistb283 nistb283 , sect283k1 , // == nistk283 nistk283 , sect239k1 , sect233r1 , // == nistb233 nistb233 , sect233k1 , // == nistk233 nistk233 , sect193r2 , sect193r1 , nistb163 , sect163r2 , // == nistb163 sect163r1 , sect163k1 , // == nistk163 nistk163 , sect131r2 , sect131r1 , sect113r2 , sect113r1 , // ANSI X9.62 Prime curves prime239v3 , prime239v2 , prime239v1 , prime192v3 , prime192v2 , prime192v1 , // == nistp192 // prime256v1 == nistp256 // ANSI X9.62 Binary curves c2pnb163v1 , c2pnb163v2 , c2pnb163v3 , c2pnb176v1 , c2tnb191v1 , c2tnb191v2 , c2tnb191v3 , //c2onb191v4 , //c2onb191v5 , c2pnb208w1 , c2tnb239v1 , c2tnb239v2 , c2tnb239v3 , //c2onb239v4 , //c2onb239v5 , c2pnb272w1 , c2pnb304w1 , c2tnb359v1 , c2pnb368w1 , c2tnb431r1 // no WTLS curves fo now }; private static Hashtable ECCurve_NameToCode = new Hashtable(); static { // NIST, SEC2 Prime curves ECCurve_NameToCode.put( "secp521r1", ECCurve_Code.secp521r1); ECCurve_NameToCode.put( "nistp521", ECCurve_Code.nistp521); ECCurve_NameToCode.put( "secp384r1", ECCurve_Code.secp384r1); ECCurve_NameToCode.put( "nistp384", ECCurve_Code.nistp384); ECCurve_NameToCode.put( "secp256r1", ECCurve_Code.secp256r1); ECCurve_NameToCode.put( "nistp256", ECCurve_Code.nistp256); ECCurve_NameToCode.put( "secp256k1", ECCurve_Code.secp256k1); ECCurve_NameToCode.put( "secp224r1", ECCurve_Code.secp224r1); ECCurve_NameToCode.put( "nistp224", ECCurve_Code.nistp224); ECCurve_NameToCode.put( "secp224k1", ECCurve_Code.secp224k1); ECCurve_NameToCode.put( "secp192r1", ECCurve_Code.secp192r1); ECCurve_NameToCode.put( "nistp192", ECCurve_Code.nistp192); ECCurve_NameToCode.put( "secp192k1", ECCurve_Code.secp192k1); ECCurve_NameToCode.put( "secp160r2", ECCurve_Code.secp160r2); ECCurve_NameToCode.put( "secp160r1", ECCurve_Code.secp160r1); ECCurve_NameToCode.put( "secp160k1", ECCurve_Code.secp160k1); ECCurve_NameToCode.put( "secp128r2", ECCurve_Code.secp128r2); ECCurve_NameToCode.put( "secp128r1", ECCurve_Code.secp128r1); ECCurve_NameToCode.put( "secp112r2", ECCurve_Code.secp112r2); ECCurve_NameToCode.put( "secp112r1", ECCurve_Code.secp112r1); // NIST, SEC2 Binary curves ECCurve_NameToCode.put( "sect571r1", ECCurve_Code.sect571r1); ECCurve_NameToCode.put( "nistb571", ECCurve_Code.nistb571); ECCurve_NameToCode.put( "sect571k1", ECCurve_Code.sect571k1); ECCurve_NameToCode.put( "nistk571", ECCurve_Code.nistk571); ECCurve_NameToCode.put( "sect409r1", ECCurve_Code.sect409r1); ECCurve_NameToCode.put( "nistb409", ECCurve_Code.nistb409); ECCurve_NameToCode.put( "sect409k1", ECCurve_Code.sect409k1); ECCurve_NameToCode.put( "nistk409", ECCurve_Code.nistk409); ECCurve_NameToCode.put( "sect283r1", ECCurve_Code.sect283r1); ECCurve_NameToCode.put( "nistb283", ECCurve_Code.nistb283); ECCurve_NameToCode.put( "sect283k1", ECCurve_Code.sect283k1); ECCurve_NameToCode.put( "nistk283", ECCurve_Code.nistk283); ECCurve_NameToCode.put( "sect239k1", ECCurve_Code.sect239k1); ECCurve_NameToCode.put( "sect233r1", ECCurve_Code.sect233r1); ECCurve_NameToCode.put( "nistb233", ECCurve_Code.nistb233); ECCurve_NameToCode.put( "sect233k1", ECCurve_Code.sect233k1); ECCurve_NameToCode.put( "nistk233", ECCurve_Code.nistk233); ECCurve_NameToCode.put( "sect193r2", ECCurve_Code.sect193r2); ECCurve_NameToCode.put( "sect193r1", ECCurve_Code.sect193r1); ECCurve_NameToCode.put( "nistb163", ECCurve_Code.nistb163); ECCurve_NameToCode.put( "sect163r2", ECCurve_Code.sect163r2); ECCurve_NameToCode.put( "sect163r1", ECCurve_Code.sect163r1); ECCurve_NameToCode.put( "sect163k1", ECCurve_Code.sect163k1); ECCurve_NameToCode.put( "nistk163", ECCurve_Code.nistk163); ECCurve_NameToCode.put( "sect131r2", ECCurve_Code.sect131r2); ECCurve_NameToCode.put( "sect131r1", ECCurve_Code.sect131r1); ECCurve_NameToCode.put( "sect113r2", ECCurve_Code.sect113r2); ECCurve_NameToCode.put( "sect113r1", ECCurve_Code.sect113r1); // ANSI Prime curves ECCurve_NameToCode.put( "prime239v3", ECCurve_Code.prime239v3); ECCurve_NameToCode.put( "prime239v2", ECCurve_Code.prime239v2); ECCurve_NameToCode.put( "prime239v1", ECCurve_Code.prime239v1); ECCurve_NameToCode.put( "prime192v3", ECCurve_Code.prime192v3); ECCurve_NameToCode.put( "prime192v2", ECCurve_Code.prime192v2); ECCurve_NameToCode.put( "prime192v1", ECCurve_Code.prime192v1); // ANSI Binary curves ECCurve_NameToCode.put( "c2pnb163v1", ECCurve_Code.c2pnb163v1); ECCurve_NameToCode.put( "c2pnb163v2", ECCurve_Code.c2pnb163v2); ECCurve_NameToCode.put( "c2pnb163v3", ECCurve_Code.c2pnb163v3); ECCurve_NameToCode.put( "c2pnb176v1", ECCurve_Code.c2pnb176v1); ECCurve_NameToCode.put( "c2tnb191v1", ECCurve_Code.c2tnb191v1); ECCurve_NameToCode.put( "c2tnb191v2", ECCurve_Code.c2tnb191v2); ECCurve_NameToCode.put( "c2tnb191v3", ECCurve_Code.c2tnb191v3); //ECCurve_NameToCode.put( // "c2onb191v4", ECCurve_Code.c2onb191v4); //ECCurve_NameToCode.put( // "c2onb191v5", ECCurve_Code.c2onb191v5); ECCurve_NameToCode.put( "c2pnb208w1", ECCurve_Code.c2pnb208w1); ECCurve_NameToCode.put( "c2tnb239v1", ECCurve_Code.c2tnb239v1); ECCurve_NameToCode.put( "c2tnb239v2", ECCurve_Code.c2tnb239v2); ECCurve_NameToCode.put( "c2tnb239v3", ECCurve_Code.c2tnb239v3); //ECCurve_NameToCode.put( // "c2onb239v4", ECCurve_Code.c2onb239v4); //ECCurve_NameToCode.put( // "c2onb239v5", ECCurve_Code.c2onb239v5); ECCurve_NameToCode.put( "c2pnb272w1", ECCurve_Code.c2pnb272w1); ECCurve_NameToCode.put( "c2pnb304w1", ECCurve_Code.c2pnb304w1); ECCurve_NameToCode.put( "c2tnb359v1", ECCurve_Code.c2tnb359v1); ECCurve_NameToCode.put( "c2pnb368w1", ECCurve_Code.c2pnb368w1); ECCurve_NameToCode.put( "c2tnb431r1", ECCurve_Code.c2tnb431r1); } // opFlag constants: each of these flags specifies a crypto operation // the key will support. Their values must match the same-named C // preprocessor macros defined in the PKCS #11 header pkcs11t.h. private static final int CKF_ENCRYPT = 0x00000100; private static final int CKF_DECRYPT = 0x00000200; private static final int CKF_SIGN = 0x00000800; private static final int CKF_SIGN_RECOVER = 0x00001000; private static final int CKF_VERIFY = 0x00002000; private static final int CKF_VERIFY_RECOVER = 0x00004000; private static final int CKF_WRAP = 0x00020000; private static final int CKF_UNWRAP = 0x00040000; private static final int CKF_DERIVE = 0x00080000; // A table for mapping SymmetricKey.Usage to opFlag. This must be // synchronized with SymmetricKey.Usage. private static final int opFlagForUsage[] = { CKF_ENCRYPT, /* 0 */ CKF_DECRYPT, /* 1 */ CKF_SIGN, /* 2 */ CKF_SIGN_RECOVER, /* 3 */ CKF_VERIFY, /* 4 */ CKF_VERIFY_RECOVER, /* 5 */ CKF_WRAP, /* 6 */ CKF_UNWRAP, /* 7 */ CKF_DERIVE /* 8 */ }; // The crypto operations the key will support. It is the logical OR // of the opFlag constants, each specifying a supported operation. private int opFlags = 0; private int opFlagsMask = 0; /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Constructor for PK11KeyPairGenerator. * @param token The PKCS #11 token that the keypair will be generated on. * @param algorithm The type of key that will be generated. Currently, * KeyPairAlgorithm.RSA , * KeyPairAlgorithm.DSA and * KeyPairAlgorithm.EC are supported. * @throws NoSuchAlgorithmException * @throws TokenException */ public PK11KeyPairGenerator(PK11Token token, KeyPairAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { Assert._assert(token!=null && algorithm!=null); mKeygenOnInternalToken = false; // Make sure we can do this kind of keygen if( ! token.doesAlgorithm(algorithm) ) { if( token.doesAlgorithm( algorithm.getAlgFamily() ) && token.isWritable() ) { // NSS will do the keygen on the internal module // and move the key to the token. We'll say this is // OK for now. mKeygenOnInternalToken = true; } else { throw new NoSuchAlgorithmException(); } } this.token = token; this.algorithm = algorithm; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Public Methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Initializes this KeyPairGenerator with the given key strength. * *

For DSA key generation, pre-cooked PQG values will be used * be used if the key size is 512, 768, or 1024. Otherwise, an * InvalidParameterException will be thrown. * * @param strength The strength (size) of the keys that will be generated. * @param random Ignored * @exception InvalidParameterException If the key strength is not * supported by the algorithm or this implementation. */ public void initialize(int strength, SecureRandom random) throws InvalidParameterException { if(algorithm == KeyPairAlgorithm.RSA) { params = new RSAParameterSpec(strength, DEFAULT_RSA_PUBLIC_EXPONENT); } else if(algorithm == KeyPairAlgorithm.DSA) { if(strength==512) { params = PQG512; } else if(strength==768) { params = PQG768; } else if(strength==1024) { params = PQG1024; } else { throw new InvalidParameterException( "In order to use pre-cooked PQG values, key strength must"+ "be 512, 768, or 1024."); } } else { Assert._assert( algorithm == KeyPairAlgorithm.EC ); if (strength < 112) { // for EC, "strength" is actually a code for curves defined in // ECCurve_Code params = getECCurve(strength); } else { // this is the old method of strength to curve mapping, // which is somewhat defective params = getCurve(strength); } } } /** * Initializes this KeyPairGenerator with the given algorithm-specific * parameters. * * @param params The algorithm-specific parameters that will govern * key pair generation. * @param random Ignored * @throws InvalidAlgorithmParameterException If the parameters * are inappropriate for the key type or are not supported by * this implementation. */ public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if(params == null) { Assert.notReached("Don't pass in null parameters"); throw new InvalidAlgorithmParameterException(); } if(algorithm == KeyPairAlgorithm.RSA) { if(! (params instanceof RSAParameterSpec) ) { throw new InvalidAlgorithmParameterException(); } // Security library stores public exponent in an unsigned long if( ((RSAParameterSpec)params).getPublicExponent().bitLength() > 31) { throw new InvalidAlgorithmParameterException( "RSA Public Exponent must fit in 31 or fewer bits."); } } else if ( algorithm == KeyPairAlgorithm.DSA ){ if(! (params instanceof DSAParameterSpec) ) { throw new InvalidAlgorithmParameterException(); } } else { Assert._assert( algorithm == KeyPairAlgorithm.EC); // requires JAVA 1.5 // if(! (params instanceof ECParameterSpec) ) { // throw new InvalidAlgorithmParameterException(); //} // requires JAVA 1.5 if(! (params instanceof PK11ParameterSpec) ) { throw new InvalidAlgorithmParameterException(); } } // future add support for X509EncodedSpec this.params = params; } /** * Generates a key pair on a token. Uses parameters if they were passed * in through a call to initialize, otherwise uses defaults. * @return * @throws TokenException */ public KeyPair generateKeyPair() throws TokenException { if(algorithm == KeyPairAlgorithm.RSA) { if(params != null) { RSAParameterSpec rsaparams = (RSAParameterSpec)params; return generateRSAKeyPairWithOpFlags( token, rsaparams.getKeySize(), rsaparams.getPublicExponent().longValue(), temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } else { return generateRSAKeyPairWithOpFlags( token, DEFAULT_RSA_KEY_SIZE, DEFAULT_RSA_PUBLIC_EXPONENT.longValue(), temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } } else if(algorithm == KeyPairAlgorithm.DSA ) { if(params==null) { params = PQG1024; } DSAParameterSpec dsaParams = (DSAParameterSpec)params; return generateDSAKeyPairWithOpFlags( token, PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getP()), PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getQ()), PQGParams.BigIntegerToUnsignedByteArray(dsaParams.getG()), temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } else { Assert._assert( algorithm == KeyPairAlgorithm.EC ); // requires JAVA 1.5 for ECParameters. // //AlgorithmParameters ecParams = // AlgorithmParameters.getInstance("ECParameters"); // ecParams.init(params); PK11ParameterSpec ecParams = (PK11ParameterSpec) params; return generateECKeyPairWithOpFlags( token, ecParams.getEncoded(), /* curve */ temporaryPairMode, sensitivePairMode, extractablePairMode, opFlags, opFlagsMask); } } /** * @return true if the keypair generation will be done on the * internal token and then moved to this token. */ public boolean keygenOnInternalToken() { return mKeygenOnInternalToken; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Native Implementation Methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Generates an RSA key pair with the given size and public exponent. */ private native KeyPair generateRSAKeyPair(PK11Token token, int keySize, long publicExponent, boolean temporary, int sensitive, int extractable) throws TokenException; /** * Generates an RSA key pair with the given size and public exponent. * Adds the ability to specify a set of flags and masks * to control how NSS generates the key pair. */ private native KeyPair generateRSAKeyPairWithOpFlags(PK11Token token, int keySize, long publicExponent, boolean temporary, int sensitive, int extractable, int op_flags, int op_flags_mask) throws TokenException; /** * Generates a DSA key pair with the given P, Q, and G values. * P, Q, and G are stored as big-endian twos-complement octet strings. */ private native KeyPair generateDSAKeyPair(PK11Token token, byte[] P, byte[] Q, byte[] G, boolean temporary, int sensitive, int extractable) throws TokenException; /** * Generates a DSA key pair with the given P, Q, and G values. * P, Q, and G are stored as big-endian twos-complement octet strings. * Adds the ability to specify a set of flags and masks * to control how NSS generates the key pair. */ private native KeyPair generateDSAKeyPairWithOpFlags(PK11Token token, byte[] P, byte[] Q, byte[] G, boolean temporary, int sensitive, int extractable, int op_flags, int op_flags_mask) throws TokenException; /** * Generates a EC key pair with the given a curve. * Curves are stored as DER Encoded Parameters. */ private native KeyPair generateECKeyPair(PK11Token token, byte[] Curve, boolean temporary, int sensitive, int extractable) throws TokenException; /** * Generates a EC key pair with the given a curve. * Curves are stored as DER Encoded Parameters. * Adds the ability to specify a set of flags and masks * to control how NSS generates the key pair. */ private native KeyPair generateECKeyPairWithOpFlags(PK11Token token, byte[] Curve, boolean temporary, int sensitive, int extractable, int op_flags, int op_flags_mask) throws TokenException; /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Defaults /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static final int DEFAULT_RSA_KEY_SIZE = 2048; private static final BigInteger DEFAULT_RSA_PUBLIC_EXPONENT = BigInteger.valueOf(65537); ////////////////////////////////////////////////////////////////////// // 1024-bit PQG parameters // These were generated and verified using the // org.mozilla.jss.crypto.PQGParams class. ////////////////////////////////////////////////////////////////////// private static final String p1024= "135839652435190934085800139191680301864221874900900696919010316554114342871389066526982023513828891845682496590926522957486592076092819515303251959435284578074745022943475516750500021440278782993316814165831392449756706958779266394680687474113495272524355075654433600922751920548192539119568200162784715902571"; private static final String q1024= "1289225024022202541601051225376429063716419728261"; private static final String g1024= "9365079229044517973775853147905914670746128595481021901304748201231245287028018351117994470223961367498481071639148009750748608477086914440940765659773400233006204556380834403997210445996745757996115285802608489502160956380238739417382954486304730446079375880915926936667959108637040861595671319957190194969"; private static final String h1024= "52442921523337940900621893014039829709890959980326720828933601226740749524581606283131306291278616835323956710592993182613544059214633911716533418368425327413628234095671352084418677611348898811691107611640282098605730539089258655659910952545940615065321018163879856499128636989240131903260975031351698627473"; private static final String seed1024= "99294487279227522120410987308721952265545668206337642687581596155167227884587528576179879564731162765515189527566190299324927751299864501359105446993895763527646668003992063667962831489586752303126546478655915858883436326503676798267446073013163508014466163441488290854738816489359449082537210762470653355837"; private static final int counter1024 = 159; /** * Pre-cooked PQG values for 1024-bit keypairs, along with the seed, * counter, and H values needed to verify them. */ public static final PQGParams PQG1024 = new PQGParams( new BigInteger(p1024), new BigInteger(q1024), new BigInteger(g1024), new BigInteger(seed1024), counter1024, new BigInteger(h1024)); ////////////////////////////////////////////////////////////////////// // 768-bit PQG parameters // These were generated and verified using the // org.mozilla.jss.crypto.PQGParams class. ////////////////////////////////////////////////////////////////////// private static final String p768 = "1334591549939035619289567230283054603122655003980178118026955029363553392594293499178687789871628588392413078786977899109276604404053531960657701920766542891720144660923735290663050045086516783083489369477138289683344192203747015183"; private static final String q768 = "1356132865877303155992130272917916166541739006871"; private static final String g768 = "1024617924160404238802957719732914916383807485923819254303813897112921288261546213295904612554364830820266594592843780972915270096284099079324418834215265083315386166747220804977600828688227714319518802565604893756612386174125343163"; private static final String seed768 = "818335465751997015393064637168438154352349887221925302425470688493624428407506863871577128315308555744979456856342994235252156194662586703244255741598129996211081771019031721876068721218509213355334043303099174315838637885951947797"; private static final int counter768 = 80; private static final String h768 = "640382699969409389484886950168366372251172224987648937408021020040753785108834000620831523080773231719549705102680417704245010958792653770817759388668805215557594892534053348624875390588773257372677159854630106242075665177245698591"; /** * Pre-cooked PQG values for 768-bit keypairs, along with the seed, * counter, and H values needed to verify them. */ public static final PQGParams PQG768 = new PQGParams( new BigInteger(p768), new BigInteger(q768), new BigInteger(g768), new BigInteger(seed768), counter768, new BigInteger(h768)); ////////////////////////////////////////////////////////////////////// // 512-bit PQG parameters // These were generated and verified using the // org.mozilla.jss.crypto.PQGParams class. ////////////////////////////////////////////////////////////////////// private static final String p512 = "6966483207285155416780416172202915863379050665227482416115451434656043093992853756903066653962454938528584622842487778598918381346739078775480034378802841"; private static final String q512 = "1310301134281640075932276656367326462518739803527"; private static final String g512 = "1765808308320938820731237312304158486199455718816858489736043318496656574508696475222741642343469219895005992985361010111736160340009944528784078083324884"; private static final String h512 = "1166033533097555931825481846268490827226947692615252570752313574243187654088977281409544725210974913958636100321681636002587474728477655589742540645702652"; private static final String seed512 = "1823071686803672528716836609217295942310764795778335243232708299998660956064222751939859670873282519585591423918449571513004815205037154878988595168291600"; private static final int counter512 = 186; /** * Pre-cooked PQG values for 512-bit keypairs, along with the seed, * counter, and H values needed to verify them. */ public static final PQGParams PQG512 = new PQGParams( new BigInteger(p512), new BigInteger(q512), new BigInteger(g512), new BigInteger(seed512), counter512, new BigInteger(h512)); /////////////////////////////////////////////////////////////////////// // Test the PQG parameters /////////////////////////////////////////////////////////////////////// private static boolean defaultsTested = false; private static synchronized void testDefaults() { if(Debug.DEBUG && !defaultsTested) { Assert._assert(PQG1024.paramsAreValid()); Assert._assert(PQG768.paramsAreValid()); Assert._assert(PQG512.paramsAreValid()); defaultsTested = true; } } public void temporaryPairs(boolean temp) { temporaryPairMode = temp; } public void sensitivePairs(boolean sensitive) { sensitivePairMode = sensitive ? 1 : 0; } public void extractablePairs(boolean extractable) { extractablePairMode = extractable ? 1 : 0; } /** * Sets the requested key usages desired for the * generated key pair. * This allows the caller to suggest how NSS generates the key pair. * @param usages List of desired key usages. * @param usages_mask Corresponding mask for the key usages. * if a usages is desired, make sure it is in the mask as well. */ public void setKeyPairUsages(org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usages, org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage[] usages_mask) { this.opFlags = 0; this.opFlagsMask = 0; if(usages != null) { for( int i = 0; i < usages.length; i++ ) { if( usages[i] != null ) { this.opFlags |= opFlagForUsage[usages[i].getVal()]; } } } if(usages_mask != null) { for( int i = 0; i < usages_mask.length; i++ ) { if( usages_mask[i] != null ) { this.opFlagsMask |= opFlagForUsage[usages_mask[i].getVal()]; } } } } // // requires JAVA 1.5 // //private AlgorithmParameterSpec getCurve(int strength) { //} private static final OBJECT_IDENTIFIER ANSI_X962_PRIME_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045, 3, 1 } ); private static final OBJECT_IDENTIFIER ANSI_X962_BINARY_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 2, 840, 10045, 3, 0 } ); private static final OBJECT_IDENTIFIER SECG_EC_CURVE = new OBJECT_IDENTIFIER( new long[] { 1, 3, 132, 0 } ); // ANSI Prime curves static final OBJECT_IDENTIFIER CURVE_ANSI_P192V1 = ANSI_X962_PRIME_CURVE.subBranch(1); static final OBJECT_IDENTIFIER CURVE_ANSI_P192V2 = ANSI_X962_PRIME_CURVE.subBranch(2); static final OBJECT_IDENTIFIER CURVE_ANSI_P192V3 = ANSI_X962_PRIME_CURVE.subBranch(3); static final OBJECT_IDENTIFIER CURVE_ANSI_P239V1 = ANSI_X962_PRIME_CURVE.subBranch(4); static final OBJECT_IDENTIFIER CURVE_ANSI_P239V2 = ANSI_X962_PRIME_CURVE.subBranch(5); static final OBJECT_IDENTIFIER CURVE_ANSI_P239V3 = ANSI_X962_PRIME_CURVE.subBranch(6); static final OBJECT_IDENTIFIER CURVE_ANSI_P256V1 = ANSI_X962_PRIME_CURVE.subBranch(7); // ANSI Binary curves static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V1 =ANSI_X962_BINARY_CURVE.subBranch(1); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V2 =ANSI_X962_BINARY_CURVE.subBranch(2); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB163V3 =ANSI_X962_BINARY_CURVE.subBranch(3); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB176V1 =ANSI_X962_BINARY_CURVE.subBranch(4); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V1 =ANSI_X962_BINARY_CURVE.subBranch(5); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V2 =ANSI_X962_BINARY_CURVE.subBranch(6); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB191V3 =ANSI_X962_BINARY_CURVE.subBranch(7); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB191V4 =ANSI_X962_BINARY_CURVE.subBranch(8); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB191V5 =ANSI_X962_BINARY_CURVE.subBranch(9); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB208W1 =ANSI_X962_BINARY_CURVE.subBranch(10); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V1 =ANSI_X962_BINARY_CURVE.subBranch(11); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V2 =ANSI_X962_BINARY_CURVE.subBranch(12); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB239V3 =ANSI_X962_BINARY_CURVE.subBranch(13); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB239V4 =ANSI_X962_BINARY_CURVE.subBranch(14); static final OBJECT_IDENTIFIER CURVE_ANSI_ONB239V5 =ANSI_X962_BINARY_CURVE.subBranch(15); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB272W1 =ANSI_X962_BINARY_CURVE.subBranch(16); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB304W1 =ANSI_X962_BINARY_CURVE.subBranch(17); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB359V1 =ANSI_X962_BINARY_CURVE.subBranch(18); static final OBJECT_IDENTIFIER CURVE_ANSI_PNB368W1 =ANSI_X962_BINARY_CURVE.subBranch(19); static final OBJECT_IDENTIFIER CURVE_ANSI_TNB431R1 =ANSI_X962_BINARY_CURVE.subBranch(20); // SEG Prime curves static final OBJECT_IDENTIFIER CURVE_SECG_P112R1 = SECG_EC_CURVE.subBranch(6); static final OBJECT_IDENTIFIER CURVE_SECG_P112R2 = SECG_EC_CURVE.subBranch(7); static final OBJECT_IDENTIFIER CURVE_SECG_P128R1 = SECG_EC_CURVE.subBranch(28); static final OBJECT_IDENTIFIER CURVE_SECG_P128R2 = SECG_EC_CURVE.subBranch(29); static final OBJECT_IDENTIFIER CURVE_SECG_P160K1 = SECG_EC_CURVE.subBranch(9); static final OBJECT_IDENTIFIER CURVE_SECG_P160R1 = SECG_EC_CURVE.subBranch(8); static final OBJECT_IDENTIFIER CURVE_SECG_P160R2 = SECG_EC_CURVE.subBranch(30); static final OBJECT_IDENTIFIER CURVE_SECG_P192K1 = SECG_EC_CURVE.subBranch(31); static final OBJECT_IDENTIFIER CURVE_SECG_P224K1 = SECG_EC_CURVE.subBranch(32); static final OBJECT_IDENTIFIER CURVE_SECG_P224R1 = SECG_EC_CURVE.subBranch(33); static final OBJECT_IDENTIFIER CURVE_SECG_P256K1 = SECG_EC_CURVE.subBranch(10); static final OBJECT_IDENTIFIER CURVE_SECG_P384R1 = SECG_EC_CURVE.subBranch(34); static final OBJECT_IDENTIFIER CURVE_SECG_P521R1 = SECG_EC_CURVE.subBranch(35); // SEG Binary curves static final OBJECT_IDENTIFIER CURVE_SECG_T113R1 = SECG_EC_CURVE.subBranch(4); static final OBJECT_IDENTIFIER CURVE_SECG_T113R2 = SECG_EC_CURVE.subBranch(5); static final OBJECT_IDENTIFIER CURVE_SECG_T131R1 = SECG_EC_CURVE.subBranch(22); static final OBJECT_IDENTIFIER CURVE_SECG_T131R2 = SECG_EC_CURVE.subBranch(23); static final OBJECT_IDENTIFIER CURVE_SECG_T163K1 = SECG_EC_CURVE.subBranch(1); static final OBJECT_IDENTIFIER CURVE_SECG_T163R1 = SECG_EC_CURVE.subBranch(2); static final OBJECT_IDENTIFIER CURVE_SECG_T163R2 = SECG_EC_CURVE.subBranch(15); static final OBJECT_IDENTIFIER CURVE_SECG_T193R1 = SECG_EC_CURVE.subBranch(24); static final OBJECT_IDENTIFIER CURVE_SECG_T193R2 = SECG_EC_CURVE.subBranch(25); static final OBJECT_IDENTIFIER CURVE_SECG_T233K1 = SECG_EC_CURVE.subBranch(26); static final OBJECT_IDENTIFIER CURVE_SECG_T233R1 = SECG_EC_CURVE.subBranch(27); static final OBJECT_IDENTIFIER CURVE_SECG_T239K1 = SECG_EC_CURVE.subBranch(3); static final OBJECT_IDENTIFIER CURVE_SECG_T283K1 = SECG_EC_CURVE.subBranch(16); static final OBJECT_IDENTIFIER CURVE_SECG_T283R1 = SECG_EC_CURVE.subBranch(17); static final OBJECT_IDENTIFIER CURVE_SECG_T409K1 = SECG_EC_CURVE.subBranch(36); static final OBJECT_IDENTIFIER CURVE_SECG_T409R1 = SECG_EC_CURVE.subBranch(37); static final OBJECT_IDENTIFIER CURVE_SECG_T571K1 = SECG_EC_CURVE.subBranch(38); static final OBJECT_IDENTIFIER CURVE_SECG_T571R1 = SECG_EC_CURVE.subBranch(39); // the EC curvecode to oid hash table private static Hashtable mECCurve_CodeToCurve = new Hashtable(); static { // SEG Prime curves mECCurve_CodeToCurve.put( ECCurve_Code.secp521r1.ordinal(), (Object) CURVE_SECG_P521R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp521.ordinal(), (Object) CURVE_SECG_P521R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp384r1.ordinal(), (Object) CURVE_SECG_P384R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp384.ordinal(), (Object) CURVE_SECG_P384R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp256r1.ordinal(), (Object) CURVE_ANSI_P256V1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp256.ordinal(), (Object) CURVE_ANSI_P256V1); mECCurve_CodeToCurve.put( ECCurve_Code.secp256k1.ordinal(), (Object) CURVE_SECG_P256K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp224r1.ordinal(), (Object) CURVE_SECG_P224R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp224.ordinal(), (Object) CURVE_SECG_P224R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp224k1.ordinal(), (Object) CURVE_SECG_P224K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp192r1.ordinal(), (Object) CURVE_ANSI_P192V1); mECCurve_CodeToCurve.put( ECCurve_Code.nistp192.ordinal(), (Object) CURVE_ANSI_P192V1); mECCurve_CodeToCurve.put( ECCurve_Code.secp192k1.ordinal(), (Object) CURVE_SECG_P192K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp160r2.ordinal(), (Object) CURVE_SECG_P160R2); mECCurve_CodeToCurve.put( ECCurve_Code.secp160r1.ordinal(), (Object) CURVE_SECG_P160R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp160k1.ordinal(), (Object) CURVE_SECG_P160K1); mECCurve_CodeToCurve.put( ECCurve_Code.secp128r2.ordinal(), (Object) CURVE_SECG_P128R2); mECCurve_CodeToCurve.put( ECCurve_Code.secp128r1.ordinal(), (Object) CURVE_SECG_P128R1); mECCurve_CodeToCurve.put( ECCurve_Code.secp112r2.ordinal(), (Object) CURVE_SECG_P112R2); mECCurve_CodeToCurve.put( ECCurve_Code.secp112r1.ordinal(), (Object) CURVE_SECG_P112R1); // SEG Binary curves mECCurve_CodeToCurve.put( ECCurve_Code.sect571r1.ordinal(), (Object) CURVE_SECG_T571R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb571.ordinal(), (Object) CURVE_SECG_T571R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect571k1.ordinal(), (Object) CURVE_SECG_T571K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk571.ordinal(), (Object) CURVE_SECG_T571K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect409r1.ordinal(), (Object) CURVE_SECG_T409R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb409.ordinal(), (Object) CURVE_SECG_T409R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect409k1.ordinal(), (Object) CURVE_SECG_T409K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk409.ordinal(), (Object) CURVE_SECG_T409K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect283r1.ordinal(), (Object) CURVE_SECG_T283R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb283.ordinal(), (Object) CURVE_SECG_T283R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect283k1.ordinal(), (Object) CURVE_SECG_T283K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk283.ordinal(), (Object) CURVE_SECG_T283K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect239k1.ordinal(), (Object) CURVE_SECG_T239K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect233r1.ordinal(), (Object) CURVE_SECG_T233R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb233.ordinal(), (Object) CURVE_SECG_T233R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect233k1.ordinal(), (Object) CURVE_SECG_T233K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk233.ordinal(), (Object) CURVE_SECG_T233K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect193r2.ordinal(), (Object) CURVE_SECG_T193R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect193r1.ordinal(), (Object) CURVE_SECG_T193R1); mECCurve_CodeToCurve.put( ECCurve_Code.nistb163.ordinal(), (Object) CURVE_SECG_T163K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect163r2.ordinal(), (Object) CURVE_SECG_T163R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect163r1.ordinal(), (Object) CURVE_SECG_T163R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect163k1.ordinal(), (Object) CURVE_SECG_T163K1); mECCurve_CodeToCurve.put( ECCurve_Code.nistk163.ordinal(), (Object) CURVE_SECG_T163K1); mECCurve_CodeToCurve.put( ECCurve_Code.sect131r2.ordinal(), (Object) CURVE_SECG_T131R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect131r1.ordinal(), (Object) CURVE_SECG_T131R1); mECCurve_CodeToCurve.put( ECCurve_Code.sect113r2.ordinal(), (Object) CURVE_SECG_T113R2); mECCurve_CodeToCurve.put( ECCurve_Code.sect113r1.ordinal(), (Object) CURVE_SECG_T113R1); // ANSI Prime curves mECCurve_CodeToCurve.put( ECCurve_Code.prime239v3.ordinal(), (Object) CURVE_ANSI_P239V3); mECCurve_CodeToCurve.put( ECCurve_Code.prime239v2.ordinal(), (Object) CURVE_ANSI_P239V2); mECCurve_CodeToCurve.put( ECCurve_Code.prime239v1.ordinal(), (Object) CURVE_ANSI_P239V1); mECCurve_CodeToCurve.put( ECCurve_Code.prime192v3.ordinal(), (Object) CURVE_ANSI_P192V3); mECCurve_CodeToCurve.put( ECCurve_Code.prime192v2.ordinal(), (Object) CURVE_ANSI_P192V2); mECCurve_CodeToCurve.put( ECCurve_Code.prime192v1.ordinal(), (Object) CURVE_ANSI_P192V1); // ANSI Binary curves mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb163v1.ordinal(), (Object) CURVE_ANSI_PNB163V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb163v2.ordinal(), (Object) CURVE_ANSI_PNB163V2); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb163v3.ordinal(), (Object) CURVE_ANSI_PNB163V3); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb176v1.ordinal(), (Object) CURVE_ANSI_PNB176V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb191v1.ordinal(), (Object) CURVE_ANSI_TNB191V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb191v2.ordinal(), (Object) CURVE_ANSI_TNB191V2); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb191v3.ordinal(), (Object) CURVE_ANSI_TNB191V3); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb191v4.ordinal(), (Object) CURVE_ANSI_ONB191V4); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb191v5.ordinal(), (Object) CURVE_ANSI_ONB191V5); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb208w1.ordinal(), (Object) CURVE_ANSI_PNB208W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb239v1.ordinal(), (Object) CURVE_ANSI_TNB239V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb239v2.ordinal(), (Object) CURVE_ANSI_TNB239V2); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb239v3.ordinal(), (Object) CURVE_ANSI_TNB239V3); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb239v4.ordinal(), (Object) CURVE_ANSI_ONB239V4); //mECCurve_CodeToCurve.put( // ECCurve_Code.c2onb239v5.ordinal(), (Object) CURVE_ANSI_ONB239V5); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb272w1.ordinal(), (Object) CURVE_ANSI_PNB272W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb304w1.ordinal(), (Object) CURVE_ANSI_PNB304W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb359v1.ordinal(), (Object) CURVE_ANSI_TNB359V1); mECCurve_CodeToCurve.put( ECCurve_Code.c2pnb368w1.ordinal(), (Object) CURVE_ANSI_PNB368W1); mECCurve_CodeToCurve.put( ECCurve_Code.c2tnb431r1.ordinal(), (Object) CURVE_ANSI_TNB431R1); } public int getCurveCodeByName(String curveName) throws InvalidParameterException { if (curveName == null) throw new InvalidParameterException(); ECCurve_Code c = (ECCurve_Code) ECCurve_NameToCode.get(curveName); if (c == null) throw new InvalidParameterException(curveName); return c.ordinal(); } /* * getECCurve * maps curvecode to the actual oid of the curve and * returns the PK11ParameterSpec */ private AlgorithmParameterSpec getECCurve(int curvecode) throws InvalidParameterException { OBJECT_IDENTIFIER oid; oid = (OBJECT_IDENTIFIER) mECCurve_CodeToCurve.get(curvecode); if (oid == null) throw new IllegalArgumentException("curvecode ="+curvecode); return new PK11ParameterSpec(ASN1Util.encode(oid)); } private AlgorithmParameterSpec getCurve(int strength) throws InvalidParameterException { OBJECT_IDENTIFIER oid; switch (strength) { case 112: oid = CURVE_SECG_P112R1; // == WTLS-6 // Can't get to curve SECG P-112R2 // Can't get to curve WTLS-8 (No oid for WTLS-8) break; case 113: oid = CURVE_SECG_T113R1; // == WTLS-4 // Can't get to curve SECG T-113R2 // Can't get to curve WTLS-1 (No oid for WTLS-1) break; case 128: oid = CURVE_SECG_P128R1; // Can't get to curve SECG P-128R2 break; case 131: oid = CURVE_SECG_T131R1; // Can't get to curve SECG T-131R2 break; case 160: oid = CURVE_SECG_P160R1; // == WTLS-7 (TLS-16) // Can't get to curve SECG P-160K1 (TLS-15) // Can't get to curve SECG P-160R2 (TLS-17) // Can't get to curve WTLS-9 (No oid for WTLS-9) break; case 163: oid = CURVE_SECG_T163K1; // == NIST K-163 == WTLS-3 (TLS-1) // Can't get to curve ANSI C2-PNB163V1 == WTLS-5 // Can't get to curve ANSI C2-PNB163V2 // Can't get to curve ANSI C2-PNB163V3 // Can't get to curve SECG T-163R1 (TLS-2) // Can't get to curve SECG T-163R2 == NIST B-163 (TLS-3) break; case 176: oid = CURVE_ANSI_PNB176V1; break; case 191: oid = CURVE_ANSI_TNB191V1; // Can't get to curve ANSI C2-TNB191V2 // Can't get to curve ANSI C2-TNB191V3 // Can't get to curve ANSI C2-ONB191V4 // Can't get to curve ANSI C2-ONB191V5 break; case 192: oid = CURVE_ANSI_P192V1; // == NIST P-192 == SECG P-192R1 (TLS-19) // Can't get to curve ANSI P-192V2 // Can't get to curve ANSI P-192V3 // Can't get to curve SECG P-192K1 (TLS-18) break; case 193: oid = CURVE_SECG_T193R1; // (TLS-4) // Can't get to curve SECG T-193R2 // (TLS-5) break; case 208: oid = CURVE_ANSI_PNB208W1; break; case 224: oid = CURVE_SECG_P224R1; // == NIST P-224 == WTLS-12 (TLS-21) // Can't get to curve SECG P-224K1 (TLS-20) break; case 233: oid = CURVE_SECG_T233R1; // == NIST B-233 == WTLS-11 (TLS-7) // Can't get to curve SECG T-233K1 == NIST K-233 == WTLS-10 (TLS-6) break; case 239: oid = CURVE_SECG_T239K1; // (TLS8) // Can't get to curve ANSI P-239V1 // Can't get to curve ANSI P-239V2 // Can't get to curve ANSI P-239V3 // Can't get to curve ANSI C2-TNB239V1 // Can't get to curve ANSI C2-TNB239V2 // Can't get to curve ANSI C2-TNB239V3 // Can't get to curve ANSI C2-ONB239V4 // Can't get to curve ANSI C2-ONB239V5 break; case 256: oid = CURVE_ANSI_P256V1; // == NIST P-256 == SECG P-256R1 (TLS-23) // Can't get to curve SECG P-256K1 (TLS-22) break; case 272: oid = CURVE_ANSI_PNB272W1; break; case 283: oid = CURVE_SECG_T283R1; // == NIST B-283 (TLS-10) // Can't get to curve SECG T-283K1 == NIST K-283 (TLS-9) break; case 304: oid = CURVE_ANSI_PNB304W1; break; case 359: oid = CURVE_ANSI_TNB359V1; break; case 368: oid = CURVE_ANSI_PNB368W1; break; case 384: oid = CURVE_SECG_P384R1; // == NIST P-384 (TLS-24) break; case 409: oid = CURVE_SECG_T409R1; // == NIST B-409 (TLS-12) // Can't get to curve SECG T-409K1 == NIST K-409 (TLS-11) break; case 431: oid = CURVE_ANSI_TNB431R1; break; case 521: oid = CURVE_SECG_P521R1; // == NIST P-521 (TLS-25) break; case 571: oid = CURVE_SECG_T571R1; // == NIST B-571 (TLS-14) // Can't get to curve SECG T-571K1 == NIST K-571 (TLS-13) break; default: throw new InvalidParameterException(); } return new PK11ParameterSpec(ASN1Util.encode(oid)); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Private members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private PK11Token token; private AlgorithmParameterSpec params; private KeyPairAlgorithm algorithm; private boolean mKeygenOnInternalToken; private boolean temporaryPairMode = false; // 1: sensitive // 0: insensitive // -1: sensitive if temporaryPairMode is false, // insensitive if temporaryPairMode is true // (the default depends on temporaryPairMode for backward // compatibility) private int sensitivePairMode = -1; // 1: extractable // 0: unextractable // -1: unspecified (token dependent) private int extractablePairMode = -1; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c000066400000000000000000000615031326145000000221050ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11KeyWrapper.h" #include #include #include #include #include #include /* JSS includes */ #include #include #include #include #include #define MAX_PRIVATE_KEY_LEN MAX_RSA_MODULUS_LEN /* * This is bytes, not bits. A 2048-bit wrapped RSA private key takes up around * 1200 bytes, because lots of "helper" values are stored along with the * modulus and exponent. 4096 bytes will hold at least a 4096-bit RSA key. */ #define MAX_WRAPPED_KEY_LEN 4096 /*********************************************************************** * * PK11KeyWrapper.nativeWrapSymWithSym */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithSym (JNIEnv *env, jobject this, jobject tokenObj, jobject toBeWrappedObj, jobject wrappingKeyObj, jobject algObj, jbyteArray ivBA) { PK11SymKey *wrapping = NULL; PK11SymKey *toBeWrapped = NULL; CK_MECHANISM_TYPE mech; SECItem wrapped; jbyteArray wrappedBA=NULL; SECItem *iv=NULL, *param=NULL; SECStatus status; /* initialize so we can goto finish */ wrapped.data = NULL; wrapped.len = 0; /* get wrapping key */ if( JSS_PK11_getSymKeyPtr(env, wrappingKeyObj, &wrapping)!= PR_SUCCESS) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "wrapping key"); return NULL; } /* get toBeWrapped key */ if( JSS_PK11_getSymKeyPtr(env, toBeWrappedObj, &toBeWrapped) != PR_SUCCESS){ JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "to be wrapped key"); return NULL; } /* get the mechanism */ mech = JSS_getPK11MechFromAlg(env, algObj); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized algorithm"); goto finish; } /* get the parameter */ if( ivBA ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(mech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to create mechanism" " parameter from initialization vector"); goto finish; } } /* setup space for wrapped key */ wrapped.len = MAX_WRAPPED_KEY_LEN; /* yuk! */ wrapped.data = PR_Malloc(wrapped.len); if(wrapped.data == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* perform the wrap */ status = PK11_WrapSymKey(mech, param, wrapping, toBeWrapped, &wrapped); if( status != SECSuccess ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Wrap operation failed on token"); goto finish; } /* package the wrapped data into a byte array */ wrappedBA = JSS_SECItemToByteArray(env, &wrapped); finish: if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*freeit*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*freeit*/); } SECITEM_FreeItem(&wrapped, PR_FALSE /*freeit*/); return wrappedBA; } /*********************************************************************** * * PK11KeyWrapper.nativeWrapSymWithPub */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapSymWithPub (JNIEnv *env, jobject this, jobject tokenObj, jobject toBeWrappedObj, jobject wrappingKeyObj, jobject algObj, jbyteArray ivBA) { SECKEYPublicKey *wrapping = NULL; PK11SymKey *toBeWrapped = NULL; CK_MECHANISM_TYPE mech; SECItem wrapped; jbyteArray wrappedBA=NULL; SECStatus status; /* initialize so we can goto finish */ wrapped.data = NULL; wrapped.len = 0; /* get wrapping key */ if( JSS_PK11_getPubKeyPtr(env, wrappingKeyObj, &wrapping)!= PR_SUCCESS) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract public " "wrapping key"); return NULL; } /* get toBeWrapped key */ if( JSS_PK11_getSymKeyPtr(env, toBeWrappedObj, &toBeWrapped) != PR_SUCCESS){ JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "to be wrapped key"); return NULL; } /* get the mechanism */ mech = JSS_getPK11MechFromAlg(env, algObj); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized algorithm"); goto finish; } /* setup space for wrapped key */ wrapped.len = MAX_WRAPPED_KEY_LEN; /* yuk! */ wrapped.data = PR_Malloc(wrapped.len); if(wrapped.data == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* perform the wrap */ status = PK11_PubWrapSymKey(mech, wrapping, toBeWrapped, &wrapped); if( status != SECSuccess ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Wrap operation failed on token"); goto finish; } /* package the wrapped data into a byte array */ wrappedBA = JSS_SECItemToByteArray(env, &wrapped); finish: SECITEM_FreeItem(&wrapped, PR_FALSE /*freeit*/); return wrappedBA; } /*********************************************************************** * * PK11KeyWrapper.nativeWrapPrivWithSym */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeWrapPrivWithSym (JNIEnv *env, jobject this, jobject tokenObj, jobject toBeWrappedObj, jobject wrappingKeyObj, jobject algObj, jbyteArray ivBA) { PK11SymKey *wrapping = NULL; SECKEYPrivateKey *toBeWrapped= NULL; CK_MECHANISM_TYPE mech; SECStatus status; SECItem wrapped; PK11SlotInfo *slot=NULL; jbyteArray wrappedBA=NULL; SECItem *iv=NULL, *param=NULL; /* setup space for wrapped key */ wrapped.len = MAX_WRAPPED_KEY_LEN; wrapped.data = PR_Malloc(wrapped.len); if(wrapped.data == NULL) { wrapped.len = 0; JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* get wrapping key */ if( JSS_PK11_getSymKeyPtr(env, wrappingKeyObj, &wrapping) != PR_SUCCESS) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract symmetric " "wrapping key"); return NULL; } /* get toBeWrapped key */ if( JSS_PK11_getPrivKeyPtr(env, toBeWrappedObj, &toBeWrapped) !=PR_SUCCESS){ JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract private " "to be wrapped key"); return NULL; } /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the mechanism */ mech = JSS_getPK11MechFromAlg(env, algObj); if(mech == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized algorithm"); goto finish; } /* get the mechanism parameter (IV) */ if( ivBA ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(mech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* perform the wrap operation */ status = PK11_WrapPrivKey(slot, wrapping, toBeWrapped, mech, param, &wrapped, NULL /* wincx */ ); if(status != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Wrapping operation failed on token"); goto finish; } PR_ASSERT(wrapped.len>0 && wrapped.data!=NULL); /* package the wrapped data into a byte array */ wrappedBA = JSS_SECItemToByteArray(env, &wrapped); /* fall through if an exception occurs */ finish: if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*freeit*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*freeit*/); } SECITEM_FreeItem(&wrapped, PR_FALSE /*freeit*/); return wrappedBA; } /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapPrivWithSym */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapPrivWithSym (JNIEnv *env, jclass clazz, jobject tokenObj, jobject unwrapperObj, jbyteArray wrappedBA, jobject wrapAlgObj, jobject typeAlgObj, jbyteArray publicValueBA, jbyteArray ivBA, jboolean temporary) { PK11SlotInfo *slot; PK11SymKey *unwrappingKey; SECKEYPrivateKey *privk=NULL; jobject privkObj=NULL; CK_MECHANISM_TYPE wrapType, keyTypeMech; CK_KEY_TYPE keyType; SECItem *wrapped=NULL, *iv=NULL, *param=NULL, *pubValue=NULL; SECItem label; /* empty secitem, doesn't need to be freed */ PRBool token; CK_ATTRIBUTE_TYPE attribs[4] = {0, 0, 0, 0}; int numAttribs = 0; CK_TOKEN_INFO tokenInfo; /* ideal defaults */ PRBool isSensitive = PR_TRUE; PRBool isExtractable = PR_FALSE; /* special case nethsm and lunasa*/ const int numManufacturerIDchars = 7; CK_UTF8CHAR nethsmManufacturerID[] = {'n','C','i','p','h','e','r'}; CK_UTF8CHAR lunasaManufacturerID[] = {'S','a','f','e','n','e','t'}; PRBool isNethsm = PR_TRUE; PRBool isLunasa = PR_TRUE; tokenInfo.manufacturerID[0] = 0; if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } if ( (PK11_GetTokenInfo(slot, &tokenInfo) == SECSuccess) && (tokenInfo.manufacturerID[0] != 0)) { int ix = 0; for(ix=0; ix < numManufacturerIDchars; ix++) { if (tokenInfo.manufacturerID[ix] != nethsmManufacturerID[ix]) { isNethsm = PR_FALSE; break; } } for(ix=0; ix < numManufacturerIDchars; ix++) { if (tokenInfo.manufacturerID[ix] != lunasaManufacturerID[ix]) { isLunasa = PR_FALSE; break; } } } else { isNethsm = PR_FALSE; isLunasa = PR_FALSE; } /* get unwrapping key */ if( JSS_PK11_getSymKeyPtr(env, unwrapperObj, &unwrappingKey) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the wrapping mechanism */ wrapType = JSS_getPK11MechFromAlg(env, wrapAlgObj); if(wrapType == CKM_INVALID_MECHANISM) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unknown algorithm"); goto finish; } /* get the mechanism parameter (IV) */ if( ivBA ) { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(wrapType, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* get wrapped key from byte array */ wrapped = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrapped == NULL ) { /* exception was thrown */ goto finish; } /* initialize the label to be empty */ label.len = 0; label.data = NULL; /* get the public value */ pubValue = JSS_ByteArrayToSECItem(env, publicValueBA); if(pubValue == NULL ) { /* exception was thrown */ goto finish; } if( temporary ) { token = PR_FALSE; } else { token = PR_TRUE; } /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } keyType = PK11_GetKeyType(keyTypeMech, 0); /* special case nethsm and lunasa*/ if( isNethsm ) { isSensitive = PR_FALSE; isExtractable = PR_FALSE; } else if ( isLunasa) { isSensitive = PR_FALSE; isExtractable = PR_TRUE; } /* figure out which operations to enable for this key */ switch (keyType) { case CKK_RSA: numAttribs = 3; attribs[0] = CKA_SIGN; attribs[1] = CKA_SIGN_RECOVER; attribs[2] = CKA_UNWRAP; if (isExtractable) { attribs[3] = CKA_EXTRACTABLE; numAttribs = 4; } break; case CKK_EC: numAttribs = 1; attribs[0] = CKA_SIGN; if (isExtractable) { attribs[1] = CKA_EXTRACTABLE; numAttribs = 2; } break; case CKK_DSA: attribs[0] = CKA_SIGN; numAttribs = 1; break; case CKK_KEA: case CKK_DH: case CKK_X9_42_DH: attribs[0] = CKA_DERIVE; numAttribs = 1; break; default: /* unknown key type */ PR_ASSERT(PR_FALSE); attribs[0] = CKA_SIGN; numAttribs = 1; break; } /* perform the unwrap */ privk = PK11_UnwrapPrivKey(slot, unwrappingKey, wrapType, param, wrapped, &label, pubValue, token, isSensitive /*sensitive*/, keyType, attribs, numAttribs, NULL /*wincx*/); if( privk == NULL ) { char err[256] = {0}; PR_snprintf(err, 256, "Key Unwrap failed on token; keyType=%d", keyType); JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, err); goto finish; } /* stuff the privk into a Java private key object. This sets privk to * NULL */ privkObj = JSS_PK11_wrapPrivKey(env, &privk); finish: if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*free iv*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*free param*/); } if(wrapped) { SECITEM_FreeItem(wrapped, PR_TRUE /*free wrapped*/); } if(pubValue) { SECITEM_FreeItem(pubValue, PR_TRUE /*free pubValue*/); } PR_ASSERT(privk==NULL); PR_ASSERT( privkObj!=NULL || (*env)->ExceptionOccurred(env) ); return privkObj; } #define ALL_SYMKEY_OPS (CKF_ENCRYPT | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP) /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapSymWithSym */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithSym (JNIEnv *env, jclass clazz, jobject tokenObj, jobject unwrapperObj, jbyteArray wrappedBA, jobject wrapAlgObj, jobject typeAlgObj, jint keyLen, jbyteArray ivBA, jint usageEnum, jboolean temporary) { PK11SymKey *symKey=NULL, *wrappingKey=NULL; CK_MECHANISM_TYPE wrappingMech, keyTypeMech; SECItem *wrappedKey=NULL, *iv=NULL, *param=NULL; jobject keyObj = NULL; CK_ULONG operation; CK_FLAGS flags; PRBool isPermanent = PR_FALSE; /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } /* get wrapping key */ if( JSS_PK11_getSymKeyPtr(env, unwrapperObj, &wrappingKey) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get wrapping mechanism */ wrappingMech = JSS_getPK11MechFromAlg(env, wrapAlgObj); if( wrappingMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized wrapping algorithm"); goto finish; } /* get the mechanism parameter (IV) */ if (ivBA == NULL) { param = PK11_ParamFromIV(wrappingMech,NULL); } else { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(wrappingMech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* get the wrapped key */ wrappedKey = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrappedKey == NULL ) { /* exception was thrown */ goto finish; } if( usageEnum == -1 ) { operation = CKA_ENCRYPT; /* doesn't matter, flags will override */ flags = ALL_SYMKEY_OPS; } else { operation = JSS_symkeyUsage[usageEnum]; flags = 0; } if( temporary ) { isPermanent = PR_FALSE; } else { isPermanent = PR_TRUE; } if( isPermanent == PR_FALSE) { symKey = PK11_UnwrapSymKeyWithFlags(wrappingKey, wrappingMech, param, wrappedKey, keyTypeMech, operation, keyLen, flags); } else { symKey = PK11_UnwrapSymKeyWithFlagsPerm(wrappingKey, wrappingMech, param, wrappedKey, keyTypeMech, operation, keyLen, flags,isPermanent); } if( symKey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); goto finish; } /* wrap the symmetric key in a Java object. This will clear symKey */ keyObj = JSS_PK11_wrapSymKey(env, &symKey); finish: if(wrappedKey) { SECITEM_FreeItem(wrappedKey, PR_TRUE /*free wrappedKey*/); } if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*free iv*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*free param*/); } if( symKey ) { PK11_FreeSymKey(symKey); } return keyObj; } /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapSymWithPriv */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithPriv (JNIEnv *env, jclass clazz, jobject tokenObj, jobject unwrapperObj, jbyteArray wrappedBA, jobject wrapAlgObj, jobject typeAlgObj, jint keyLen, jbyteArray ivBA, jint usageEnum) { PK11SymKey *symKey=NULL; CK_MECHANISM_TYPE wrappingMech=0, keyTypeMech=0; SECItem *wrappedKey=NULL, *iv=NULL, *param=NULL; jobject keyObj=NULL; SECKEYPrivateKey *wrappingKey=NULL; CK_ULONG operation; /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } /* get wrapping key */ if( JSS_PK11_getPrivKeyPtr(env, unwrapperObj, &wrappingKey) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the mechanism parameter (IV) */ if (ivBA == NULL) { param = PK11_ParamFromIV(wrappingMech, NULL); } else { iv = JSS_ByteArrayToSECItem(env, ivBA); if( iv == NULL ) { goto finish; /* exception was thrown */ } param = PK11_ParamFromIV(wrappingMech, iv); if( param == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to convert initialization vector to parameter"); goto finish; } } /* get the wrapped key */ wrappedKey = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrappedKey == NULL ) { /* exception was thrown */ goto finish; } if( usageEnum == -1 ) { /* !!!XXX If they didn't specify a usage, we'll assume decrypt because that's the most common case, and we can't specify more than one. See bug 135255. */ operation = CKA_DECRYPT; } else { operation = JSS_symkeyUsage[usageEnum]; } symKey = PK11_PubUnwrapSymKey(wrappingKey, wrappedKey, keyTypeMech, operation, keyLen); if( symKey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); goto finish; } /* Put the symmetric key into a Java object. This will clear symKey */ keyObj = JSS_PK11_wrapSymKey(env, &symKey); finish: if(wrappedKey) { SECITEM_FreeItem(wrappedKey, PR_TRUE /*free wrappedKey*/); } if(iv) { SECITEM_FreeItem(iv, PR_TRUE /*free iv*/); } if(param) { SECITEM_FreeItem(param, PR_TRUE /*free param*/); } if( symKey ) { PK11_FreeSymKey(symKey); } return keyObj; } /*********************************************************************** * * PK11KeyWrapper.nativeUnwrapSymPlaintext */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymPlaintext (JNIEnv *env, jclass clazz, jobject tokenObj, jbyteArray wrappedBA, jobject typeAlgObj, jint usageEnum, jboolean temporary) { PK11SymKey *symKey=NULL; CK_MECHANISM_TYPE keyTypeMech; SECItem *wrappedKey=NULL; jobject keyObj = NULL; PK11SlotInfo *slot = NULL; CK_ULONG operation; CK_FLAGS flags; PRBool isPerm = PR_FALSE; /* get key type */ keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); if( keyTypeMech == CKM_INVALID_MECHANISM ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unrecognized key type algorithm"); goto finish; } if( temporary ) { isPerm = PR_FALSE; } else { isPerm = PR_TRUE; } /* get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the wrapped key */ wrappedKey = JSS_ByteArrayToSECItem(env, wrappedBA); if( wrappedKey == NULL ) { /* exception was thrown */ goto finish; } if( usageEnum == -1 ) { operation = CKA_ENCRYPT; flags = ALL_SYMKEY_OPS; } else { operation = JSS_symkeyUsage[usageEnum]; flags = 0; } /* pull in the key */ symKey = PK11_ImportSymKeyWithFlags(slot, keyTypeMech, PK11_OriginUnwrap, operation, wrappedKey, flags, isPerm, NULL); if( symKey == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); goto finish; } /* wrap the symmetric key in a Java object. This will clear symKey */ keyObj = JSS_PK11_wrapSymKey(env, &symKey); finish: if(wrappedKey) { SECITEM_FreeItem(wrappedKey, PR_TRUE /*free wrappedKey*/); } if( symKey ) { PK11_FreeSymKey(symKey); } return keyObj; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t E r r o r S t r i n g * * Returns a simple error string for a given PKCS #11 error. */ char* JSS_PK11_getErrorString(CK_RV crv) { switch(crv) { case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY"; case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID"; case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID"; case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL"; case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED"; case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR"; case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY"; case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED"; case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED"; case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED"; case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR"; case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY"; case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID"; case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE"; case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE"; case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE"; case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID"; case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID"; case CKR_OK: return "CKR_OK"; case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE"; case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED"; case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID"; case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY"; case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE"; case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT"; case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED"; case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID"; case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE"; case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT"; case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN"; case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID"; case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE"; case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID"; case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE"; case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT"; default: return "PKCS #11 error"; } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java000066400000000000000000000550311326145000000226030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.util.Assert; import java.security.PublicKey; import java.security.interfaces.RSAPublicKey; import java.security.interfaces.DSAPublicKey; //requires JAVA 1.5 //import java.security.interfaces.ECPublicKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; final class PK11KeyWrapper implements KeyWrapper { private PK11Token token; private KeyWrapAlgorithm algorithm; private int state=UNINITIALIZED; private AlgorithmParameterSpec parameters=null; private SymmetricKey symKey=null; private PrivateKey privKey=null; private PublicKey pubKey=null; private byte[] IV=null; // states private static final int UNINITIALIZED=0; private static final int WRAP=1; private static final int UNWRAP=2; private PK11KeyWrapper() { } PK11KeyWrapper(PK11Token token, KeyWrapAlgorithm algorithm) { this.token = token; this.algorithm = algorithm; } public void initWrap(SymmetricKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initWrap(parameters); checkWrapper(wrappingKey); this.symKey = wrappingKey; } public void initWrap(PublicKey wrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initWrap(parameters); checkWrapper(wrappingKey); this.pubKey = wrappingKey; } public void initWrap() throws InvalidKeyException, InvalidAlgorithmParameterException { if( algorithm != KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException(algorithm + " requires a key"); } reset(); state = WRAP; } /** * Does everything that is key-independent for initializing a wrap. */ private void initWrap(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException { reset(); checkParams(parameters); this.parameters = parameters; state = WRAP; } public void initUnwrap(PrivateKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initUnwrap(parameters); checkWrapper(unwrappingKey); this.privKey = unwrappingKey; } public void initUnwrap(SymmetricKey unwrappingKey, AlgorithmParameterSpec parameters) throws InvalidKeyException, InvalidAlgorithmParameterException { initUnwrap(parameters); checkWrapper(unwrappingKey); this.symKey = unwrappingKey; } public void initUnwrap() throws InvalidKeyException, InvalidAlgorithmParameterException { if( algorithm != KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException(algorithm + " requires a key"); } reset(); state = UNWRAP; } /** * Does the key-independent parts of initializing an unwrap. */ private void initUnwrap(AlgorithmParameterSpec parameters) throws InvalidAlgorithmParameterException { reset(); checkParams(parameters); this.parameters = parameters; state = UNWRAP; } /** * Makes sure the key is right for the algorithm. */ private void checkWrapper(PublicKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } if( ! (key instanceof PK11PubKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } try { KeyType type = KeyType.getKeyTypeFromAlgorithm(algorithm); if( (type == KeyType.RSA && !(key instanceof RSAPublicKey)) || // requires JAVA 1.5 // (type == KeyType.EC && !(key instanceof ECPublicKey)) || (type == KeyType.DSA && !(key instanceof DSAPublicKey)) ) { throw new InvalidKeyException("Key is not the right type for "+ "this algorithm"); } } catch( NoSuchAlgorithmException e ) { Assert.notReached("unable to find algorithm from key type"); } } /** * Makes sure the key lives on the token and is right for the algorithm. */ private void checkWrapper(SymmetricKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } try { if( ! key.getOwningToken().equals(token) ) { throw new InvalidKeyException("Key does not reside on the current token: key owning token="+ key.getOwningToken().getName()); } if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } if( ((PK11SymKey)key).getKeyType() != KeyType.getKeyTypeFromAlgorithm(algorithm) ) { throw new InvalidKeyException("Key is not the right type for"+ " this algorithm"); } } catch( NoSuchAlgorithmException e ) { Assert.notReached("Unknown algorithm"); } catch (Exception e) { Assert.notReached("Exception:"+ e.toString()); } } /** * Makes sure the key is on the token and is right for the algorithm. */ private void checkWrapper(PrivateKey key) throws InvalidKeyException { if( key==null ) { throw new InvalidKeyException("Key is null"); } if( ! key.getOwningToken().equals(token) ) { throw new InvalidKeyException("Key does not reside on the "+ "current token"); } if( ! (key instanceof PK11PrivKey) ) { throw new InvalidKeyException("Key is not a PKCS #11 key"); } try { if( ((PK11PrivKey)key).getKeyType() != KeyType.getKeyTypeFromAlgorithm(algorithm) ) { throw new InvalidKeyException("Key is not the right type for"+ " this algorithm"); } } catch( NoSuchAlgorithmException e ) { Assert.notReached("Unknown algorithm"); } } private void checkParams(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { if( ! algorithm.isValidParameterObject(params) ) { String name = "null"; if( params != null ) { name = params.getClass().getName(); } throw new InvalidAlgorithmParameterException( algorithm + " cannot use a " + name + " parameter"); } if( params instanceof IVParameterSpec ) { IV = ((IVParameterSpec)params).getIV(); } else if( params instanceof javax.crypto.spec.IvParameterSpec ) { IV = ((javax.crypto.spec.IvParameterSpec)params).getIV(); } else if( params instanceof RC2ParameterSpec ) { IV = ((RC2ParameterSpec)params).getIV(); } } public byte[] wrap(PrivateKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException { if( state != WRAP ) { throw new IllegalStateException(); } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException( "plaintext wrapping not supported"); } checkWrappee(toBeWrapped); if( symKey != null ) { Assert._assert( privKey==null && pubKey==null ); return nativeWrapPrivWithSym(token, toBeWrapped, symKey, algorithm, IV); } else { throw new InvalidKeyException( "Wrapping a private key with a public key is not supported"); /* Assert._assert( pubKey!=null && privKey==null && symKey==null ); return nativeWrapPrivWithPub(token, toBeWrapped, pubKey, algorithm, IV); */ } } public byte[] wrap(SymmetricKey toBeWrapped) throws InvalidKeyException, IllegalStateException, TokenException { if( state != WRAP ) { throw new IllegalStateException(); } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { throw new InvalidKeyException("plaintext wrapping not supported"); } checkWrappee(toBeWrapped); if( symKey != null ) { Assert._assert( privKey==null && pubKey==null ); return nativeWrapSymWithSym(token, toBeWrapped, symKey, algorithm, IV); } else { Assert._assert( pubKey!=null && privKey==null && symKey==null ); return nativeWrapSymWithPub(token, toBeWrapped, pubKey, algorithm, IV); } } /** * Makes sure the key lives on the right token. */ private void checkWrappee(SymmetricKey symKey) throws InvalidKeyException { if( symKey == null ) { throw new InvalidKeyException("key to be wrapped is null"); } if( ! (symKey instanceof PK11SymKey) ) { throw new InvalidKeyException("key to be wrapped is not a "+ "PKCS #11 key"); } /* NSS is capable of moving keys appropriately, so this call is prematurely bailing if( ! symKey.getOwningToken().equals(token) ) { throw new InvalidKeyException("key to be wrapped does not live"+ " on the same token as the wrapping key"); } */ } /** * Makes sure the key lives on the right token. */ private void checkWrappee(PrivateKey privKey) throws InvalidKeyException { if( privKey == null ) { throw new InvalidKeyException("key to be wrapped is null"); } if( ! (privKey instanceof PK11PrivKey) ) { throw new InvalidKeyException("key to be wrapped is not a "+ "PKCS #11 key"); } /* NSS is capable of moving keys appropriately, so this call is prematurely bailing if( ! privKey.getOwningToken().equals(token) ) { throw new InvalidKeyException("key to be wrapped does not live"+ " on the same token as the wrapping key"); } */ } /** * Wrap a symmetric with a symmetric */ private static native byte[] nativeWrapSymWithSym(PK11Token token, SymmetricKey toBeWrapped, SymmetricKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; /** * Wrap a symmetric with a public */ private static native byte[] nativeWrapSymWithPub(PK11Token token, SymmetricKey toBeWrapped, PublicKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; /** * Wrap a private with a symmetric */ private static native byte[] nativeWrapPrivWithSym(PK11Token token, PrivateKey toBeWrapped, SymmetricKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; /** * Wrap a private with a public. * NOTE: This operation is not supported by the security library. private static native byte[] nativeWrapPrivWithPub(PK11Token token, PrivateKey toBeWrapped, PublicKey wrappingKey, KeyWrapAlgorithm alg, byte[] IV) throws TokenException; */ /** * Unwraps a private key, creating a permanent private key object. * A permanent private key object resides on a token until it is * explicitly deleted from the token. */ public PrivateKey unwrapPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException { return baseUnwrapPrivate(wrapped, type, publicKey, false); } /** * Unwraps a private key, creating a temporary private key object. * A temporary * private key is one that does not permanently reside on a token. * As soon as it is garbage-collected, it is gone forever. */ public PrivateKey unwrapTemporaryPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey) throws TokenException, InvalidKeyException, IllegalStateException { return baseUnwrapPrivate(wrapped, type, publicKey, true); } private PrivateKey baseUnwrapPrivate(byte[] wrapped, PrivateKey.Type type, PublicKey publicKey, boolean temporary) throws TokenException, InvalidKeyException, IllegalStateException { if( state != UNWRAP ) { throw new IllegalStateException(); } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { throw new TokenException("plaintext unwrapping of private keys " + "is not supported"); } byte[] publicValue = extractPublicValue(publicKey, type); if( symKey != null ) { Assert._assert(pubKey==null && privKey==null); return nativeUnwrapPrivWithSym(token, symKey, wrapped, algorithm, algFromType(type), publicValue, IV, temporary ); } else { throw new InvalidKeyException("Unwrapping a private key with" + " a private key is not supported"); /* Assert._assert(privKey!=null && pubKey==null && symKey==null); return nativeUnwrapPrivWithPriv(token, privKey, wrapped, algorithm, algFromType(type), publicValue, IV, temporary ); */ } } /** * Extracts the "public value" from a public key. The public value is * used to construct the key identifier (CKA_ID). Also, the internal token * stores the EC DSA and EC public value along with the private key. */ private static byte[] extractPublicValue(PublicKey publicKey, PrivateKey.Type type) throws InvalidKeyException { /* this code should call a generic function which returns the * proper public value. */ if( publicKey == null ) { throw new InvalidKeyException("publicKey is null"); } if( type == PrivateKey.RSA ) { if( !(publicKey instanceof RSAPublicKey)) { throw new InvalidKeyException("Type of public key does not "+ "match type of private key which is RSA"); } return ((RSAPublicKey)publicKey).getModulus().toByteArray(); } else if(type == PrivateKey.EC) { if( !(publicKey instanceof PK11ECPublicKey) ) { throw new InvalidKeyException("Type of public key does not "+ "match type of private key which is EC"); } return ((PK11ECPublicKey)publicKey).getW().toByteArray(); } else if(type == PrivateKey.DSA) { if( !(publicKey instanceof DSAPublicKey) ) { throw new InvalidKeyException("Type of public key does not "+ "match type of private key which is DSA"); } return ((DSAPublicKey)publicKey).getY().toByteArray(); } else { Assert.notReached("Unknown private key type"); return new byte[] { }; } } public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetric(wrapped, type, usage.getVal(), keyLen); } public SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetric(wrapped, type, -1, keyLen); } public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, SymmetricKey.Usage usage, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetricPerm(wrapped, type, usage.getVal(), keyLen); } public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { return unwrapSymmetricPerm(wrapped, type, -1, keyLen); } private SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, int usageEnum, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { if( state != UNWRAP ) { throw new IllegalStateException(); } /* Since we want permanent,make the temporary arg false */ boolean temporary = false; if( (! algorithm.isPadded()) && (type == SymmetricKey.RC4) ) { if( keyLen <= 0 ) { throw new InvalidAlgorithmParameterException( "RC4 keys wrapped in unpadded algorithms need key length"+ " specified when unwrapping"); } } else { // Don't use the key length keyLen = 0; } if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { return nativeUnwrapSymPlaintext(token, wrapped, algFromType(type), usageEnum,temporary ); } else { if( symKey != null ) { Assert._assert(pubKey==null && privKey==null); return nativeUnwrapSymWithSym(token, symKey, wrapped, algorithm, algFromType(type), keyLen, IV, usageEnum,temporary); } else { Assert._assert(privKey!=null && pubKey==null && symKey==null); throw new TokenException("We do not support permnament unwrapping with private key."); } } } private SymmetricKey unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, int usageEnum, int keyLen) throws TokenException, IllegalStateException, InvalidAlgorithmParameterException { if( state != UNWRAP ) { throw new IllegalStateException(); } if( (! algorithm.isPadded()) && (type == SymmetricKey.RC4) ) { if( keyLen <= 0 ) { throw new InvalidAlgorithmParameterException( "RC4 keys wrapped in unpadded algorithms need key length"+ " specified when unwrapping"); } } else { // Don't use the key length //keyLen = 0; } /* Since we DONT want permanent,make the temporary arg true */ boolean temporary = true; if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { return nativeUnwrapSymPlaintext(token, wrapped, algFromType(type), usageEnum, temporary ); } else { if( symKey != null ) { Assert._assert(pubKey==null && privKey==null); return nativeUnwrapSymWithSym(token, symKey, wrapped, algorithm, algFromType(type), keyLen, IV, usageEnum,temporary); } else { Assert._assert(privKey!=null && pubKey==null && symKey==null); return nativeUnwrapSymWithPriv(token, privKey, wrapped, algorithm, algFromType(type), keyLen, IV, usageEnum ); } } } private static Algorithm algFromType(PrivateKey.Type type) { if (type == PrivateKey.RSA) { return KeyPairAlgorithm.RSAFamily; } else if (type == PrivateKey.DSA) { return KeyPairAlgorithm.DSAFamily; } else { Assert._assert( type == PrivateKey.EC); return KeyPairAlgorithm.ECFamily; } } private static Algorithm algFromType(SymmetricKey.Type type) { if( type == SymmetricKey.DES ) { return EncryptionAlgorithm.DES_ECB; } else if( type == SymmetricKey.DES3 ) { return EncryptionAlgorithm.DES3_ECB; } else if( type == SymmetricKey.AES ) { return EncryptionAlgorithm.AES_128_ECB; }else if( type == SymmetricKey.RC4 ) { return EncryptionAlgorithm.RC4; } else if( type == SymmetricKey.AES ) { return EncryptionAlgorithm.AES_128_ECB; } else if( type == SymmetricKey.SHA1_HMAC) { return HMACAlgorithm.SHA1; } else { Assert._assert( type == SymmetricKey.RC2 ); return EncryptionAlgorithm.RC2_CBC; } } /** * Unwrap a private with a symmetric. */ private static native PrivateKey nativeUnwrapPrivWithSym(PK11Token token, SymmetricKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, byte[] publicValue, byte[] IV, boolean temporary) throws TokenException; /** * Unwrap a private with a private. * NOTE: this is not supported by the security library. private static native PrivateKey nativeUnwrapPrivWithPriv(PK11Token token, PrivateKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, byte[] publicValue, byte[] IV, boolean temporary) throws TokenException; */ /** * Unwrap a symmetric with a symmetric. */ private static native SymmetricKey nativeUnwrapSymWithSym(PK11Token token, SymmetricKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, int keyLen, byte[] IV, int usageEnum, boolean temporary) throws TokenException; /** * Unwrap a symmetric with a private. */ private static native SymmetricKey nativeUnwrapSymWithPriv(PK11Token token, PrivateKey unwrappingKey, byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, int keyLen, byte[] IV, int usageEnum) throws TokenException; private static native SymmetricKey nativeUnwrapSymPlaintext(PK11Token token, byte[] wrappedKey, Algorithm type, int usageEnum, boolean temporary); private void reset() { state = UNINITIALIZED; symKey = null; privKey = null; pubKey = null; parameters = null; IV = null; } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11MessageDigest.c000066400000000000000000000113571326145000000225420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11MessageDigest.h" #include #include #include #include #include /* JSS includes */ #include #include #include #include #include /*********************************************************************** * * PK11MessageDigest.initDigest * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initDigest (JNIEnv *env, jclass clazz, jobject algObj) { SECOidTag alg; PK11Context *context=NULL; alg = JSS_getOidTagFromAlg(env, algObj); PR_ASSERT( alg != SEC_OID_UNKNOWN ); /* we checked already in Java */ context = PK11_CreateDigestContext(alg); if( context == NULL ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Unable to create digest context"); return NULL; } return JSS_PK11_wrapCipherContextProxy(env, &context); } /*********************************************************************** * * PK11MessageDigest.initHMAC * */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_initHMAC (JNIEnv *env, jclass clazz, jobject tokenObj, jobject algObj, jobject keyObj) { PK11SymKey *origKey = NULL, *newKey=NULL; PK11Context *context = NULL; CK_MECHANISM_TYPE mech; SECItem param; jobject contextObj=NULL; mech = JSS_getPK11MechFromAlg(env, algObj); PR_ASSERT( mech != CKM_INVALID_MECHANISM ); /* we checked already in Java */ if( JSS_PK11_getSymKeyPtr(env, keyObj, &origKey) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* copy the key, setting the CKA_SIGN attribute */ newKey = PK11_CopySymKeyForSigning(origKey, mech); /* For some key on the hsm, this call could fail, but the key may work anyway */ if( newKey == NULL ) { newKey = origKey; } param.data = NULL; param.len = 0; context = PK11_CreateContextBySymKey(mech, CKA_SIGN, newKey, ¶m); if( context == NULL ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Unable to initialize digest context"); goto finish; } contextObj = JSS_PK11_wrapCipherContextProxy(env, &context); finish: if(newKey && (newKey != origKey)) { /* SymKeys are ref counted, and the context will free it's ref * when it is destroyed */ PK11_FreeSymKey(newKey); } return contextObj; } /*********************************************************************** * * PK11MessageDigest.update * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_update (JNIEnv *env, jclass clazz, jobject proxyObj, jbyteArray inbufBA, jint offset, jint len) { PK11Context *context = NULL; jbyte* bytes = NULL; if( JSS_PK11_getCipherContext(env, proxyObj, &context) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } PR_ASSERT( (*env)->GetArrayLength(env, inbufBA) >= offset+len ); bytes = (*env)->GetByteArrayElements(env, inbufBA, NULL); if( bytes == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if( PK11_DigestOp(context, (unsigned char*)(bytes+offset), len) != SECSuccess ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Digest operation failed"); goto finish; } finish: if(bytes) { (*env)->ReleaseByteArrayElements(env, inbufBA, bytes, JNI_ABORT); } } /*********************************************************************** * * PK11MessageDigest.digest * */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11MessageDigest_digest (JNIEnv *env, jclass clazz, jobject proxyObj, jbyteArray outbuf, jint offset, jint len) { PK11Context *context=NULL; jbyte *bytes=NULL; SECStatus status; unsigned int outLen = 0; if( JSS_PK11_getCipherContext(env, proxyObj, &context) != PR_SUCCESS) { /* exception was thrown */ goto finish; } PR_ASSERT( (*env)->GetArrayLength(env, outbuf) >= offset+len ); bytes = (*env)->GetByteArrayElements(env, outbuf, NULL); if( bytes == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } status = PK11_DigestFinal(context, (unsigned char*)(bytes+offset), &outLen, len); if( status != SECSuccess ) { JSS_throwMsg(env, DIGEST_EXCEPTION, "Error occurred while performing" " digest operation"); goto finish; } finish: if(bytes) { (*env)->ReleaseByteArrayElements(env, outbuf, bytes, 0); } return outLen; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11MessageDigest.java000066400000000000000000000072641326145000000232430ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import java.security.DigestException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; /** * Message Digesting with PKCS #11. */ public final class PK11MessageDigest extends JSSMessageDigest { private PK11Token token; private CipherContextProxy digestProxy; private PK11SymKey hmacKey; private DigestAlgorithm alg; PK11MessageDigest(PK11Token token, DigestAlgorithm alg) throws NoSuchAlgorithmException, DigestException { this.token = token; this.alg = alg; if( ! token.doesAlgorithm(alg) ) { throw new NoSuchAlgorithmException(); } reset(); } public void initHMAC(SymmetricKey key) throws DigestException, InvalidKeyException { if( ! (alg instanceof HMACAlgorithm) ) { throw new DigestException("Digest is not an HMAC digest"); } reset(); if( ! (key instanceof PK11SymKey) ) { throw new InvalidKeyException("HMAC key is not a PKCS #11 key"); } hmacKey = (PK11SymKey) key; if( ! key.getOwningToken().equals(token) ) { hmacKey = null; throw new InvalidKeyException( "HMAC key does not live on the same token as this digest"); } this.digestProxy = initHMAC(token, alg, hmacKey); } public void update(byte[] input, int offset, int len) throws DigestException { if( digestProxy == null ) { throw new DigestException("Digest not correctly initialized"); } if( input.length < offset+len ) { throw new IllegalArgumentException( "Input buffer is not large enough for offset and length"); } update(digestProxy, input, offset, len); } public int digest(byte[] outbuf, int offset, int len) throws DigestException { if( digestProxy == null ) { throw new DigestException("Digest not correctly initialized"); } if( outbuf.length < offset+len ) { throw new IllegalArgumentException( "Output buffer is not large enough for offset and length"); } int retval = digest(digestProxy, outbuf, offset, len); reset(); return retval; } public void reset() throws DigestException { if( ! (alg instanceof HMACAlgorithm) ) { // This is a regular digest, so we have enough information // to initialize the context this.digestProxy = initDigest(alg); } else if( hmacKey != null ) { // This is an HMAC digest, and we have a key this.digestProxy = initHMAC(token, alg, hmacKey); } else { // this is an HMAC digest for which we don't have the key yet, // we have to wait to construct the context this.digestProxy = null; } } public DigestAlgorithm getAlgorithm() { return alg; } private static native CipherContextProxy initDigest(DigestAlgorithm alg) throws DigestException; private static native CipherContextProxy initHMAC(PK11Token token, DigestAlgorithm alg, PK11SymKey key) throws DigestException; private static native void update(CipherContextProxy proxy, byte[] inbuf, int offset, int len); private static native int digest(CipherContextProxy proxy, byte[] outbuf, int offset, int len); } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Module.c000066400000000000000000000150101326145000000212310ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Module.h" #include #include #include #include #include #include "pk11util.h" #include #include #include "jss_exceptions.h" /*********************************************************************** * Class: org_mozilla_jss_pkcs11_PK11Module * Method: getName * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Module_getName (JNIEnv *env, jobject this) { SECMODModule *module; jstring nameString=NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getModulePtr(env, this, &module) != PR_SUCCESS) { goto finish; } PR_ASSERT(module->commonName != NULL); nameString = (*env)->NewStringUTF(env, module->commonName); finish: PR_ASSERT( nameString || (*env)->ExceptionOccurred(env) ); return nameString; } /*********************************************************************** * Class: org_mozilla_jss_pkcs11_PK11Module * Method: getLibraryName * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Module_getLibraryName (JNIEnv *env, jobject this) { SECMODModule *module; jstring libName = NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getModulePtr(env, this, &module) != PR_SUCCESS) { goto finish; } PR_ASSERT(module->dllName != NULL); libName = (*env)->NewStringUTF(env, module->dllName); finish: PR_ASSERT( libName || (*env)->ExceptionOccurred(env) ); return libName; } /*********************************************************************** * Class: org_mozilla_jss_pkcs11_PK11Module * Method: putTokensInVector * Signature: (Ljava/util/Vector;)V */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Module_putTokensInVector (JNIEnv *env, jobject this, jobject vector) { SECMODModule *module; jclass vectorClass; jmethodID addElement; jobject token; PK11SlotInfo *slot; int i; PR_ASSERT(env!=NULL && this!=NULL && vector!=NULL); /*************************** * Get Vector JNI ids ***************************/ vectorClass = (*env)->GetObjectClass(env, vector); if(vectorClass==NULL) goto finish; addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement==NULL) goto finish; /*************************** * Get the PKCS #11 module ***************************/ if( JSS_PK11_getModulePtr(env, this, &module) != PR_SUCCESS) goto finish; /************************** * Loop over slots **************************/ for(i=0; i < module->slotCount; i++) { if (PK11_IsPresent(module->slots[i])) { char *tokenname; tokenname = PK11_GetTokenName(module->slots[i]); /* ignore if the token has no name */ if( tokenname!=NULL && tokenname[0]!='\0' ) { /* turn the slot into a PK11Token */ slot = PK11_ReferenceSlot(module->slots[i]); PR_ASSERT(slot!=NULL); token = JSS_PK11_wrapPK11Token(env, &slot); /* stick the PK11Token in the Vector */ (*env)->CallVoidMethod(env, vector, addElement, token); } } } finish: return; } /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 M o d u l e * * Turns a SECMODModule* C structure into a PK11Module Java object. * * INPUTS * ptr * Address of a SECMODModule *. This pointer will be copied * into the new Java object, then set to NULL. * RETURNS * A new Java PK11Module object, or NULL if an exception was thrown. * In any case, the ptr parameter is eaten. */ jobject JSS_PK11_wrapPK11Module(JNIEnv *env, SECMODModule **module) { jclass moduleClass; jmethodID constructor; jobject newModule=NULL; jbyteArray pointer; PR_ASSERT(env!=NULL && module!=NULL && *module!=NULL); pointer = JSS_ptrToByteArray(env, (void*)*module); /* * Lookup the class and constructor */ moduleClass = (*env)->FindClass(env, PK11MODULE_CLASS_NAME); if(moduleClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, moduleClass, PLAIN_CONSTRUCTOR, PK11MODULE_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * Call the constructor */ newModule = (*env)->NewObject(env, moduleClass, constructor, pointer); finish: if(newModule==NULL) { SECMOD_DestroyModule(*module); } *module = NULL; return newModule; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t M o d u l e P t r * * Retrieve the SECMODModule pointer of the given PK11Module. * * INPUTS * module * A reference to a Java PK11Module. * ptr * Address of a SECMODModule * that will be loaded with the * SECMODModule pointer of the given PK11Module. * RETURNS * PR_FAILURE if an exception was thrown, or PR_SUCCESS if the * peration succeeded. */ PRStatus JSS_PK11_getModulePtr(JNIEnv *env, jobject module, SECMODModule **ptr) { PR_ASSERT(env!=NULL && module!=NULL && ptr!=NULL); return JSS_getPtrFromProxyOwner(env, module, PK11MODULE_PROXY_FIELD, PK11MODULE_PROXY_SIG, (void**)ptr); } /********************************************************************** * ModuleProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_ModuleProxy_releaseNativeResources (JNIEnv *env, jobject this) { SECMODModule *module; if (JSS_getPtrFromProxy(env, this, (void **)&module) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(module != NULL); SECMOD_DestroyModule(module); finish: return; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Module.java000066400000000000000000000030031326145000000217270ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.util.Assert; import java.util.Enumeration; import java.util.Vector; public final class PK11Module { private PK11Module() { Assert.notReached("PK11Module default constructor"); } /** * This constructor should only be called from native code. */ private PK11Module(byte[] pointer) { Assert._assert(pointer!=null); moduleProxy = new ModuleProxy(pointer); reloadTokens(); } /** * Returns the common name of this module. */ public native String getName(); /** * Returns the name of the shared library implementing this module. */ public native String getLibraryName(); /** * Get the CryptoTokens provided by this module. * * @return An enumeration of CryptoTokens that come from this module. */ public synchronized Enumeration getTokens() { return tokenVector.elements(); } /** * Re-load the list of this module's tokens. This function is private * to JSS. */ public synchronized void reloadTokens() { tokenVector = new Vector(); putTokensInVector(tokenVector); } private native void putTokensInVector(Vector tokens); private Vector tokenVector; private ModuleProxy moduleProxy; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11ParameterSpec.java000066400000000000000000000010201326145000000232320ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import java.security.spec.AlgorithmParameterSpec; public final class PK11ParameterSpec implements AlgorithmParameterSpec { public PK11ParameterSpec(byte [] derBlob) { blob = derBlob; } public byte [] getEncoded() { return blob; } private byte [] blob; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11PrivKey.c000066400000000000000000000426161326145000000214110ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PrivateKeyProxy.h" #include #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include "java_ids.h" /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P r i v K e y * privk: will be stored in a Java wrapper. * Returns: a new PK11PrivKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapPrivKey(JNIEnv *env, SECKEYPrivateKey **privk) { jclass keyClass; jmethodID constructor; jbyteArray ptrArray; jobject Key=NULL; const char *className = NULL; PR_ASSERT(env!=NULL && privk!=NULL && *privk!=NULL); /* Find the class */ switch( (*privk)->keyType ) { case rsaKey: className = "org/mozilla/jss/pkcs11/PK11RSAPrivateKey"; break; case dsaKey: className = "org/mozilla/jss/pkcs11/PK11DSAPrivateKey"; break; case ecKey: className = "org/mozilla/jss/pkcs11/PK11ECPrivateKey"; break; default: className = "org/mozilla/jss/pkcs11/PK11PrivKey"; break; } keyClass = (*env)->FindClass(env, className); if(keyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* find the constructor */ constructor = (*env)->GetMethodID(env, keyClass, "", "([B)V"); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* convert the pointer to a byte array */ ptrArray = JSS_ptrToByteArray(env, (void*)*privk); if(ptrArray == NULL) { goto finish; } /* call the constructor */ Key = (*env)->NewObject(env, keyClass, constructor, ptrArray); finish: if(Key == NULL) { SECKEY_DestroyPrivateKey(*privk); } *privk = NULL; return Key; } /*********************************************************************** * PK11PrivKey.verifyKeyIsOnToken */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_verifyKeyIsOnToken (JNIEnv *env, jobject this, jobject token) { SECKEYPrivateKey *key = NULL; PK11SlotInfo *slot = NULL; PK11SlotInfo *keySlot = NULL; PK11SlotInfo *dbSlot = NULL; PK11SlotInfo *cryptoSlot = NULL; if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } keySlot = PK11_GetSlotFromPrivateKey(key); dbSlot = PK11_GetInternalKeySlot(); if(keySlot == dbSlot) { cryptoSlot = PK11_GetInternalSlot(); /* hack for internal module */ if(slot != keySlot && slot != cryptoSlot) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } } else if(keySlot != slot) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } finish: if(keySlot != NULL) { PK11_FreeSlot(keySlot); } if(dbSlot != NULL) { PK11_FreeSlot(dbSlot); } if(cryptoSlot != NULL) { PK11_FreeSlot(cryptoSlot); } } /* * PK11PrivKey.getKeyType * * Returns: The KeyType of this key. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getKeyType (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; SECKEYPrivateKey *privk; KeyType keyType; char* keyTypeFieldName; jclass keyTypeClass; jfieldID keyTypeField; jobject keyTypeObject = NULL; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if(JSS_PK11_getPrivKeyPtr(env, this, &privk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); goto finish; } PR_ASSERT(privk!=NULL); keyType = SECKEY_GetPrivateKeyType(privk); switch(keyType) { case nullKey: keyTypeFieldName = NULL_KEYTYPE_FIELD; break; case rsaKey: keyTypeFieldName = RSA_KEYTYPE_FIELD; break; case dsaKey: keyTypeFieldName = DSA_KEYTYPE_FIELD; break; case fortezzaKey: keyTypeFieldName = FORTEZZA_KEYTYPE_FIELD; break; case dhKey: keyTypeFieldName = DH_KEYTYPE_FIELD; break; case keaKey: keyTypeFieldName = KEA_KEYTYPE_FIELD; break; case ecKey: keyTypeFieldName = EC_KEYTYPE_FIELD; break; default: PR_ASSERT(PR_FALSE); keyTypeFieldName = NULL_KEYTYPE_FIELD; break; } keyTypeClass = (*env)->FindClass(env, KEYTYPE_CLASS_NAME); if(keyTypeClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeField = (*env)->GetStaticFieldID(env, keyTypeClass, keyTypeFieldName, KEYTYPE_FIELD_SIG); if(keyTypeField==NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeObject = (*env)->GetStaticObjectField( env, keyTypeClass, keyTypeField); if(keyTypeObject == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: PR_DetachThread(); return keyTypeObject; } /* * PrivateKeyProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PrivateKeyProxy_releaseNativeResources (JNIEnv *env, jobject this) { SECKEYPrivateKey *privk; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); /* Get the SECKEYPrivateKey structure */ if(JSS_getPtrFromProxy(env, this, (void**) &privk) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } PR_ASSERT(privk != NULL); SECKEY_DestroyPrivateKey(privk); finish: PR_DetachThread(); return; } /* * Given a PrivateKey object, extracts the SECKEYPrivateKey* and stores it * at the given address. * * privkObject: A JNI reference to a PrivateKey object. * ptr: Address of a SECKEYPrivateKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPrivKeyPtr(JNIEnv *env, jobject privkObject, SECKEYPrivateKey** ptr) { PR_ASSERT(env!=NULL && privkObject!=NULL); /* Get the pointer from the key proxy */ PR_ASSERT(sizeof(SECKEYPrivateKey*) == sizeof(void*)); return JSS_getPtrFromProxyOwner(env, privkObject, KEY_PROXY_FIELD, KEY_PROXY_SIG, (void**)ptr); } /*********************************************************************** * * PK11PrivKey.getPK11Token * * Figures out which slot this key lives on and wraps it in a PK11Token, * * RETURNS * NULL if an exception occurred, otherwise a new PK11Token object. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getOwningToken (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; PK11SlotInfo *keySlot = NULL; jobject token = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* Get the C key structure */ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* Get the slot that this key lives on */ keySlot = PK11_GetSlotFromPrivateKey(key); PR_ASSERT(keySlot != NULL); /* Turn the slot into a Java PK11Token */ token = JSS_PK11_wrapPK11Token(env, &keySlot); if(token == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: if(keySlot != NULL) { PK11_FreeSlot(keySlot); } return token; } /* * workaround for bug 100791: misspelled function prototypes in pk11func.h */ SECItem* PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey*); /********************************************************************** * PK11PrivKey.getUniqueID */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getUniqueID (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; SECItem *idItem = NULL; jbyteArray byteArray = NULL; PR_ASSERT(env!=NULL && this!=NULL); /*************************************************** * Get the private key structure ***************************************************/ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /*************************************************** * Get the key id ***************************************************/ idItem = PK11_GetLowLevelKeyIDForPrivateKey(key); if(idItem == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to get key id"); goto finish; } /*************************************************** * Write the key id to a new byte array ***************************************************/ PR_ASSERT(idItem->len > 0); byteArray = (*env)->NewByteArray(env, idItem->len); if(byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, byteArray, 0, idItem->len, (jbyte*)idItem->data); if( (*env)->ExceptionOccurred(env) != NULL) { PR_ASSERT(PR_FALSE); goto finish; } finish: if(idItem != NULL) { SECITEM_FreeItem(idItem, PR_TRUE /*freeit*/); } return byteArray; } /********************************************************************** * PK11PrivKey.getStrength */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getStrength (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; PK11SlotInfo *slot = NULL; int strength; PR_ASSERT(env!=NULL && this!=NULL); /*************************************************** * Get the private key and slot C structures ***************************************************/ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return -1; } slot = PK11_GetSlotFromPrivateKey(key); PR_ASSERT(slot!=NULL); /*************************************************** * Try to login to the token if necessary ***************************************************/ PK11_Authenticate(slot, PR_TRUE /*readCerts*/, NULL /*wincx*/); /*************************************************** * Get the strength ( in bytes ) ***************************************************/ strength = PK11_GetPrivateModulusLen(key); if( strength > 0 ) { /* convert to bits */ return strength * 8; } else { return strength; } } /*********************************************************************** * JSS_PK11_getKeyType * * Converts a PrivateKey.KeyType object to a PKCS #11 key type. * * INPUTS * keyTypeObj * A org.mozilla.jss.crypto.PrivateKey.KeyType object. * RETURNS * The key type, or nullKey if an exception occurred. */ KeyType JSS_PK11_getKeyType(JNIEnv *env, jobject keyTypeObj) { jclass keyTypeClass; jfieldID fieldID; char *fieldNames[] = { RSA_PRIVKEYTYPE_FIELD, DSA_PRIVKEYTYPE_FIELD, FORTEZZA_KEYTYPE_FIELD, DH_KEYTYPE_FIELD, KEA_KEYTYPE_FIELD, EC_KEYTYPE_FIELD }; int numTypes = 6; KeyType keyTypes[] = { rsaKey, dsaKey, fortezzaKey, dhKey, keaKey, ecKey }; jobject field; int i; PR_ASSERT(env!=NULL && keyTypeObj!=NULL); keyTypeClass = (*env)->FindClass(env, PRIVKEYTYPE_CLASS_NAME); if( keyTypeClass == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } for(i=0; i < numTypes; i++) { fieldID = (*env)->GetStaticFieldID(env, keyTypeClass, fieldNames[i], PRIVKEYTYPE_SIG); if( fieldID == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } field = (*env)->GetStaticObjectField(env, keyTypeClass, fieldID); if( field == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } if( (*env)->IsSameObject(env, keyTypeObj, field) ) { return keyTypes[i]; } } /* unrecognized type? */ PR_ASSERT( PR_FALSE ); finish: return nullKey; } /*********************************************************************** * importPrivateKey */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_fromPrivateKeyInfo ( JNIEnv *env, jclass clazz, jbyteArray keyArray, jobject tokenObj, jbyteArray publicValueArray ) { SECItem *derPK = NULL; jthrowable excep; SECStatus status; SECItem nickname; jobject keyObj = NULL; SECKEYPrivateKey* privk = NULL; PK11SlotInfo *slot = NULL; unsigned int keyUsage; SECItem *publicValue = NULL; PR_ASSERT(env!=NULL && clazz!=NULL); if(keyArray == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } /* * copy the java byte arrays into local copies */ derPK = JSS_ByteArrayToSECItem(env, keyArray); if( derPK == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if( publicValueArray != NULL ) { publicValue = JSS_ByteArrayToSECItem(env, publicValueArray); if( publicValue == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } } /* * get the slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } nickname.len = 0; nickname.data = NULL; /* * enable the key for as many operations as possible */ keyUsage = KU_ALL; status = PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPK, &nickname, publicValue, PR_FALSE /*isPerm*/, PR_TRUE /*isPrivate*/, keyUsage, &privk, NULL /*wincx*/); if(status != SECSuccess) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to import private key info"); goto finish; } PR_ASSERT(privk != NULL); keyObj = JSS_PK11_wrapPrivKey(env, &privk); finish: /* Save any exceptions */ if( (excep=(*env)->ExceptionOccurred(env)) != NULL ) { (*env)->ExceptionClear(env); } if( derPK != NULL ) { SECITEM_FreeItem(derPK, PR_TRUE /*freeit*/); } if( publicValue != NULL ) { SECITEM_FreeItem(publicValue, PR_TRUE /*freeit*/); } /* now re-throw the exception */ if( excep ) { (*env)->Throw(env, excep); } return keyObj; } #define ZERO_SECITEM(item) (item).data=NULL; (item).len=0; /*********************************************************************** * getDSAParamsNative * * Returns a 3-element array of byte[]. The elements are P, Q, and G. */ JNIEXPORT jobjectArray JNICALL Java_org_mozilla_jss_pkcs11_PK11PrivKey_getDSAParamsNative (JNIEnv *env, jobject this) { SECKEYPrivateKey *key = NULL; PQGParams *pqgParams = NULL; /*----PQG parameters and friends----*/ SECItem P; /* prime */ SECItem Q; /* subPrime */ SECItem G; /* base */ /*----Java versions of the PQG parameters----*/ jobject jP = NULL; jobject jQ = NULL; jobject jG = NULL; jobjectArray pqgArray = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* clear the SECItems so we can free them indiscriminately at the end */ ZERO_SECITEM(P); ZERO_SECITEM(Q); ZERO_SECITEM(G); /* * Get the private key C structure */ if( JSS_PK11_getPrivKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* * Get the PQG params from the private key */ pqgParams = (PQGParams*)PK11_GetPQGParamsFromPrivateKey(key); if( pqgParams == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract PQG parameters from private key"); goto finish; } if( PK11_PQG_GetPrimeFromParams( pqgParams, &P) || PK11_PQG_GetSubPrimeFromParams( pqgParams, &Q) || PK11_PQG_GetBaseFromParams( pqgParams, &G) ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to extract PQG parameters from private key"); goto finish; } /* * Now turn them into byte arrays */ if( !(jP = JSS_OctetStringToByteArray(env, &P)) || !(jQ = JSS_OctetStringToByteArray(env, &Q)) || !(jG = JSS_OctetStringToByteArray(env, &G)) ) { goto finish; } /* * Stash the byte arrays into an array of arrays. */ pqgArray = (*env)->NewObjectArray( env, 3, (*env)->GetObjectClass(env, jP), NULL); if( pqgArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetObjectArrayElement(env, pqgArray, 0, jP); (*env)->SetObjectArrayElement(env, pqgArray, 1, jQ); (*env)->SetObjectArrayElement(env, pqgArray, 2, jG); finish: if(pqgParams!=NULL) { PK11_PQG_DestroyParams(pqgParams); } SECITEM_FreeItem(&P, PR_FALSE /*don't free P itself*/); SECITEM_FreeItem(&Q, PR_FALSE); SECITEM_FreeItem(&G, PR_FALSE); return pqgArray; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11PrivKey.java000066400000000000000000000100111326145000000220700ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.DSAParameterSpec; import java.security.interfaces.DSAParams; import org.mozilla.jss.util.*; import java.math.BigInteger; public class PK11PrivKey extends org.mozilla.jss.pkcs11.PK11Key implements PrivateKey { private PK11PrivKey() { } protected PK11PrivKey(byte[] pointer) { Assert._assert(pointer!=null); keyProxy = new PrivateKeyProxy(pointer); } /** * Make sure this key lives on the given token. */ public native void verifyKeyIsOnToken(PK11Token token) throws org.mozilla.jss.crypto.NoSuchItemOnTokenException; /** * Returns a new CryptoToken where this key resides. * * @return The PK11Token that owns this key. */ public native CryptoToken getOwningToken(); public native byte[] getUniqueID() throws TokenException; public native KeyType getKeyType(); public PrivateKey.Type getType() { KeyType kt = getKeyType(); if( kt == KeyType.RSA ) { return PrivateKey.Type.RSA; } else if (kt == KeyType.DSA) { return PrivateKey.Type.DSA; } else { Assert._assert(kt == KeyType.EC); return PrivateKey.Type.EC; } } public String getAlgorithm() { return getType().toString(); } /** * Returns the size in bits of the modulus of an RSA Private key. * Returns -1 for other types of keys. */ public native int getStrength(); /** * Imports a PrivateKeyInfo, storing it as a temporary PrivateKey * on the given token. * The key will be a temporary (session) key until it is imported * into a KeyStore, at which point it will be made a permanent (token) * object. */ public static PK11PrivKey fromPrivateKeyInfo(PKCS8EncodedKeySpec spec, CryptoToken token) throws TokenException { return fromPrivateKeyInfo(spec.getEncoded(), token); } /** * Imports a PrivateKeyInfo, storing it as a temporary PrivateKey * on the given token. * The key will be a temporary (session) key until it is imported * into a KeyStore, at which point it will be made a permanent (token) * object. */ public static PK11PrivKey fromPrivateKeyInfo(byte[] pki, CryptoToken token) throws TokenException { return fromPrivateKeyInfo(pki, token, null); } /** * Imports a PrivateKeyInfo, storing it as a temporary PrivateKey * on the given token. * The key will be a temporary (session) key until it is imported * into a KeyStore, at which point it will be made a permanent (token) * object. * @param publicValue An encoding of the public key, as used by the NSS * pk11wrap code. Don't use this unless you know what you're doing. */ public static native PK11PrivKey fromPrivateKeyInfo(byte[] pki, CryptoToken token, byte[] publicValue) throws TokenException; protected DSAParameterSpec getDSAParams() throws TokenException { byte[][] pqgArray = getDSAParamsNative(); return new DSAParameterSpec( new BigInteger(pqgArray[0]), new BigInteger(pqgArray[1]), new BigInteger(pqgArray[2]) ); } private native byte[][] getDSAParamsNative() throws TokenException; } class PrivateKeyProxy extends KeyProxy { public PrivateKeyProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); Debug.trace(Debug.OBNOXIOUS, "Finalizing a PrivateKeyProxy"); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11PubKey.c000066400000000000000000000426001326145000000212100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PublicKeyProxy.h" #include "_jni/org_mozilla_jss_pkcs11_PK11RSAPublicKey.h" #include "_jni/org_mozilla_jss_pkcs11_PK11DSAPublicKey.h" #include "_jni/org_mozilla_jss_pkcs11_PK11ECPublicKey.h" #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include "java_ids.h" #include #include /*********************************************************************** * PublicKeyProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PublicKeyProxy_releaseNativeResources (JNIEnv *env, jobject this) { SECKEYPublicKey *pubk; PRThread * VARIABLE_MAY_NOT_BE_USED pThread; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); /* Get the SECKEYPublicKey structure */ if(JSS_getPtrFromProxy(env, this, (void**) &pubk) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } PR_ASSERT(pubk != NULL); SECKEY_DestroyPublicKey(pubk); finish: PR_DetachThread(); return; } /*********************************************************************** ** JSS_PK11_wrapPubKey */ jobject JSS_PK11_wrapPubKey(JNIEnv *env, SECKEYPublicKey **pKey) { jobject pubKey=NULL; jclass keyClass; KeyType keyType; jmethodID constructor; jbyteArray ptr; char *keyClassName; PR_ASSERT(env!=NULL && pKey!=NULL); /* What kind of public key? */ keyType = (*pKey)->keyType; switch(keyType) { case rsaKey: keyClassName = PK11_RSA_PUBKEY_CLASS_NAME; break; case dsaKey: keyClassName = PK11_DSA_PUBKEY_CLASS_NAME; break; case ecKey: keyClassName = PK11_EC_PUBKEY_CLASS_NAME; break; default: keyClassName = PK11PUBKEY_CLASS_NAME; break; } keyClass = (*env)->FindClass(env, keyClassName); if(keyClass==NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, keyClass, PK11PUBKEY_CONSTRUCTOR_NAME, PK11PUBKEY_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } ptr = JSS_ptrToByteArray(env, (void*)*pKey); if(ptr == NULL) { ASSERT_OUTOFMEM(env); goto finish; } pubKey = (*env)->NewObject(env, keyClass, constructor, ptr); if(pubKey == NULL) { ASSERT_OUTOFMEM(env); goto finish; } *pKey = NULL; finish: if(pubKey==NULL && *pKey!=NULL) { SECKEY_DestroyPublicKey(*pKey); *pKey = NULL; } PR_DetachThread(); return pubKey; } /*********************************************************************** * Given a PublicKey object, extracts the SECKEYPublicKey* and stores it * at the given address. * * pubkObject: A JNI reference to a PublicKey object. * ptr: Address of a SECKEYPublicKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPubKeyPtr(JNIEnv *env, jobject pubkObject, SECKEYPublicKey** ptr) { PR_ASSERT(env!=NULL && pubkObject!=NULL); /* Get the pointer from the key proxy */ PR_ASSERT(sizeof(SECKEYPublicKey*) == sizeof(void*)); return JSS_getPtrFromProxyOwner(env, pubkObject, KEY_PROXY_FIELD, KEY_PROXY_SIG, (void**)ptr); } /*********************************************************************** * PK11PubKey.verifyKeyIsOnToken */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_verifyKeyIsOnToken (JNIEnv *env, jobject this, jobject token) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; SECKEYPublicKey *key = NULL; PK11SlotInfo *slot = NULL; PK11SlotInfo *keySlot = NULL; pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if( JSS_PK11_getPubKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if( JSS_PK11_getTokenSlotPtr(env, token, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } #if 0 keySlot = PK11_GetSlotFromPublicKey(key); #else keySlot = PK11_ReferenceSlot(key->pkcs11Slot); #endif if(keySlot == PK11_GetInternalKeySlot()) { /* hack for internal module */ if(slot != keySlot && slot != PK11_GetInternalSlot()) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } } else if(keySlot != slot) { JSS_throwMsg(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION, "Key is not present on this token"); goto finish; } finish: if(keySlot != NULL) { PK11_FreeSlot(keySlot); } PR_DetachThread(); } /*********************************************************************** * PK11PubKey.getKeyType * * Returns: The KeyType of this key. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_getKeyType (JNIEnv *env, jobject this) { PRThread * VARIABLE_MAY_NOT_BE_USED pThread; SECKEYPublicKey *pubk; KeyType keyType; char* keyTypeFieldName; jclass keyTypeClass; jfieldID keyTypeField; jobject keyTypeObject = NULL; PR_ASSERT(env!=NULL && this!=NULL); pThread = PR_AttachThread(PR_SYSTEM_THREAD, 0, NULL); PR_ASSERT(pThread != NULL); if(JSS_PK11_getPubKeyPtr(env, this, &pubk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); goto finish; } PR_ASSERT(pubk!=NULL); keyType = pubk->keyType; switch(keyType) { case nullKey: keyTypeFieldName = NULL_KEYTYPE_FIELD; break; case rsaKey: keyTypeFieldName = RSA_KEYTYPE_FIELD; break; case dsaKey: keyTypeFieldName = DSA_KEYTYPE_FIELD; break; case ecKey: keyTypeFieldName = EC_KEYTYPE_FIELD; break; case fortezzaKey: keyTypeFieldName = FORTEZZA_KEYTYPE_FIELD; break; case dhKey: keyTypeFieldName = DH_KEYTYPE_FIELD; break; case keaKey: keyTypeFieldName = KEA_KEYTYPE_FIELD; break; default: PR_ASSERT(PR_FALSE); keyTypeFieldName = NULL_KEYTYPE_FIELD; break; } keyTypeClass = (*env)->FindClass(env, KEYTYPE_CLASS_NAME); if(keyTypeClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeField = (*env)->GetStaticFieldID(env, keyTypeClass, keyTypeFieldName, KEYTYPE_FIELD_SIG); if(keyTypeField==NULL) { ASSERT_OUTOFMEM(env); goto finish; } keyTypeObject = (*env)->GetStaticObjectField( env, keyTypeClass, keyTypeField); if(keyTypeObject == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: PR_DetachThread(); return keyTypeObject; } typedef enum { DSA_P, DSA_Q, DSA_G, DSA_PUBLIC, RSA_MODULUS, RSA_PUBLIC_EXPONENT, EC_CURVE, EC_W } PublicKeyField; static jbyteArray get_public_key_info(JNIEnv *env, jobject this, PublicKeyField field); /********************************************************************** * * PK11RSAPublicKey.getModulusByteArray * * Returns the modulus of this RSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getModulusByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, RSA_MODULUS); } /********************************************************************** * * PK11RSAPublicKey.getPublicExponentByteArray * * Returns the modulus of this RSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getPublicExponentByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, RSA_PUBLIC_EXPONENT); } /********************************************************************** * * PK11DSAPublicKey.getPByteArray * * Returns the prime of this DSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getPByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_P); } /********************************************************************** * * PK11DSAPublicKey.getQByteArray * * Returns the subprime of this DSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getQByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_Q); } /********************************************************************** * * PK11DSAPublicKey.getGByteArray * * Returns the base of this DSA Public Key. The format is a big-endian * octet string in a byte array, suitable for importing into a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getGByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_G); } /********************************************************************** * * PK11DSAPublicKey.getYByteArray * * Returns the public value (Y) of this DSA Public Key. The format is a * big-endian octet string in a byte array, suitable for importing into * a BigInteger. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11DSAPublicKey_getYByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, DSA_PUBLIC); } /********************************************************************** * * PK11ECPublicKey.getParamByteArray * * Returns the curve of this EC Public Key. The format is a DER encoded * octet string in a byte array. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getCurveByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, EC_CURVE); } /********************************************************************** * * PK11ECPublicKey.getWByteArray * * Returns the public value (W) of this EC Public Key. * The format is a 1 byte to indicate compression followed by points * Wx and Wy unsigned and concatenated. * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11ECPublicKey_getWByteArray (JNIEnv *env, jobject this) { return get_public_key_info(env, this, EC_W); } /********************************************************************** * g e t _ p u b l i c _ k e y _ i n f o * * Looks up a field in a PK11PubKey and converts it to a Java byte array. * The field is assumed to be a SECItem big-endian octet string. The byte * array is suitable for feeding to a BigInteger constructor. */ static jbyteArray get_public_key_info (JNIEnv *env, jobject this, PublicKeyField field) { SECKEYPublicKey *pubk; jbyteArray byteArray=NULL; SECItem *item=NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getPubKeyPtr(env, this, &pubk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } switch( field ) { case DSA_P: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.params.prime; break; case DSA_Q: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.params.subPrime; break; case DSA_G: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.params.base; break; case DSA_PUBLIC: PR_ASSERT(pubk->keyType == dsaKey); item = &pubk->u.dsa.publicValue; break; case RSA_MODULUS: PR_ASSERT(pubk->keyType == rsaKey); item = &pubk->u.rsa.modulus; break; case RSA_PUBLIC_EXPONENT: PR_ASSERT(pubk->keyType == rsaKey); item = &pubk->u.rsa.publicExponent; break; case EC_CURVE: PR_ASSERT(pubk->keyType == ecKey); item = &pubk->u.ec.DEREncodedParams; break; case EC_W: PR_ASSERT(pubk->keyType == ecKey); item = &pubk->u.ec.publicValue; break; default: PR_ASSERT(PR_FALSE); break; } PR_ASSERT(item != NULL); byteArray = JSS_OctetStringToByteArray(env, item); if(byteArray == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: return byteArray; } /*********************************************************************** * * p u b k F r o m R a w * * Creates a PK11PubKey from its raw form. The raw form is a DER encoding * of the public key. For example, this is what is stored in a * SubjectPublicKeyInfo. */ static jobject pubkFromRaw(JNIEnv *env, CK_KEY_TYPE type, jbyteArray rawBA) { jobject pubkObj=NULL; SECKEYPublicKey *pubk=NULL; SECItem *pubkDER=NULL; /* validate args */ PR_ASSERT(env!=NULL); if( rawBA == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } pubkDER = JSS_ByteArrayToSECItem(env, rawBA); if( pubkDER == NULL ) { /* exception was thrown */ goto finish; } pubk = SECKEY_ImportDERPublicKey(pubkDER, type); if( pubk == NULL ) { JSS_throw(env, INVALID_KEY_FORMAT_EXCEPTION); goto finish; } /* this clears pubk */ pubkObj = JSS_PK11_wrapPubKey(env, &pubk); if( pubkObj == NULL ) { /* exception was thrown */ goto finish; } finish: if(pubkDER!=NULL) { SECITEM_FreeItem(pubkDER, PR_TRUE /*freeit*/); } return pubkObj; } /*********************************************************************** * * PK11PubKey.fromRawNative */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_fromRawNative (JNIEnv *env, jclass clazz, jint type, jbyteArray rawBA) { return pubkFromRaw(env, type, rawBA); } /*********************************************************************** * * PK11PubKey.RSAfromRaw * Deprecated: call fromRawNative instead. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_RSAFromRaw (JNIEnv *env, jclass clazz, jbyteArray rawBA) { return pubkFromRaw(env, CKK_RSA, rawBA); } /*********************************************************************** * * PK11PubKey.DSAfromRaw * Deprecated: call fromRawNative instead. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_DSAFromRaw (JNIEnv *env, jclass clazz, jbyteArray rawBA) { return pubkFromRaw(env, CKK_DSA, rawBA); } /*********************************************************************** * * PK11PubKey.getEncoded * * Converts the public key to a SubjectPublicKeyInfo, and returns its * DER-encoding. */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_getEncoded (JNIEnv *env, jobject this) { SECKEYPublicKey *pubk; jbyteArray encodedBA=NULL; SECItem *spkiDER=NULL; /* get the public key */ if( JSS_PK11_getPubKeyPtr(env, this, &pubk) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } spkiDER = PK11_DEREncodePublicKey(pubk); if( spkiDER == NULL ) { JSS_trace(env, JSS_TRACE_ERROR, "unable to DER-encode" " SubjectPublicKeyInfo"); JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* convert the der-encoding to a Java byte array */ encodedBA = JSS_SECItemToByteArray(env, spkiDER); finish: if(spkiDER!=NULL) { SECITEM_FreeItem(spkiDER, PR_TRUE /*freeit*/); } return encodedBA; } /*********************************************************************** * * PK11PubKey.fromSPKI * * Generates a PK11PubKey from a DER-encoded SubjectPublicKeyInfo. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11PubKey_fromSPKI (JNIEnv *env, jobject this, jbyteArray spkiBA) { jobject pubkObj = NULL; SECItem *spkiItem = NULL; CERTSubjectPublicKeyInfo *spki = NULL; SECKEYPublicKey *pubk = NULL; /* * convert byte array to SECItem */ spkiItem = JSS_ByteArrayToSECItem(env, spkiBA); if( spkiItem == NULL ) { /* exception was thrown */ goto finish; } /* * convert SECItem to SECKEYPublicKey */ spki = SECKEY_DecodeDERSubjectPublicKeyInfo(spkiItem); if( spki == NULL ) { JSS_throwMsg(env, INVALID_KEY_FORMAT_EXCEPTION, "Unable to decode DER-encoded SubjectPublicKeyInfo: " "invalid DER encoding"); goto finish; } pubk = SECKEY_ExtractPublicKey(spki); if( pubk == NULL ) { JSS_throwMsg(env, INVALID_KEY_FORMAT_EXCEPTION, "Unable to decode SubjectPublicKeyInfo: DER encoding problem, or" " unrecognized key type "); goto finish; } /* * put a Java wrapper around it */ pubkObj = JSS_PK11_wrapPubKey(env, &pubk); /* this clears pubk */ if( pubkObj == NULL ) { /* exception was thrown */ goto finish; } finish: if( spkiItem != NULL ) { SECITEM_FreeItem(spkiItem, PR_TRUE /*freeit*/); } if( spki != NULL ) { SECKEY_DestroySubjectPublicKeyInfo(spki); } if( pubk != NULL ) { SECKEY_DestroyPublicKey(pubk); } return pubkObj; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11PubKey.java000066400000000000000000000063671326145000000217210ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.util.*; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.InvalidKeyFormatException; public class PK11PubKey extends org.mozilla.jss.pkcs11.PK11Key implements java.security.PublicKey { protected PK11PubKey(byte[] pointer) { Assert._assert(pointer!=null); keyProxy = new PublicKeyProxy(pointer); } /** * Make sure this key lives on the given token. */ public native void verifyKeyIsOnToken(PK11Token token) throws org.mozilla.jss.crypto.NoSuchItemOnTokenException; public native KeyType getKeyType(); public String getAlgorithm() { return getKeyType().toString(); } /** * Creates a PK11PubKey from its raw form. The raw form is a DER encoding * of the public key. For example, this is what is stored in a * SubjectPublicKeyInfo. * * @param type The type of private key to be decoded. * @param rawKey The bytes of the raw key. * @exception InvalidKeyFormatException If the raw key could not be * decoded. * @deprecated This method works for RSA keys but not DSA or EC keys. Use * fromSPKI() instead. * @see #fromSPKI(byte[]) */ public static PK11PubKey fromRaw(PrivateKey.Type type, byte[] rawKey) throws InvalidKeyFormatException { if( type != PrivateKey.Type.RSA ) { throw new InvalidKeyFormatException( "fromRaw() is broken for DSA keys. Use fromSPKI() instead."); } return fromRawNative( type.getPKCS11Type(), rawKey ); } /** * param type The PKCS #11 type of the key (CKK_). */ private static native PK11PubKey fromRawNative(int type, byte[] rawKey) throws InvalidKeyFormatException; /** * Creates a PK11PubKey from a SubjectPublicKeyInfo. * * @param spki The BER-encoded SubjectPublicKeyInfo. * @exception InvalidKeyFormatException If the SPKI could not be * decoded. */ public static native PK11PubKey fromSPKI(byte[] spki) throws InvalidKeyFormatException; /** * deprecated Use fromRawNative instead. */ private static native PK11PubKey RSAFromRaw(byte[] rawKey); /** * deprecated Use fromRawNative instead. */ private static native PK11PubKey DSAFromRaw(byte[] rawKey); /** * Returns a DER-encoded SubjectPublicKeyInfo representing this key. */ public native byte[] getEncoded(); /** * The name of the primary encoding format of this key. The primary * encoding format is X.509 SubjectPublicKeyInfo, and the name * is "X.509". */ public String getFormat() { return "X.509"; } } class PublicKeyProxy extends KeyProxy { public PublicKeyProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); Debug.trace(Debug.OBNOXIOUS, "Releasing a PublicKeyProxy"); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11RSAPrivateKey.java000066400000000000000000000011601326145000000231350ustar00rootroot00000000000000package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.util.Assert; import java.math.BigInteger; class PK11RSAPrivateKey extends PK11PrivKey implements java.security.interfaces.RSAPrivateKey { private PK11RSAPrivateKey() { super(null); } protected PK11RSAPrivateKey(byte[] pointer) { super(pointer); } public PrivateKey.Type getType() { return PrivateKey.Type.RSA; } public BigInteger getModulus() { // !!! return null; } public BigInteger getPrivateExponent() { // !!! return null; } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11RSAPublicKey.java000066400000000000000000000017361326145000000227520ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.util.Assert; import java.security.interfaces.RSAPublicKey; import java.math.BigInteger; public class PK11RSAPublicKey extends PK11PubKey implements RSAPublicKey { public PK11RSAPublicKey(byte[] pointer) { super(pointer); } public BigInteger getModulus() { try { return new BigInteger(getModulusByteArray()); } catch( NumberFormatException e) { return null; } } private native byte[] getModulusByteArray(); public BigInteger getPublicExponent() { try { return new BigInteger(getPublicExponentByteArray()); } catch( NumberFormatException e) { return null; } } private native byte[] getPublicExponentByteArray(); } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11SecureRandom.c000066400000000000000000000126261326145000000224050ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * NSS and NSPR header files */ #include #include /* * JNI header files */ #include "_jni/org_mozilla_jss_pkcs11_PK11SecureRandom.h" /* * JSS header files */ #include /* * JNI FUNCTION: PK11SecureRandom.setSeed * * JNI FUNCTION TYPE: protected * * JNI INPUTS: * * env * The JNI object through which all JNI functions are referenced * * this * A JNI reference to the class which defines this native method * * INPUTS: * * N/A * * OUTPUTS: * * jseed * A JNI array for storage of the random byte seed sequence * * ERRORS: * * N/A * * RETURN: * * Upon success, this method returns a byte array * containing a random byte sequence * * NOTES: * * This routine is called to seed the pseudo-random number generator. * * JNI NOTES: * * Class: org_mozilla_jss_pkcs11_PK11SecureRandom * Method: setSeed * Signature: ([B)V */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11SecureRandom_setSeed ( JNIEnv* env, jobject this, jbyteArray jseed ) { /* * "JNI" data members */ jbyte* jdata = NULL; jboolean jIsCopy = JNI_FALSE; jsize jlen = 0; /* * "C" data members */ PRThread* VARIABLE_MAY_NOT_BE_USED pThread = NULL; SECStatus status = PR_FALSE; PK11SlotInfo* slot = NULL; /* * Perform initial assertions */ PR_ASSERT( env != NULL && this != NULL ); /* * Attach to the external java thread */ pThread = PR_AttachThread( PR_SYSTEM_THREAD, 0, NULL ); PR_ASSERT( pThread != NULL ); /* * Obtain the appropriate "slot" */ slot = PK11_GetBestSlot( CKM_FAKE_RANDOM, NULL ); if( slot == NULL ) { PR_ASSERT( PR_FALSE ); goto loser; } /* * Convert "JNI jbyteArray" into "JNI jbyte*" so * that it can be cast into a "C unsigned char*" */ jdata = ( *env )->GetByteArrayElements( env, jseed, &jIsCopy ); /* * Retrieve the length of the "JNI jbyteArray" * so that it can be cast into a "C int" */ jlen = ( *env )->GetArrayLength( env, jseed ); /* * Seed the pseudo-random number generator; * currently, failures from this routine are ignored */ status = PK11_SeedRandom( slot, ( unsigned char* ) jdata, ( int ) jlen ); if( status != SECSuccess ) { PR_ASSERT( PR_FALSE ); goto loser; } loser: /* * Copy back the contents of the "JNI jbyte*" and * free any resources associated with it */ if( jIsCopy == JNI_TRUE ) { ( *env )->ReleaseByteArrayElements( env, jseed, jdata, 0 ); } /* * Free any "C" resources */ if( slot != NULL ) { PK11_FreeSlot( slot ); } slot = NULL; /* * Detach from the external java thread and return */ PR_DetachThread(); return; } /* * JNI FUNCTION: PK11SecureRandom.nextBytes * * JNI FUNCTION TYPE: protected * * JNI INPUTS: * * env * The JNI object through which all JNI functions are referenced * * this * A JNI reference to the class which defines this native method * * INPUTS: * * N/A * * OUTPUTS: * * jbytes * A JNI array for storage of the random byte sequence * * ERRORS: * * N/A * * RETURN: * * Upon success, this method returns a byte array * containing a random byte sequence * * NOTES: * * This routine is called to generate a pseudo-random number. * * JNI NOTES: * * Class: org_mozilla_jss_pkcs11_PK11SecureRandom * Method: nextBytes * Signature: ([B)V */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11SecureRandom_nextBytes ( JNIEnv* env, jobject this, jbyteArray jbytes ) { /* * "JNI" data members */ jbyte* jdata = NULL; jboolean jIsCopy = JNI_FALSE; jsize jlen = 0; /* * "C" data members */ PRThread* VARIABLE_MAY_NOT_BE_USED pThread = NULL; SECStatus status = PR_FALSE; /* * Perform initial assertions */ PR_ASSERT( env != NULL && this != NULL ); /* * Attach to the external java thread */ pThread = PR_AttachThread( PR_SYSTEM_THREAD, 0, NULL ); PR_ASSERT( pThread != NULL ); /* * Convert "JNI jbyteArray" into "JNI jbyte*" so * that it can be cast into a "C unsigned char*" */ jdata = ( *env )->GetByteArrayElements( env, jbytes, &jIsCopy ); /* * Retrieve the length of the "JNI jbyteArray" * so that it can be cast into a "C int" */ jlen = ( *env )->GetArrayLength( env, jbytes ); /* * Generate a pseudo-random number; currently, * failures from this routine are ignored */ status = PK11_GenerateRandom( ( unsigned char* ) jdata, ( int ) jlen ); if( status != SECSuccess ) { goto loser; } loser: /* * Copy back the contents of the "JNI jbyte*" and * free any resources associated with it */ if( jIsCopy == JNI_TRUE ) { ( *env )->ReleaseByteArrayElements( env, jbytes, jdata, 0 ); } /* * Detach from the external java thread and return */ PR_DetachThread(); return; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11SecureRandom.java000066400000000000000000000023231326145000000230750ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import java.util.*; import org.mozilla.jss.util.*; import org.mozilla.jss.crypto.*; /** * A random number generator for PKCS #11. * * @see org.mozilla.jss.CryptoManager */ public final class PK11SecureRandom implements org.mozilla.jss.crypto.JSSSecureRandom { //////////////////////////////////////////////////// // construction and finalization //////////////////////////////////////////////////// public PK11SecureRandom() {} //////////////////////////////////////////////////// // public routines //////////////////////////////////////////////////// public synchronized native void setSeed( byte[] seed ); public void setSeed( long seed ) { byte[] data = new byte[8]; // convert long into 8-byte byte array for( int i = 0; i < 8; i++ ) { data[i] = ( byte ) ( seed >> ( 8 * i ) ); } setSeed( data ); } public synchronized native void nextBytes( byte bytes[] ); } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Signature.c000066400000000000000000000501171326145000000217540ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include "_jni/org_mozilla_jss_pkcs11_PK11Signature.h" #include "_jni/org_mozilla_jss_pkcs11_SigContextProxy.h" #include #include #include #include #include #include #include #include "pk11util.h" static PRStatus getPrivateKey(JNIEnv *env, jobject sig, SECKEYPrivateKey**key); static PRStatus getPublicKey(JNIEnv *env, jobject sig, SECKEYPublicKey**key); static PRStatus getSomeKey(JNIEnv *env, jobject sig, void **key, short type); static SECOidTag getAlgorithm(JNIEnv *env, jobject sig); static void setSigContext(JNIEnv *env, jobject sig, jobject context); static PRStatus getSigContext(JNIEnv *env, jobject sig, void**pContext, SigContextType* pType); /*********************************************************************** * * PK11Signature.initSigContext */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_initSigContext (JNIEnv *env, jobject this) { SGNContext *ctxt=NULL; jobject contextProxy=NULL; SECKEYPrivateKey *privk; /* Extract the private key from the PK11Signature */ if( getPrivateKey(env, this, &privk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* Start the signing operation */ ctxt = SGN_NewContext(getAlgorithm(env, this), privk); if(ctxt == NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to create signing context"); goto finish; } if( SGN_Begin(ctxt) != SECSuccess ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to begin signing context"); goto finish; } /* Create a contextProxy and stick it in the PK11Signature object */ contextProxy = JSS_PK11_wrapSigContextProxy(env, (void**)&ctxt, SGN_CONTEXT); if(contextProxy == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } setSigContext(env, this, contextProxy); finish: if(contextProxy==NULL && ctxt!=NULL) { /* we created a context but not the Java wrapper, so we need to * delete the context here. */ SGN_DestroyContext(ctxt, PR_TRUE /*freeit*/); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_initVfyContext (JNIEnv *env, jobject this) { VFYContext *ctxt=NULL; jobject contextProxy=NULL; SECKEYPublicKey *pubk; if( getPublicKey(env, this, &pubk) != PR_SUCCESS ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } ctxt = VFY_CreateContext(pubk, NULL /*sig*/, getAlgorithm(env, this), NULL /*wincx*/); if( ctxt == NULL) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to create verification context"); goto finish; } if( VFY_Begin(ctxt) != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to begin verification context"); goto finish; } /* create a ContextProxy and stick it in the PK11Signature object */ contextProxy = JSS_PK11_wrapSigContextProxy(env, (void**)&ctxt, VFY_CONTEXT); if(contextProxy == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } setSigContext(env, this, contextProxy); finish: if(contextProxy==NULL && ctxt!=NULL) { /* we created a context but not the Java wrapper, so we need to * delete the context here */ VFY_DestroyContext(ctxt, PR_TRUE /*freeit*/); } } /********************************************************************** * * PK11Signature.engineUpdateNative * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineUpdateNative (JNIEnv *env, jobject this, jbyteArray bArray, jint offset, jint length) { SigContextType type; void *ctxt; jbyte *bytes=NULL; jint numBytes; /* Extract the signature context */ if( getSigContext(env, this, &ctxt, &type) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(ctxt != NULL); /* Get the bytes to be updated */ bytes = (*env)->GetByteArrayElements(env, bArray, NULL); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } numBytes = (*env)->GetArrayLength(env, bArray); PR_ASSERT(numBytes > 0); if( offset < 0 || offset >= numBytes || length < 0 || (offset+length) > numBytes || (offset+length) < 0 ) { JSS_throw(env, ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION); goto finish; } /* Update the context */ if(type == SGN_CONTEXT) { if( SGN_Update( (SGNContext*)ctxt, (unsigned char*)bytes + offset, (unsigned)length ) != SECSuccess) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "update failed"); goto finish; } } else { PR_ASSERT( type == VFY_CONTEXT ); if( VFY_Update( (VFYContext*)ctxt, (unsigned char*)bytes + offset, (unsigned) length ) != SECSuccess) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "update failed"); goto finish; } } finish: if(bytes!=NULL) { (*env)->ReleaseByteArrayElements(env, bArray, bytes, JNI_ABORT); } } /********************************************************************** * * PK11Signature.engineSignNative * */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineSignNative (JNIEnv *env, jobject this) { SGNContext *ctxt; SigContextType type; SECItem signature; jbyteArray sigArray=NULL; jbyte *sigBytes=NULL; PR_ASSERT(env!=NULL && this!=NULL); signature.data = NULL; /* * Extract the signature context from the Java wrapper */ if( getSigContext(env, this, (void**)&ctxt, &type) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(ctxt!=NULL && type==SGN_CONTEXT); /* * Finish the signing operation. */ if( SGN_End(ctxt, &signature) != SECSuccess) { JSS_throwMsgPrErr(env, SIGNATURE_EXCEPTION, "Signing operation failed"); goto finish; } /* * Convert SECItem signature to Java byte array */ sigArray = (*env)->NewByteArray(env, signature.len); if(sigArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } sigBytes = (*env)->GetByteArrayElements(env, sigArray, NULL); if(sigBytes == NULL) { ASSERT_OUTOFMEM(env); goto finish; } memcpy(sigBytes, signature.data, signature.len); finish: if(sigBytes != NULL) { (*env)->ReleaseByteArrayElements(env, sigArray, sigBytes, 0); } if( signature.data != NULL ) { PR_Free(signature.data); } return sigArray; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineVerifyNative (JNIEnv *env, jobject this, jbyteArray sigArray) { jboolean verified = JNI_FALSE; VFYContext *ctxt; SigContextType type; SECItem sigItem = {siBuffer, NULL, 0}; PR_ASSERT( env!=NULL && this!=NULL && sigArray!=NULL); /* * Lookup the context */ if( getSigContext(env, this, (void**)&ctxt, &type) != PR_SUCCESS) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Unable to retrieve verification context"); goto finish; } if(type != VFY_CONTEXT) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Verification engine has signature context"); goto finish; } /* * Convert signature to SECItem */ sigItem.data = (unsigned char*) (*env)->GetByteArrayElements(env, sigArray, 0); if(sigItem.data == NULL) { ASSERT_OUTOFMEM(env); goto finish; } sigItem.len = (*env)->GetArrayLength(env, sigArray); /* * Finish the verification operation */ if( VFY_EndWithSignature(ctxt, &sigItem) == SECSuccess) { verified = JNI_TRUE; } else if( PR_GetError() != SEC_ERROR_BAD_SIGNATURE) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Failed to complete verification operation"); goto finish; } finish: if(sigItem.data!=NULL) { (*env)->ReleaseByteArrayElements( env, sigArray, (jbyte*)sigItem.data, JNI_ABORT); } return verified; } /* * Extract the algorithm from a PK11Signature. * * sig: a PK11Signature. * Returns: the algorithm of this signature, or SEC_OID_UNKNOWN if an * error occurs. */ static SECOidTag getAlgorithm(JNIEnv *env, jobject sig) { jclass sigClass; jfieldID algField; jobject alg; SECOidTag retval=SEC_OID_UNKNOWN; PR_ASSERT(env!=NULL && sig!=NULL); sigClass = (*env)->GetObjectClass(env, sig); PR_ASSERT(sigClass != NULL); algField = (*env)->GetFieldID( env, sigClass, SIG_ALGORITHM_FIELD, SIG_ALGORITHM_SIG); if(algField == NULL) { ASSERT_OUTOFMEM(env); goto finish; } alg = (*env)->GetObjectField(env, sig, algField); if(alg == NULL) { ASSERT_OUTOFMEM(env); goto finish; } retval = JSS_getOidTagFromAlg(env, alg); finish: return retval; } /* * Set the contextProxy member of a PK11Signature. * * sig: the PK11Signature whose contextProxy we are setting. * context: the ContextProxy we are setting in the signature. It may be NULL. **/ static void setSigContext(JNIEnv *env, jobject sig, jobject context) { jclass sigClass; jfieldID contextField; PR_ASSERT(env!=NULL && sig!=NULL); sigClass = (*env)->GetObjectClass(env, sig); PR_ASSERT(sigClass!=NULL); contextField = (*env)->GetFieldID( env, sigClass, SIG_CONTEXT_PROXY_FIELD, SIG_CONTEXT_PROXY_SIG); if(contextField == NULL) { ASSERT_OUTOFMEM(env); /* This function doesn't advertise that it can throw exceptions, * so we shouldn't throw one */ (*env)->ExceptionClear(env); return; } (*env)->SetObjectField(env, sig, contextField, context); } /* * Don't call this if there is no context. */ static PRStatus getSigContext(JNIEnv *env, jobject sig, void**pContext, SigContextType* pType) { jfieldID contextField; jclass sigClass; jobject proxy; PR_ASSERT(env!=NULL && sig!=NULL && pContext!=NULL && pType!=NULL); sigClass = (*env)->GetObjectClass(env, sig); #ifdef DEBUG { jclass realSigClass = (*env)->FindClass(env, PK11SIGNATURE_CLASS_NAME); PR_ASSERT( (*env)->IsInstanceOf(env, sig, realSigClass) ); } #endif contextField = (*env)->GetFieldID(env, sigClass, SIG_CONTEXT_PROXY_FIELD, SIG_CONTEXT_PROXY_SIG); if(contextField == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } proxy = (*env)->GetObjectField(env, sig, contextField); if(proxy == NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, TOKEN_EXCEPTION); return PR_FAILURE; } if( JSS_PK11_getSigContext(env, proxy, pContext, pType) != PR_SUCCESS ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return PR_FAILURE; } PR_ASSERT(*pContext != NULL); return PR_SUCCESS; } #define PUBLICKEYTYPE 0 #define PRIVATEKEYTYPE 1 /********************************************************************** * * g e t P r i v a t e K e y */ static PRStatus getPrivateKey(JNIEnv *env, jobject sig, SECKEYPrivateKey**key) { return getSomeKey(env, sig, (void**)key, PRIVATEKEYTYPE); } /********************************************************************** * * g e t P u b l i c K e y */ static PRStatus getPublicKey(JNIEnv *env, jobject sig, SECKEYPublicKey**key) { return getSomeKey(env, sig, (void**)key, PUBLICKEYTYPE); } static PRStatus getSomeKey(JNIEnv *env, jobject sig, void **key, short type) { jfieldID keyField; jclass sigClass; jobject keyProxy; PR_ASSERT(env!=NULL && sig!=NULL && key!=NULL); sigClass = (*env)->GetObjectClass(env, sig); #ifdef DEBUG { jclass realSigClass = (*env)->FindClass(env, PK11SIGNATURE_CLASS_NAME); PR_ASSERT( (*env)->IsInstanceOf(env, sig, realSigClass) ); } #endif keyField = (*env)->GetFieldID(env, sigClass, SIG_KEY_FIELD, SIG_KEY_SIG); if(keyField == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } keyProxy = (*env)->GetObjectField(env, sig, keyField); if(keyProxy == NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, TOKEN_EXCEPTION); return PR_FAILURE; } if(type == PRIVATEKEYTYPE) { if( JSS_PK11_getPrivKeyPtr(env, keyProxy, (SECKEYPrivateKey**)key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return PR_FAILURE; } } else { if( JSS_PK11_getPubKeyPtr(env, keyProxy, (SECKEYPublicKey**)key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return PR_FAILURE; } } PR_ASSERT(*key != NULL); return PR_SUCCESS; } struct SigContextProxyStr { void *ctxt; SigContextType type; }; /*********************************************************************** * J S S _ P K 1 1 _ g e t S i g C o n t e x t * * Extracts the context pointer from a SigContextProxy. * proxy: a non-NULL SigContextProxy object. * pContext: address of a SGNContext* or VFYContext* where the pointer will be * stored. * pType: address of a SigContextType where will be stored the type * of the context either SGN_CONTEXT or VFY_CONTEXT. * Returns: PR_SUCCESS, unless an exception was thrown. */ PRStatus JSS_PK11_getSigContext(JNIEnv *env, jobject proxy, void**pContext, SigContextType *pType) { SigContextProxy *ctxtProxy; PR_ASSERT(env!=NULL && proxy!=NULL && pContext!=NULL && pType!=NULL); if( JSS_getPtrFromProxy(env, proxy, (void**)&ctxtProxy) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } /* Make sure the pointers are OK */ if(ctxtProxy==NULL || ctxtProxy->ctxt==NULL) { PR_ASSERT(PR_FALSE); JSS_throw(env, SIGNATURE_EXCEPTION); return PR_FAILURE; } /* Everything looks good, return the pointer */ *pContext = ctxtProxy->ctxt; *pType = ctxtProxy->type; return PR_SUCCESS; } /********************************************************************** * * J S S _ P K 1 1 _ w r a p S i g C o n t e x t P r o x y * * Wraps a SGNContext in a SigContextProxy. * * ctxt: address of ptr to a SGNContext or VfyContext, which must not be NULL. * It will be eaten by the wrapper and set to NULL. * * type: type of context, either SGN_CONTEXT or VFY_CONTEXT * Returns: a new SigContextProxy object wrapping the given SGNContext, or * NULL if an exception was thrown. */ jobject JSS_PK11_wrapSigContextProxy(JNIEnv *env, void **ctxt, SigContextType type) { jclass proxyClass; jmethodID constructor; jbyteArray byteArray; SigContextProxy *proxy=NULL; jobject Context=NULL; PR_ASSERT(env!=NULL && ctxt!=NULL && *ctxt!=NULL); /* Create the proxy structure */ proxy = (SigContextProxy*) PR_Malloc(sizeof(SigContextProxy)); if(proxy == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } proxy->ctxt = *ctxt; proxy->type = type; byteArray = JSS_ptrToByteArray(env, (void*)proxy); /* * Lookup the class and constructor */ proxyClass = (*env)->FindClass(env, SIG_CONTEXT_PROXY_CLASS_NAME); if( proxyClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, proxyClass, SIG_CONTEXT_PROXY_CONSTRUCTOR_NAME, SIG_CONTEXT_PROXY_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* call the constructor */ Context = (*env)->NewObject(env, proxyClass, constructor, byteArray); finish: if(Context==NULL) { /* didn't work, so free resources */ if(proxy!=NULL) { PR_Free(proxy); } if(type==SGN_CONTEXT) { SGN_DestroyContext( (SGNContext*)*ctxt, PR_TRUE /*freeit*/); } else { PR_ASSERT(type == VFY_CONTEXT); VFY_DestroyContext( (VFYContext*)*ctxt, PR_TRUE /*freeit*/); } } *ctxt = NULL; return Context; } /*********************************************************************** * * SigContextProxy.releaseNativeResources * * Deletes the SGNContext wrapped by this SigContextProxy object. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_SigContextProxy_releaseNativeResources (JNIEnv *env, jobject this) { SigContextProxy *proxy; /* Retrieve the proxy pointer */ if( JSS_getPtrFromProxy(env, this, (void**)&proxy) != PR_SUCCESS) { #ifdef DEBUG PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); PR_fprintf(PR_STDERR, "ERROR: native signature context was not released\n"); #endif goto finish; } PR_ASSERT(proxy!=NULL); /* Free the context and the proxy */ if(proxy->type == SGN_CONTEXT) { SGN_DestroyContext( (SGNContext*)proxy->ctxt, PR_TRUE /*freeit*/); } else { PR_ASSERT(proxy->type == VFY_CONTEXT); VFY_DestroyContext( (VFYContext*)proxy->ctxt, PR_TRUE /*freeit*/); } PR_Free(proxy); finish: ; } /*********************************************************************** * PK11Signature.engineRawSignNative */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawSignNative (JNIEnv *env, jclass clazz, jobject tokenObj, jobject keyObj, jbyteArray hashBA) { SECKEYPrivateKey *key = NULL; SECItem *sig = NULL; SECItem *hash = NULL; jbyteArray sigBA = NULL; PR_ASSERT(env!=NULL && tokenObj!=NULL && keyObj!=NULL && hashBA!=NULL); /* Get the private key */ if( JSS_PK11_getPrivKeyPtr(env, keyObj, &key) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* get the hash */ hash = JSS_ByteArrayToSECItem(env, hashBA); /* prepare space for the sig */ sig = PR_NEW(SECItem); sig->len = PK11_SignatureLen(key); sig->data = PR_Malloc(sig->len); /* perform the signature operation */ if( PK11_Sign(key, sig, hash) != SECSuccess ) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Signature operation failed" " on token"); goto finish; } /* convert signature to byte array */ sigBA = JSS_SECItemToByteArray(env, sig); finish: if(sig) { SECITEM_FreeItem(sig, PR_TRUE /*freeit*/); } if(hash) { SECITEM_FreeItem(hash, PR_TRUE /*freeit*/); } return sigBA; } /*********************************************************************** * PK11Signature.engineRawVerifyNative */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Signature_engineRawVerifyNative (JNIEnv *env, jclass clazz, jobject tokenObj, jobject keyObj, jbyteArray hashBA, jbyteArray sigBA) { SECItem *sig=NULL; SECItem *hash=NULL; SECKEYPublicKey *key=NULL; jboolean verified=JNI_FALSE; SECStatus status; PR_ASSERT(env!=NULL && tokenObj!=NULL && keyObj!=NULL && hashBA!=NULL && sigBA!=NULL); sig = JSS_ByteArrayToSECItem(env, sigBA); if(sig==NULL) { goto finish; } hash = JSS_ByteArrayToSECItem(env, hashBA); if(hash==NULL) { goto finish; } if( JSS_PK11_getPubKeyPtr(env, keyObj, &key) != PR_SUCCESS ) { goto finish; } /* perform the operation */ status = PK11_Verify(key, sig, hash, NULL /*wincx*/); if( status == SECSuccess ) { verified = JNI_TRUE; } else if( PR_GetError() != SEC_ERROR_BAD_SIGNATURE ) { JSS_throwMsg(env, SIGNATURE_EXCEPTION, "Verification operation" " failed on token"); goto finish; } finish: if(sig) { SECITEM_FreeItem(sig, PR_TRUE /*freeit*/); } if(hash) { SECITEM_FreeItem(hash, PR_TRUE /*freeit*/); } return verified; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Signature.java000066400000000000000000000245511326145000000224560ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import java.security.spec.AlgorithmParameterSpec; import java.security.*; import java.security.SecureRandom; import java.io.ByteArrayOutputStream; import org.mozilla.jss.crypto.PrivateKey; final class PK11Signature extends org.mozilla.jss.crypto.SignatureSpi { public PK11Signature(PK11Token token, SignatureAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { Assert._assert(token!=null && algorithm!=null); // Make sure this token supports this algorithm. It's OK if // it only supports the signing part; the hashing can be done // on the internal module. if( ! token.doesAlgorithm(algorithm) && ! token.doesAlgorithm(algorithm.getSigningAlg()) ) { throw new NoSuchAlgorithmException(); } this.tokenProxy = token.getProxy(); this.token = token; this.algorithm = algorithm; if( algorithm.getRawAlg() == algorithm ) { raw = true; rawInput = new ByteArrayOutputStream(); } this.state = UNINITIALIZED; } public void engineInitSign(org.mozilla.jss.crypto.PrivateKey privateKey) throws InvalidKeyException, TokenException { PK11PrivKey privKey; Assert._assert(privateKey!=null); // // Scrutinize the key. Make sure it: // -is a PKCS #11 key // -lives on this token // -is the right type for the algorithm // if( privateKey == null ) { throw new InvalidKeyException("private key is null"); } if( ! (privateKey instanceof PK11PrivKey) ) { throw new InvalidKeyException("privateKey is not a PKCS #11 "+ "private key"); } privKey = (PK11PrivKey) privateKey; try { privKey.verifyKeyIsOnToken(token); } catch(NoSuchItemOnTokenException e) { throw new InvalidKeyException(e.toString()); } try { if( KeyType.getKeyTypeFromAlgorithm(algorithm) != privKey.getKeyType()) { throw new InvalidKeyException( "Key type is inconsistent with algorithm"); } } catch( NoSuchAlgorithmException e ) { Assert.notReached("unknown algorithm: "+algorithm); throw new InvalidKeyException(); } // Finally, the key is OK key = privKey; // Now initialize the signature context if( ! raw ) { sigContext = null; initSigContext(); } // Don't set state until we know everything worked state = SIGN; } /************************************************************* ** This is just here for JCA compliance, we don't take randoms this way. */ public void engineInitSign(org.mozilla.jss.crypto.PrivateKey privateKey, SecureRandom random) throws InvalidKeyException, TokenException { Assert.notReached("This function is not supported"); engineInitSign(privateKey); } /************************************************************* ** Creates a signing context, initializes it, ** and sets the sigContext field. */ protected native void initSigContext() throws TokenException; public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException, TokenException { PK11PubKey pubKey; Assert._assert(publicKey!=null); // // Scrutinize the key. Make sure it: // -is a PKCS #11 key // -lives on this token // -is the right type for the algorithm // if( ! (publicKey instanceof PK11PubKey) ) { throw new InvalidKeyException("publicKey is not a PKCS #11 "+ "public key"); } pubKey = (PK11PubKey) publicKey; //try { // pubKey.verifyKeyIsOnToken(token); //} catch( NoSuchItemOnTokenException e) { // throw new InvalidKeyException(e.toString()); //} try { if( KeyType.getKeyTypeFromAlgorithm(algorithm) != pubKey.getKeyType()) { throw new InvalidKeyException( "Key type is inconsistent with algorithm"); } } catch( NoSuchAlgorithmException e ) { Assert.notReached("unknown algorithm: "+algorithm); throw new InvalidKeyException(); } key = pubKey; if( ! raw ) { sigContext = null; initVfyContext(); } // Don't set state until we know everything worked. state = VERIFY; } protected native void initVfyContext() throws TokenException; public void engineUpdate(byte b) throws SignatureException, TokenException { engineUpdate(new byte[] {b}, 0, 1); } public void engineUpdate(byte[] b, int off, int len) throws SignatureException, TokenException { Assert._assert(b != null); if( (state==SIGN || state==VERIFY) ) { if(!raw && sigContext==null) { Assert.notReached("signature has no context"); throw new SignatureException("Signature has no context"); } else if( raw && rawInput==null) { Assert.notReached("raw signature has no input stream"); throw new SignatureException("raw signature has no input "+ "stream"); } } else { Assert._assert(state == UNINITIALIZED); throw new SignatureException("Signature is not initialized"); } Assert._assert(token!=null); Assert._assert(tokenProxy!=null); Assert._assert(algorithm!=null); Assert._assert(key!=null); if( raw ) { rawInput.write(b, off, len); } else { engineUpdateNative( b, off, len); } } protected native void engineUpdateNative(byte[] b, int off, int len) throws TokenException; public byte[] engineSign() throws SignatureException, TokenException { if(state != SIGN) { throw new SignatureException("Signature is not initialized"); } if(!raw && sigContext==null) { throw new SignatureException("Signature has no context"); } else if(raw && rawInput==null) { throw new SignatureException("Signature has no input"); } Assert._assert(token!=null); Assert._assert(tokenProxy!=null); Assert._assert(algorithm!=null); Assert._assert(key!=null); byte[] result; if( raw ) { result = engineRawSignNative(token, (PK11PrivKey)key, rawInput.toByteArray()); rawInput.reset(); } else { result = engineSignNative(); } state = UNINITIALIZED; sigContext = null; return result; } public int engineSign(byte[] outbuf, int offset, int len) throws SignatureException, TokenException { Assert._assert(outbuf!=null); byte[] sig; if( raw ) { sig = engineRawSignNative(token, (PK11PrivKey)key, rawInput.toByteArray()); rawInput.reset(); } else { sig = engineSign(); } if( (outbuf==null) || (outbuf.length <= offset) || (len < sig.length) || (offset+len > outbuf.length)) { throw new SignatureException( "outbuf is not sufficient to hold signature"); } System.arraycopy( (Object)sig, 0, (Object)outbuf, offset, sig.length); return sig.length; } /** * Performs raw signing of the given hash with the given private key. */ private static native byte[] engineRawSignNative(PK11Token token, PrivateKey key, byte[] hash) throws SignatureException, TokenException; private native byte[] engineSignNative() throws SignatureException, TokenException; public boolean engineVerify(byte[] sigBytes) throws SignatureException, TokenException { Assert._assert(sigBytes!=null); if(state != VERIFY) { throw new SignatureException( "Signature is not initialized properly"); } if(!raw && sigContext==null) { Assert.notReached("Signature has no context"); throw new SignatureException("Signature has no context"); } if(raw && rawInput==null) { Assert.notReached("Signature has no input"); throw new SignatureException("Signature has no input"); } Assert._assert(token!=null); Assert._assert(tokenProxy!=null); Assert._assert(algorithm!=null); Assert._assert(key!=null); if(sigBytes==null) { return false; } boolean result; if( raw ) { result = engineRawVerifyNative(token, (PK11PubKey)key, rawInput.toByteArray(), sigBytes); rawInput.reset(); } else { result = engineVerifyNative(sigBytes); } state = UNINITIALIZED; sigContext = null; return result; } /** * Performs raw verification of the signature of a hash using the * given public key, on the given token. */ protected static native boolean engineRawVerifyNative(PK11Token token, PublicKey key, byte[] hash, byte[] signature) throws SignatureException, TokenException; native protected boolean engineVerifyNative(byte[] sigBytes) throws SignatureException, TokenException; public void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException, TokenException { Assert.notYetImplemented("PK11Signature.engineSetParameter"); } protected PK11Token token; protected TokenProxy tokenProxy; protected Algorithm algorithm; protected PK11Key key; protected int state; protected SigContextProxy sigContext; protected boolean raw=false; // raw signing only, no hashing protected ByteArrayOutputStream rawInput; // states static public final int UNINITIALIZED = 0; static public final int SIGN = 1; static public final int VERIFY = 2; } class SigContextProxy extends NativeProxy { public SigContextProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { Debug.trace(Debug.OBNOXIOUS, "Finalizing a SigContextProxy"); super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Store.c000066400000000000000000000561311326145000000211110ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Store.h" #include #include #include #include #include #include #include #include #include #include #include "pk11util.h" #include #include typedef struct { enum { PW_NONE = 0, PW_FROMFILE = 1, PW_PLAINTEXT = 2, PW_EXTERNAL = 3 } source; char *data; } secuPWData; SECItem *preparePassword(JNIEnv *env, jobject conv, jobject pwObj); /********************************************************************** * PK11Store.putSymKeysInVector */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector (JNIEnv *env, jobject this, jobject keyVector) { PK11SlotInfo *slot; jobject object = NULL; jclass vectorClass; jmethodID addElement; PK11SymKey *firstSymKey= NULL; PK11SymKey *sk = NULL; PK11SymKey *nextSymKey = NULL; secuPWData pwdata; pwdata.source = PW_NONE; pwdata.data = (char *) NULL; PR_ASSERT(env!=NULL && this!=NULL && keyVector!=NULL); if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); vectorClass = (*env)->GetObjectClass(env, keyVector); if(vectorClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement == NULL) { ASSERT_OUTOFMEM(env); goto finish; } PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); /* Obtain the symmetric key list. */ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata ); sk = firstSymKey; while(( sk != NULL )) { if( sk ) { nextSymKey = sk; object = JSS_PK11_wrapSymKey(env, &sk); if(object == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } /*************************************************** * Insert the key into the vector ***************************************************/ (*env)->CallVoidMethod(env, keyVector, addElement, object); } sk = PK11_GetNextSymKey( nextSymKey ); } finish: return; } /********************************************************************** * PK11Store.putKeysInVector */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_putKeysInVector (JNIEnv *env, jobject this, jobject keyVector) { PK11SlotInfo *slot; SECKEYPrivateKeyList *keyList = NULL; SECKEYPrivateKey* keyCopy = NULL; jobject object = NULL; jclass vectorClass; jmethodID addElement; SECKEYPrivateKeyListNode *node = NULL; PR_ASSERT(env!=NULL && this!=NULL && keyVector!=NULL); if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); /* * Most, if not all, tokens have to be logged in before they allow * access to their private keys, so try to log in here. If we're already * logged in, this is a no-op. * If the login fails, go ahead and try to get the keys anyway, in case * this is an exceptionally promiscuous token. */ PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); /* * Get the list of keys on this token */ keyList = PK11_ListPrivateKeysInSlot(slot); if( keyList == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "PK11_ListPrivateKeysInSlot " "returned an error"); goto finish; } /************************************************** * Get JNI ids **************************************************/ vectorClass = (*env)->GetObjectClass(env, keyVector); if(vectorClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement == NULL) { ASSERT_OUTOFMEM(env); goto finish; } for( node = PRIVKEY_LIST_HEAD(keyList); !PRIVKEY_LIST_END(node, keyList); node = PRIVKEY_LIST_NEXT(node) ) { /*************************************************** * Wrap the object ***************************************************/ keyCopy = SECKEY_CopyPrivateKey(node->key); object = JSS_PK11_wrapPrivKey(env, &keyCopy); if(object == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } /*************************************************** * Insert the key into the vector ***************************************************/ (*env)->CallVoidMethod(env, keyVector, addElement, object); } finish: if( keyList != NULL ) { SECKEY_DestroyPrivateKeyList(keyList); } return; } /********************************************************************** * PK11Store.putCertsInVector */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_putCertsInVector (JNIEnv *env, jobject this, jobject certVector) { PK11SlotInfo *slot; PK11SlotInfo *slotCopy; jclass vectorClass; jmethodID addElement; CERTCertList *certList = NULL; CERTCertificate *certCopy; CERTCertListNode *node = NULL; jobject object; PR_ASSERT(env!=NULL && this!=NULL && certVector!=NULL); if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); /* * log in if the slot does not have publicly readable certs */ if( !PK11_IsFriendly(slot) ) { PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); } certList = PK11_ListCertsInSlot(slot); if( certList == NULL ) { JSS_throwMsg(env, TOKEN_EXCEPTION, "PK11_ListCertsInSlot " "returned an error"); goto finish; } /************************************************** * Get JNI ids **************************************************/ vectorClass = (*env)->GetObjectClass(env, certVector); if(vectorClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } addElement = (*env)->GetMethodID(env, vectorClass, VECTOR_ADD_ELEMENT_NAME, VECTOR_ADD_ELEMENT_SIG); if(addElement == NULL) { ASSERT_OUTOFMEM(env); goto finish; } for( node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { /*************************************************** * Wrap the object ***************************************************/ certCopy = CERT_DupCertificate(node->cert); slotCopy = PK11_ReferenceSlot(slot); object = JSS_PK11_wrapCertAndSlotAndNickname(env, &certCopy, &slotCopy, node->appData); if(object == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } /*************************************************** * Insert the cert into the vector ***************************************************/ (*env)->CallVoidMethod(env, certVector, addElement, object); } finish: if( certList != NULL ) { CERT_DestroyCertList(certList); } return; } /************************************************************************ * * J S S _ g e t S t o r e S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given PK11Store. * * INPUTS * store * A reference to a Java PK11Store * slot * address of a PK11SlotInfo* that will be loaded with * the PK11SlotInfo pointer of the given token. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getStoreSlotPtr(JNIEnv *env, jobject store, PK11SlotInfo **slot) { PR_ASSERT(env!=NULL && store!=NULL && slot!=NULL); return JSS_getPtrFromProxyOwner(env, store, PK11STORE_PROXY_FIELD, PK11STORE_PROXY_SIG, (void**)slot); } /********************************************************************** * PK11Store.deletePrivateKey */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_deletePrivateKey (JNIEnv *env, jobject this, jobject key) { PK11SlotInfo *slot; SECKEYPrivateKey *privk; PR_ASSERT(env!=NULL && this!=NULL); if(key == NULL) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } /************************************************** * Get the C structures **************************************************/ if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } if( JSS_PK11_getPrivKeyPtr(env, key, &privk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /*************************************************** * Validate structures ***************************************************/ /* A private key may be temporary, but you can't use this function * to delete it. Instead, just let it be garbage collected */ if( privk->pkcs11IsTemp ) { PR_ASSERT(PR_FALSE); JSS_throwMsg(env, TOKEN_EXCEPTION, "Private Key is not a permanent PKCS #11 object"); goto finish; } if( slot != privk->pkcs11Slot) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } /*************************************************** * Perform the destruction ***************************************************/ if( PK11_DestroyTokenObject(privk->pkcs11Slot, privk->pkcs11ID) != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Unable to actually destroy object"); goto finish; } finish: return; } /********************************************************************** * PK11Store.deleteCert * * This function deletes the specified certificate and its associated * private key. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_deleteCert (JNIEnv *env, jobject this, jobject certObject) { CERTCertificate *cert; SECStatus VARIABLE_MAY_NOT_BE_USED status; PR_ASSERT(env!=NULL && this!=NULL); if(certObject == NULL) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if( JSS_PK11_getCertPtr(env, certObject, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } status = PK11_DeleteTokenCertAndKey(cert, NULL); status = SEC_DeletePermCertificate(cert); finish: return; } /********************************************************************** * PK11Store.deleteCertOnly * * This function deletes the specified certificate only. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_deleteCertOnly (JNIEnv *env, jobject this, jobject certObject) { CERTCertificate *cert; SECStatus VARIABLE_MAY_NOT_BE_USED status; PR_ASSERT(env!=NULL && this!=NULL); if(certObject == NULL) { JSS_throw(env, NO_SUCH_ITEM_ON_TOKEN_EXCEPTION); goto finish; } if( JSS_PK11_getCertPtr(env, certObject, &cert) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } status = SEC_DeletePermCertificate(cert); finish: return; } #define DER_DEFAULT_CHUNKSIZE (2048) int PK11_NumberObjectsFor(PK11SlotInfo*, CK_ATTRIBUTE*, int); /*********************************************************************** * PK11Store.importdPrivateKey */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_importPrivateKey ( JNIEnv *env, jobject this, jbyteArray keyArray, jobject keyTypeObj, jboolean temporary ) { SECItem derPK; PK11SlotInfo *slot; jthrowable excep; SECStatus status; SECItem nickname; jobject privkObj = NULL; /* * initialize so we can goto finish */ derPK.data = NULL; derPK.len = 0; PR_ASSERT(env!=NULL && this!=NULL); if(keyArray == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } /* * copy the java byte array into a local copy */ derPK.len = (*env)->GetArrayLength(env, keyArray); if(derPK.len <= 0) { JSS_throwMsg(env, INVALID_KEY_FORMAT_EXCEPTION, "Key array is empty"); goto finish; } derPK.data = (unsigned char*) (*env)->GetByteArrayElements(env, keyArray, NULL); if(derPK.data == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* * Get the PKCS #11 slot */ if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } nickname.len = 0; nickname.data = NULL; SECKEYPrivateKey *privk = NULL; status = PK11_ImportDERPrivateKeyInfoAndReturnKey( slot, &derPK, &nickname, NULL /*public value*/, !temporary /*isPerm*/, PR_TRUE /*isPrivate*/, 0 /*keyUsage*/, &privk, NULL /*wincx*/); if(status != SECSuccess) { JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to import private key info"); goto finish; } privkObj = JSS_PK11_wrapPrivKey(env, &privk); if (privkObj == NULL) { goto finish; } finish: /* Save any exceptions */ if( (excep=(*env)->ExceptionOccurred(env)) ) { (*env)->ExceptionClear(env); } if(derPK.data != NULL) { (*env)->ReleaseByteArrayElements( env, keyArray, (jbyte*) derPK.data, JNI_ABORT ); } /* now re-throw the exception */ if( excep ) { (*env)->Throw(env, excep); } return privkObj; } extern const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[]; JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_getEncryptedPrivateKeyInfo( JNIEnv *env, jobject this, jobject conv, jobject pwObj, jobject algObj, jint iterations, jobject key) { // initialisations so we can goto finish SECItem *pwItem = NULL; SECKEYEncryptedPrivateKeyInfo *epki = NULL; SECItem epkiItem; epkiItem.data = NULL; epkiItem.len = 0; PR_ASSERT(env != NULL && this != NULL); if (pwObj == NULL || algObj == NULL || key == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } if (iterations <= 0) { iterations = 2000; // set default iterations } // get slot PK11SlotInfo *slot = NULL; if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot!=NULL); // get algorithm SECOidTag algTag = JSS_getOidTagFromAlg(env, algObj); if (algTag == SEC_OID_UNKNOWN) { JSS_throwMsg(env, NO_SUCH_ALG_EXCEPTION, "Unrecognized algorithm"); goto finish; } pwItem = preparePassword(env, conv, pwObj); if (pwItem == NULL) { ASSERT_OUTOFMEM(env); goto finish; } // get key SECKEYPrivateKey *privk; if (JSS_PK11_getPrivKeyPtr(env, key, &privk) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } // export the epki epki = PK11_ExportEncryptedPrivKeyInfo( slot, algTag, pwItem, privk, iterations, NULL /*wincx*/); if (epki == NULL) { JSS_throwMsgPrErr( env, TOKEN_EXCEPTION, "Failed to export EncryptedPrivateKeyInfo"); goto finish; } // DER-encode the epki if (SEC_ASN1EncodeItem(NULL, &epkiItem, epki, SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate)) == NULL) { JSS_throwMsg( env, TOKEN_EXCEPTION, "Failed to ASN1-encode EncryptedPrivateKeyInfo"); goto finish; } // convert to Java byte array jbyteArray encodedEpki = JSS_SECItemToByteArray(env, &epkiItem); finish: if (epki != NULL) { SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE /*freeit*/); } if (epkiItem.data != NULL) { SECITEM_FreeItem(&epkiItem, PR_FALSE /*freeit*/); } if (pwItem != NULL) { SECITEM_FreeItem(pwItem, PR_TRUE /*freeit*/); } return encodedEpki; } JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Store_importEncryptedPrivateKeyInfo( JNIEnv *env, jobject this, jobject conv, jobject pwObj, jstring nickname, jobject pubKeyObj, jbyteArray epkiBytes) { // initialisations so we can goto finish SECItem *epkiItem = NULL; SECKEYEncryptedPrivateKeyInfo *epki = NULL; SECItem *pwItem = NULL; SECItem *spkiItem = NULL; CERTSubjectPublicKeyInfo *spki = NULL; SECKEYPublicKey *pubKey = NULL; const char *nicknameChars = NULL; PR_ASSERT(env != NULL && this != NULL); if (pwObj == NULL || nickname == NULL || pubKeyObj == NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } // get slot PK11SlotInfo *slot = NULL; if (JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ASSERT_OUTOFMEM(env); goto finish; } PR_ASSERT(slot != NULL); // decode EncryptedPrivateKeyInfo epkiItem = JSS_ByteArrayToSECItem(env, epkiBytes); epki = PR_Calloc(1, sizeof(SECKEYEncryptedPrivateKeyInfo)); if (SEC_ASN1DecodeItem( NULL, epki, SEC_ASN1_GET(SECKEY_EncryptedPrivateKeyInfoTemplate), epkiItem ) != SECSuccess) { JSS_throwMsg(env, INVALID_DER_EXCEPTION, "Failed to decode EncryptedPrivateKeyInfo"); goto finish; } pwItem = preparePassword(env, conv, pwObj); if (pwItem == NULL) { ASSERT_OUTOFMEM(env); goto finish; } // get public key value jclass pubKeyClass = (*env)->GetObjectClass(env, pubKeyObj); if (pubKeyClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } jmethodID getEncoded = (*env)->GetMethodID( env, pubKeyClass, "getEncoded", "()[B"); if (getEncoded == NULL) { ASSERT_OUTOFMEM(env); goto finish; } jbyteArray spkiBytes = (*env)->CallObjectMethod( env, pubKeyObj, getEncoded); spkiItem = JSS_ByteArrayToSECItem(env, spkiBytes); spki = PR_Calloc(1, sizeof(CERTSubjectPublicKeyInfo)); if (SEC_ASN1DecodeItem( NULL, spki, SEC_ASN1_GET(CERT_SubjectPublicKeyInfoTemplate), spkiItem ) != SECSuccess) { JSS_throwMsg(env, INVALID_DER_EXCEPTION, "Failed to decode SubjectPublicKeyInfo"); goto finish; } pubKey = SECKEY_ExtractPublicKey(spki); if (pubKey == NULL) { JSS_throwMsgPrErr(env, INVALID_DER_EXCEPTION, "Failed to extract public key from SubjectPublicKeyInfo"); goto finish; } SECItem *pubValue; switch (pubKey->keyType) { case dsaKey: pubValue = &pubKey->u.dsa.publicValue; break; case dhKey: pubValue = &pubKey->u.dh.publicValue; break; case rsaKey: pubValue = &pubKey->u.rsa.modulus; break; case ecKey: pubValue = &pubKey->u.ec.publicValue; break; default: pubValue = NULL; } // prepare nickname nicknameChars = (*env)->GetStringUTFChars(env, nickname, NULL); if (nicknameChars == NULL) { ASSERT_OUTOFMEM(env); goto finish; } SECItem nickItem; nickItem.data = nicknameChars; nickItem.len = (*env)->GetStringUTFLength(env, nickname); // if keyUsage = 0, defaults to signing and encryption/key agreement. // see pk11akey.c in NSS int keyUsage = 0; // perform import SECStatus result = PK11_ImportEncryptedPrivateKeyInfo( slot, epki, pwItem, &nickItem, pubValue, PR_TRUE /* isperm */, PR_TRUE /* isprivate */, pubKey->keyType, keyUsage, NULL /* wincx */); if (result != SECSuccess) { JSS_throwMsgPrErr( env, TOKEN_EXCEPTION, "Failed to import EncryptedPrivateKeyInfo to token"); goto finish; } finish: if (epkiItem != NULL) { SECITEM_FreeItem(epkiItem, PR_TRUE /*freeit*/); } if (epki != NULL) { SECKEY_DestroyEncryptedPrivateKeyInfo(epki, PR_TRUE /*freeit*/); } if (spkiItem != NULL) { SECITEM_FreeItem(spkiItem, PR_TRUE /*freeit*/); } if (spki != NULL) { SECKEY_DestroySubjectPublicKeyInfo(spki); } if (pwItem != NULL) { SECITEM_FreeItem(pwItem, PR_TRUE /*freeit*/); } if (pubKey != NULL) { SECKEY_DestroyPublicKey(pubKey); } if (nicknameChars != NULL) { (*env)->ReleaseStringUTFChars(env, nickname, nicknameChars); } } /* Process the given password through the given PasswordConverter, * returning a new SECItem* on success. * * After use, the caller should free the SECItem: * * SECITEM_FreeItem(pwItem, PR_TRUE). */ SECItem *preparePassword(JNIEnv *env, jobject conv, jobject pwObj) { jclass passwordClass = (*env)->GetObjectClass(env, pwObj); if (passwordClass == NULL) { ASSERT_OUTOFMEM(env); return NULL; } jbyteArray pwBytes; if (conv == NULL) { jmethodID getByteCopy = (*env)->GetMethodID( env, passwordClass, PW_GET_BYTE_COPY_NAME, PW_GET_BYTE_COPY_SIG); if (getByteCopy == NULL) { ASSERT_OUTOFMEM(env); return NULL; } pwBytes = (*env)->CallObjectMethod(env, pwObj, getByteCopy); } else { jmethodID getChars = (*env)->GetMethodID( env, passwordClass, "getChars", "()[C"); if (getChars == NULL) { ASSERT_OUTOFMEM(env); return NULL; } jcharArray pwChars = (*env)->CallObjectMethod(env, pwObj, getChars); jclass convClass = (*env)->GetObjectClass(env, conv); if (conv == NULL) { ASSERT_OUTOFMEM(env); return NULL; } jmethodID convert = (*env)->GetMethodID( env, convClass, "convert", "([C)[B"); if (convert == NULL) { ASSERT_OUTOFMEM(env); return NULL; } pwBytes = (*env)->CallObjectMethod(env, conv, convert, pwChars); } return JSS_ByteArrayToSECItem(env, pwBytes); } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Store.java000066400000000000000000000114551326145000000216100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; import java.util.Vector; public final class PK11Store implements CryptoStore { //////////////////////////////////////////////////////////// // Private Keys //////////////////////////////////////////////////////////// /** * Imports a raw private key into this token. * * @param key The private key. * @exception TokenException If the key cannot be imported to this token. * @exception KeyAlreadyImportedException If the key already on this token. */ public PrivateKey importPrivateKey(byte[] key, PrivateKey.Type type) throws TokenException,KeyAlreadyImportedException { return importPrivateKey(key, type, false); } public native PrivateKey importPrivateKey( byte[] key, PrivateKey.Type type, boolean temporary) throws TokenException,KeyAlreadyImportedException; public synchronized PrivateKey[] getPrivateKeys() throws TokenException { Vector keys = new Vector(); putKeysInVector(keys); PrivateKey[] array = new PrivateKey[keys.size()]; keys.copyInto( (Object[]) array ); return array; } public synchronized SymmetricKey[] getSymmetricKeys() throws TokenException { Vector keys = new Vector(); putSymKeysInVector(keys); SymmetricKey[] array = new SymmetricKey[keys.size()]; keys.copyInto( (Object[]) array); return array; } protected native void putKeysInVector(Vector keys) throws TokenException; protected native void putSymKeysInVector(Vector symKeys) throws TokenException; public native void deletePrivateKey(PrivateKey key) throws NoSuchItemOnTokenException, TokenException; public byte[] getEncryptedPrivateKeyInfo( X509Certificate cert, PBEAlgorithm pbeAlg, Password pw, int iteration) throws CryptoManager.NotInitializedException, ObjectNotFoundException, TokenException { return getEncryptedPrivateKeyInfo( null, pw, pbeAlg, iteration, CryptoManager.getInstance().findPrivKeyByCert(cert) ); } public native byte[] getEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, Algorithm alg, int n, PrivateKey k); public native void importEncryptedPrivateKeyInfo( KeyGenerator.CharToByteConverter conv, Password pw, String nickname, PublicKey pubKey, byte[] epkiBytes); //////////////////////////////////////////////////////////// // Certs //////////////////////////////////////////////////////////// public X509Certificate[] getCertificates() throws TokenException { Vector certs = new Vector(); putCertsInVector(certs); X509Certificate[] array = new X509Certificate[certs.size()]; certs.copyInto( (Object[]) array ); return array; } protected native void putCertsInVector(Vector certs) throws TokenException; /** * Deletes the specified certificate and its associated private * key from the store. * * @param cert certificate to be deleted * @exception NoSuchItemOnTokenException If the certificate not found * @exception TokenException General token error */ // Currently have to use PK11_DeleteTokenObject + PK11_FindObjectForCert // or maybe SEC_DeletePermCertificate. public native void deleteCert(X509Certificate cert) throws NoSuchItemOnTokenException, TokenException; /** * Deletes the specified certificate from the store. * * @param cert certificate to be deleted * @exception NoSuchItemOnTokenException If the certificate not found * @exception TokenException General token error */ public native void deleteCertOnly(X509Certificate cert) throws NoSuchItemOnTokenException, TokenException; //////////////////////////////////////////////////////////// // Construction //////////////////////////////////////////////////////////// protected boolean updated; public PK11Store(TokenProxy proxy) { Assert._assert(proxy!=null); this.storeProxy = proxy; } protected PK11Store() { } //////////////////////////////////////////////////////////// // Private data //////////////////////////////////////////////////////////// protected TokenProxy storeProxy; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11SymKey.c000066400000000000000000000233561326145000000212410ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_SymKeyProxy.h" #include #include #include #include #include #include #include #include "pk11util.h" /*********************************************************************** * * J S S _ P K 1 1 _ w r a p S y m K e y * Puts a Symmetric Key into a Java object. * (Does NOT perform a cryptographic "wrap" operation.) * symKey: will be stored in a Java wrapper. * Returns: a new PK11SymKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapSymKey(JNIEnv *env, PK11SymKey **symKey) { jclass keyClass; jmethodID constructor; jbyteArray ptrArray; jobject Key=NULL; char *nickname = NULL; jstring jnickname = NULL; PR_ASSERT(env!=NULL && symKey!=NULL && *symKey!=NULL); /* find the class */ keyClass = (*env)->FindClass(env, PK11SYMKEY_CLASS_NAME); if( keyClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } nickname = PK11_GetSymKeyNickname( *symKey ); if (nickname) { jnickname = (*env)->NewStringUTF(env, nickname); } /* find the constructor */ constructor = (*env)->GetMethodID(env, keyClass, PLAIN_CONSTRUCTOR, PK11SYMKEY_CONSTRUCTOR_1_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* convert the pointer to a byte array */ ptrArray = JSS_ptrToByteArray(env, (void*)*symKey); if( ptrArray == NULL ) { goto finish; } /* call the constructor */ Key = (*env)->NewObject(env, keyClass, constructor, ptrArray, jnickname); finish: if(Key == NULL) { PK11_FreeSymKey(*symKey); } if(nickname != NULL) { PORT_Free(nickname); nickname = NULL; } *symKey = NULL; return Key; } /*********************************************************************** * * PK11SymKey.getOwningToken */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getOwningToken (JNIEnv *env, jobject this) { PK11SymKey *key = NULL; PK11SlotInfo *slot = NULL; jobject token = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* Get the C key structure */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } /* Get the slot this key lives on */ slot = PK11_GetSlotFromKey(key); PR_ASSERT(slot != NULL); /* Turn the slot into a Java PK11Token */ token = JSS_PK11_wrapPK11Token(env, &slot); if(token == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); goto finish; } finish: if(slot != NULL) { PK11_FreeSlot(slot); } return token; } /*********************************************************************** * * PK11SymKey.getStrength */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getStrength (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; int strength = 0; /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } strength = PK11_GetKeyStrength(key, NULL /*algid*/); finish: return strength; } /*********************************************************************** * * PK11SymKey.getLength */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getLength (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; unsigned int strength = 0; /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } strength = PK11_GetKeyLength(key); finish: return (jint) strength; } /*********************************************************************** * * PK11SymKey.setNickNameNative */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative (JNIEnv *env, jobject this,jstring nickname) { PK11SymKey *key=NULL; const char *keyname = NULL; SECStatus status; /* If no nickname provided, we are done */ if( nickname == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Nickname is NULL, will not be set"); goto finish; } /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } /* convert the Java String into a native "C" string */ keyname = (*env)->GetStringUTFChars( env, nickname, 0 ); /* name the key */ status = PK11_SetSymKeyNickname( key, keyname ); if( status != SECSuccess ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to name symmetric key"); } finish: if( keyname != NULL ) { /* free the native "C" string */ (*env)->ReleaseStringUTFChars(env, nickname, keyname); } return; } /*********************************************************************** * * PK11SymKey.getKeyData */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyData (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; SECItem *keyData; /* a reference to the key data */ jbyteArray dataArray=NULL; /* get the key pointer */ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { goto finish; } /* Extract the key data */ if( PK11_ExtractKeyValue(key) != SECSuccess ) { /* key is not extractable */ JSS_throwMsg(env, NOT_EXTRACTABLE_EXCEPTION, "Unable to extract " "symmetric key data"); goto finish; } keyData = PK11_GetKeyData(key); /* PK11_ExtractKeyValue should have failed if keyData is NULL */ PR_ASSERT(keyData != NULL); /* copy the key data into a Java byte array */ dataArray = JSS_SECItemToByteArray(env, keyData); finish: /* keyData is just a reference, nothing to free */ if( dataArray == NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); } return dataArray; } /*********************************************************************** * * PK11SymKey.getKeyType */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11SymKey_getKeyType (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; CK_MECHANISM_TYPE keyMech; char *typeFieldName=NULL; jclass typeClass=NULL; jfieldID typeField=NULL; jobject typeObject=NULL; if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS ) { ASSERT_OUTOFMEM(env); goto finish; } /* Look up the key type from the key */ keyMech = PK11_GetMechanism(key); switch(keyMech) { /* PBE mechanisms have to be handled by hand */ case CKM_PBE_MD2_DES_CBC: case CKM_PBE_MD5_DES_CBC: case CKM_NETSCAPE_PBE_SHA1_DES_CBC: typeFieldName = DES_KEYTYPE_FIELD; break; case CKM_PBE_SHA1_RC4_128: case CKM_PBE_SHA1_RC4_40: typeFieldName = RC4_KEYTYPE_FIELD; break; case CKM_PBE_SHA1_RC2_128_CBC: case CKM_PBE_SHA1_RC2_40_CBC: typeFieldName = RC2_KEYTYPE_FIELD; break; case CKM_PBE_SHA1_DES3_EDE_CBC: typeFieldName = DES3_KEYTYPE_FIELD; break; case CKM_PBA_SHA1_WITH_SHA1_HMAC: typeFieldName = SHA1_HMAC_KEYTYPE_FIELD; break; default: keyMech = PK11_GetKeyType( keyMech, 0 ); switch(keyMech) { case CKK_DES: typeFieldName = DES_KEYTYPE_FIELD; break; case CKK_DES3: typeFieldName = DES3_KEYTYPE_FIELD; break; case CKK_RC4: typeFieldName = RC4_KEYTYPE_FIELD; break; case CKK_RC2: typeFieldName = RC2_KEYTYPE_FIELD; break; case CKK_AES: typeFieldName = AES_KEYTYPE_FIELD; break; case CKK_DES2: typeFieldName = DES3_KEYTYPE_FIELD; break; case CKK_GENERIC_SECRET: typeFieldName = GENERIC_SECRET_KEYTYPE_FIELD; break; default: PR_ASSERT(PR_FALSE); typeFieldName = DES_KEYTYPE_FIELD; break; } break; } /* convert to a Java key type */ typeClass = (*env)->FindClass(env, KEYTYPE_CLASS_NAME); if(typeClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } typeField = (*env)->GetStaticFieldID(env, typeClass, typeFieldName, KEYTYPE_FIELD_SIG); if(typeField == NULL) { ASSERT_OUTOFMEM(env); goto finish; } typeObject = (*env)->GetStaticObjectField(env, typeClass, typeField); if(typeObject == NULL) { ASSERT_OUTOFMEM(env); goto finish; } finish: return typeObject; } /*********************************************************************** * * J S S _ P K 1 1 _ g e t S y m K e y P t r * */ PRStatus JSS_PK11_getSymKeyPtr(JNIEnv *env, jobject symKeyObject, PK11SymKey **ptr) { PR_ASSERT(env!=NULL && symKeyObject!=NULL); /* Get the pointer from the key proxy */ return JSS_getPtrFromProxyOwner(env, symKeyObject, SYM_KEY_PROXY_FIELD, SYM_KEY_PROXY_SIG, (void**)ptr); } /*********************************************************************** * * SymKeyProxy.releaseNativeResources */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_SymKeyProxy_releaseNativeResources (JNIEnv *env, jobject this) { PK11SymKey *key=NULL; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_getPtrFromProxy(env, this, (void**)&key) == PR_SUCCESS) { PK11_FreeSymKey(key); } else { /* can't really throw an exception from a destructor */ PR_ASSERT(PR_FALSE); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11SymKey.java000066400000000000000000000060271326145000000217340ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.Assert; public final class PK11SymKey implements SymmetricKey { protected PK11SymKey(byte[] pointer) { Assert._assert(pointer!=null); keyProxy = new SymKeyProxy(pointer); nickName = null; } protected PK11SymKey(byte[] pointer,String nickName) { Assert._assert(pointer!=null); keyProxy = new SymKeyProxy(pointer); this.nickName = nickName; } private SymKeyProxy keyProxy; private String nickName; public SymmetricKey.Type getType() { KeyType kt = getKeyType(); if(kt == KeyType.DES) { return DES; } else if(kt == KeyType.DES3) { return DES3; } else if(kt == KeyType.RC4) { return RC4; } else if(kt == KeyType.RC2) { return RC2; } else if(kt == KeyType.AES) { return AES; } else if(kt == KeyType.SHA1_HMAC) { return SHA1_HMAC; } else { Assert.notReached("Unrecognized key type"); return DES; } } public native CryptoToken getOwningToken(); /** * Returns key strength, measured as the number of bits of secret material. * NOTE: Due to a bug in the security library (333440), this * may return a wrong answer for PBE keys that have embedded parity * (like DES). A DES key is 56 bits of information plus * 8 bits of parity, so it takes up 64 bits. For a normal DES key, * this method will correctly return 56, but for a PBE-generated DES key, * the security library bug causes it to return 64. */ public native int getStrength(); /** * Returns the length of the key in bytes, as returned by * PK11_GetKeyLength(). */ public native int getLength(); public native byte[] getKeyData() throws SymmetricKey.NotExtractableException; public native KeyType getKeyType(); public String getAlgorithm() { return getKeyType().toString(); } public byte[] getEncoded() { try { return getKeyData(); } catch(SymmetricKey.NotExtractableException nee) { return null; } } public String getFormat() { return "RAW"; } public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; if( nickName != null) { setNickNameNative(nickName); } } public native void setNickNameNative(String nickName); } class SymKeyProxy extends KeyProxy { public SymKeyProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.c000066400000000000000000000242471326145000000237660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "java_ids.h" #include "pk11util.h" #include /*********************************************************************** * Expose the NSS functionality at low level, one should know what to do * at the Java level. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey (JNIEnv * env, jobject this,jobject tokenObj, jobject baseKeyObj, jobject secondaryKeyObj, jlong deriveMechanism, jbyteArray param, jbyteArray iv, jlong targetMechanism, jlong operation, jlong keySize) { jobject keyObj = NULL; PK11SlotInfo *slot=NULL; PK11SlotInfo *bestSlot = NULL; PK11SlotInfo *slotForKey = NULL; PK11SlotInfo *slotForSecondaryKey = NULL; PK11SlotInfo *finalSlot = NULL; PK11SlotInfo *finalSecondarySlot = NULL; PK11SlotInfo *finalBaseKeySlot = NULL; PK11SymKey *baseKey = NULL; PK11SymKey *bestBaseKey = NULL; PK11SymKey *finalBaseKey = NULL; PK11SymKey *newKey = NULL; PK11SymKey *secondaryKey = NULL; PK11SymKey *bestSecondaryKey = NULL; PK11SymKey *finalSecondaryKey = NULL; PK11SymKey *derivedKey = NULL; jbyte *paramValue = NULL; int paramLength = 0; jbyte *ivValue = NULL; int ivLength = 0; CK_OBJECT_HANDLE keyhandle = 0; CK_AES_CBC_ENCRYPT_DATA_PARAMS aes; CK_DES_CBC_ENCRYPT_DATA_PARAMS des; CK_KEY_DERIVATION_STRING_DATA string; SECItem paramsItem = { siBuffer, NULL, 0 }; PR_ASSERT(env!=NULL && this!=NULL); if( baseKeyObj == 0) { PR_fprintf(PR_STDOUT,"baseKeyObj can not be null!\n"); goto loser; } if( param != NULL) { paramValue = (*env)->GetByteArrayElements(env,param, NULL); paramLength = (*env)->GetArrayLength(env,param); } if( iv != NULL) { ivValue = (*env)->GetByteArrayElements(env,iv, NULL); ivLength = (*env)->GetArrayLength(env,iv); } /* Set up the params data for the PK11_Derive family */ switch ( deriveMechanism ) { case CKM_DES_ECB_ENCRYPT_DATA: case CKM_DES3_ECB_ENCRYPT_DATA: case CKM_AES_ECB_ENCRYPT_DATA: case CKM_CAMELLIA_ECB_ENCRYPT_DATA: case CKM_SEED_ECB_ENCRYPT_DATA: /* Use CK_KEY_DERIVATION_STRING_DATA */ string.pData = (unsigned char *) paramValue; string.ulLen = paramLength; paramsItem.data = (void *) &string; paramsItem.len = sizeof(string); break; case CKM_DES_CBC_ENCRYPT_DATA: case CKM_DES3_CBC_ENCRYPT_DATA: /* Use CK_DES_CBC_ENCRYPT_DATA_PARAMS */ if( ivValue == NULL) { PR_fprintf(PR_STDOUT, "Need iv param for CKM_DES_CBC_ENCRYPT_DATA or CKM_DES3_CBC_ENCRYPT_DATA. \n"); goto loser; } if( ivLength != 8) { PR_fprintf(PR_STDOUT, "Need iv param for CKM_DES_CBC_ENCRYPT_DATA structure to be 8 bytes!. \n"); goto loser; } des.pData = (unsigned char *) paramValue; des.length = paramLength; PORT_Memcpy(des.iv,ivValue,ivLength); paramsItem.data = (void *) &des; paramsItem.len = sizeof(des); break; case CKM_AES_CBC_ENCRYPT_DATA: case CKM_CAMELLIA_CBC_ENCRYPT_DATA: case CKM_SEED_CBC_ENCRYPT_DATA: /* Use CK_AES_CBC_ENCRYPT_DATA_PARAMS */ if ( ivValue == NULL ) { PR_fprintf(PR_STDOUT, "Need iv param for CBC encrypt derive for AES, or CAMELLIA or SEED. \n"); goto loser; } if( ivLength != 16) { PR_fprintf(PR_STDOUT, "Need iv param for CK_AES_CBC_ENCRYPT_DATA_PARAMS structure to be 16 bytes!. \n"); goto loser; } aes.pData = (unsigned char *) paramValue; aes.length = paramLength; PORT_Memcpy(aes.iv,ivValue,ivLength); paramsItem.data = (void *) &aes; paramsItem.len = sizeof(aes); break; default: paramsItem.data = (unsigned char *) paramValue; paramsItem.len = paramLength; break; } /* Get slot */ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { goto loser; } /* Get base key */ if( JSS_PK11_getSymKeyPtr(env, baseKeyObj, &baseKey) != PR_SUCCESS) { PR_fprintf(PR_STDOUT, "PK11SymmetricKeyDeriver.nativeDeriveSymKey: Unable to extract symmetric base key!"); goto loser; } /* Ask NSS what the best slot for the given mechanism */ bestSlot = PK11_GetBestSlot(deriveMechanism, NULL); if( bestSlot == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't find suitable slot for sym key derivation! \n"); goto loser; } slotForKey = PK11_GetSlotFromKey(baseKey); int keyOnRequestedSlot = 0; if(slotForKey != slot) { keyOnRequestedSlot = 0; } else { keyOnRequestedSlot = 1; finalBaseKeySlot = slot; } if ( PK11_DoesMechanism( slot, deriveMechanism)) { if ( keyOnRequestedSlot ) { finalBaseKey = baseKey; } else { bestBaseKey = PK11_MoveSymKey( slot, CKA_ENCRYPT, 0, PR_FALSE, baseKey ); if(bestBaseKey == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't move Base Key to requested slot!\n"); goto loser; } finalBaseKey = bestBaseKey; finalBaseKeySlot = slot; } } else { bestBaseKey = PK11_MoveSymKey( bestSlot, CKA_ENCRYPT, 0, PR_FALSE, baseKey ); if(bestBaseKey == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't move Base Key to best slot!\n"); goto loser; } finalBaseKey = bestBaseKey; finalBaseKeySlot = bestSlot; } /* Assume we want to do a concatenation family here */ if( secondaryKeyObj != NULL) { if( JSS_PK11_getSymKeyPtr(env, secondaryKeyObj, &secondaryKey) != PR_SUCCESS) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't find secondary sym key!\n"); goto loser; } /* Make sure the secondary key is in the proper slot to do concatenation */ slotForSecondaryKey = PK11_GetSlotFromKey( secondaryKey ); if( finalBaseKeySlot != slotForSecondaryKey ) { finalSecondaryKey = PK11_MoveSymKey (finalBaseKeySlot, CKA_ENCRYPT, 0, PR_FALSE, secondaryKey); if( finalSecondaryKey == NULL) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey, Problem moving secondary key to proper slot.\n"); goto loser; } } else { finalSecondaryKey = secondaryKey; } if( paramValue == NULL) { keyhandle = PK11_GetSymKeyHandle(finalSecondaryKey); if( keyhandle == 0) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey, can't get handle for secondary sym key.\n"); goto loser; } paramsItem.data=(unsigned char *) &keyhandle; paramsItem.len=sizeof(keyhandle); } else { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: incorrect input parameter provided!\n"); goto loser; } } derivedKey = PK11_Derive(finalBaseKey, deriveMechanism, ¶msItem, targetMechanism, operation, keySize); if(derivedKey == NULL) { PR_fprintf(PR_STDOUT, "ERROR: Can't derive symmetric key, error: %d \n",PR_GetError()); goto loser; } if ( (finalSlot = PK11_GetSlotFromKey(derivedKey )) != slot) { newKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, derivedKey); if ( newKey == NULL ) { PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: error moving key to original slot, return anyway. \n"); newKey = derivedKey; derivedKey = NULL; } } else { newKey = derivedKey; derivedKey = NULL; } keyObj = JSS_PK11_wrapSymKey(env, &newKey); loser: if ( bestBaseKey != NULL ) { PK11_FreeSymKey ( bestBaseKey ); bestBaseKey = NULL; } if ( bestSecondaryKey != NULL ) { PK11_FreeSymKey ( bestSecondaryKey ); bestSecondaryKey = NULL; } if ( derivedKey != NULL) { PK11_FreeSymKey ( derivedKey ); derivedKey = NULL; } if (bestSlot != NULL ) { PK11_FreeSlot(bestSlot); bestSlot = NULL; } if ( slotForKey != NULL ) { PK11_FreeSlot( slotForKey ); slotForKey = NULL; } if ( finalSlot != NULL ) { PK11_FreeSlot( finalSlot ); finalSlot = NULL; } if ( finalSecondarySlot != NULL ) { PK11_FreeSlot( finalSecondarySlot ); finalSecondarySlot = NULL; } if ( slotForSecondaryKey != NULL ) { PK11_FreeSlot( slotForSecondaryKey ); slotForSecondaryKey = NULL; } if(paramValue) { (*env)->ReleaseByteArrayElements(env, param, (jbyte*)paramValue, JNI_ABORT); } if(ivValue) { (*env)->ReleaseByteArrayElements(env, iv, (jbyte*)ivValue, JNI_ABORT); } if( keyObj == NULL) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to derive symmetric key! " "failure!"); } return keyObj; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.java000066400000000000000000000130421326145000000244540ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.Assert; import sun.security.pkcs11.wrapper.*; import java.security.InvalidKeyException; /*This operation is pkcs11 based only */ public class PK11SymmetricKeyDeriver implements SymmetricKeyDeriver { private PK11Token token = null; private SymmetricKey baseKey = null; private SymmetricKey secondaryKey = null; private long deriveMechanism = 0; private long targetMechanism = 0; private long operation = 0; private long keySize = 0; private byte[] param = null; private byte[] iv = null; public PK11SymmetricKeyDeriver(PK11Token token) { this.token = token; } /* Use with the encrypt type mechanisms Example: initDerive( symKey, (PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA) 4354L, derivationData, null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16); */ public void initDerive(SymmetricKey baseKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException { reset(); if(baseKey == null) { throw new InvalidKeyException("Key is null"); } this.baseKey = baseKey; this.deriveMechanism = deriveMech; this.targetMechanism = targetMech; this.operation = operation; if ( param != null) { this.param = new byte[param.length]; System.arraycopy(param,0,this.param,0,param.length); } if ( iv != null) { this.iv = new byte[iv.length]; System.arraycopy(iv,0,this.iv,0,iv.length); } this.keySize = keySize; } /* Use with key extraction and key concatanation mechanisms Example Extraction: param: byte array that has the bit position of where to extract initDerive( derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8); Example Concat: initDerive( baseSymKey,secondarySymKey, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0); */ public void initDerive(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException { reset(); if ( baseKey == null || secondaryKey == null) { throw new InvalidKeyException("Key is null"); } initDerive(baseKey, deriveMech, param,iv,targetMech,operation,keySize); this.secondaryKey = secondaryKey; } public SymmetricKey derive() throws TokenException { SymmetricKey result = deriveSymKey(this.baseKey,this.secondaryKey,this.deriveMechanism, this.param, this.iv, this.targetMechanism, this.operation,this.keySize); return result; } private SymmetricKey deriveSymKey(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMechanism, byte[] param, byte[] iv, long targetMechanism, long operation, long keySize) throws TokenException, IllegalStateException { return nativeDeriveSymKey(token, baseKey, secondaryKey,deriveMechanism, param, iv, targetMechanism, operation, keySize); } public native SymmetricKey nativeDeriveSymKey(PK11Token token, SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMechanism, byte[] param, byte[] iv, long targetMechanism, long operation, long keySize); private void reset() { baseKey = null; secondaryKey = null; deriveMechanism = 0; targetMechanism = 0; operation = 0; keySize = 0; param = null; iv = null; } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Token.c000066400000000000000000000731211326145000000210730ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_pkcs11_PK11Token.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "java_ids.h" #include "pk11util.h" #include #define ERRX 1 #define KEYTYPE_DSA_STRING "dsa" #define KEYTYPE_RSA_STRING "rsa" #define KEYTYPE_EC_STRING "ec" static CERTCertificateRequest* make_cert_request(JNIEnv *env, const char *subject, SECKEYPublicKey *pubk); static void GenerateCertRequest(JNIEnv *env, SECOidTag ktype, const char *subject, PK11SlotInfo *slot, unsigned char **b64request, void *params); /* these values are taken from PK11KeyPairGenerator.java */ #define DEFAULT_RSA_KEY_SIZE 2048 #define DEFAULT_RSA_PUBLIC_EXPONENT 0x10001 /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 T o k e n * * Create a PK11Token object from a PKCS #11 slot. * * slot is a pointer to a PKCS #11 slot, which must not be NULL. It will * be eaten by the wrapper, so you can't use it after you call this. * * Returns a new PK11Token object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapPK11Token(JNIEnv *env, PK11SlotInfo **slot) { jclass tokenClass; jmethodID constructor; jbyteArray byteArray; jobject Token=NULL; jboolean internal; jboolean keyStorage; PR_ASSERT(env!=NULL && slot!=NULL && *slot!=NULL); internal = (*slot == PK11_GetInternalSlot()); keyStorage = (*slot == PK11_GetInternalKeySlot()); byteArray = JSS_ptrToByteArray(env, (void*)*slot); /* * Lookup the class and constructor */ tokenClass = (*env)->FindClass(env, PK11TOKEN_CLASS_NAME); if(tokenClass == NULL) { ASSERT_OUTOFMEM(env); goto finish; } constructor = (*env)->GetMethodID( env, tokenClass, PK11TOKEN_CONSTRUCTOR_NAME, PK11TOKEN_CONSTRUCTOR_SIG); if(constructor == NULL) { ASSERT_OUTOFMEM(env); goto finish; } /* Call the constructor */ Token = (*env)->NewObject(env, tokenClass, constructor, byteArray, internal, keyStorage); finish: if(Token==NULL) { PK11_FreeSlot(*slot); } *slot = NULL; return Token; } /************************************************************************ * * P K 1 1 T o k e n . needs Login * * returns true if this token needs to be logged into before it can be used. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_needsLogin (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jboolean retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ retval = JNI_FALSE; goto finish; } PR_ASSERT(slot != NULL); if(PK11_NeedLogin(slot) == PR_TRUE) { retval = JNI_TRUE; } else { retval = JNI_FALSE; } finish: return retval; } /************************************************************************ * * P K 1 1 T o k e n . i s L o g g e d I n * * Returns true if this token is logged in. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_isLoggedIn (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jboolean retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ retval = JNI_FALSE; goto finish; } PR_ASSERT(slot != NULL); if(PK11_IsLoggedIn(slot, NULL) == PR_TRUE) { retval = JNI_TRUE; } else { retval = JNI_FALSE; } finish: return retval; } /************************************************************************ * * P K 1 1 T o k e n . n a t i v e L o g i n * * Attempts to login to the token with the given password callback. * Throws NotInitializedException if the token is not initialized. * Throws IncorrectPINException if the supplied PIN is incorrect. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_nativeLogin (JNIEnv *env, jobject this, jobject callback) { PK11SlotInfo *slot; PR_ASSERT(env!=NULL && this!=NULL && callback!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } PR_ASSERT(slot != NULL); /* Is the token initialized? */ if(PK11_NeedUserInit(slot)) { JSS_nativeThrow( env, TOKEN_NOT_INITIALIZED_EXCEPTION ); goto finish; } if(PK11_Authenticate(slot, PR_TRUE /*loadCerts*/, (void*)callback) != SECSuccess) { JSS_nativeThrow(env, INCORRECT_PASSWORD_EXCEPTION); goto finish; } /* Success! */ finish: return; } /************************************************************************ * * P K 1 1 T o k e n . l o g o u t */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_logout (JNIEnv *env, jobject this) { PK11SlotInfo *slot; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception occurred */ goto finish; } PR_ASSERT(slot != NULL); if( PK11_Logout(slot) != SECSuccess) { JSS_nativeThrowMsg( env, TOKEN_EXCEPTION, "Unable to logout token" ); goto finish; } finish: return; } /************************************************************************ * * P K 1 1 T o k e n . g e t L o g i n M o d e * * Returns the login mode (ONE_TIME, TIMEOUT, EVERY_TIME) for this token. * These constants must sync with the ones defined in CryptoToken. */ #define ONE_TIME 0 #define TIMEOUT 1 #define EVERY_TIME 2 /************************************************************************ * * P K 1 1 T o k e n . g e t L o g i n M o d e * */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_getLoginMode (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jint mode=ONE_TIME; int askpw; int timeout; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); if(askpw == -1) { mode = EVERY_TIME; } else if(askpw == 0) { mode = ONE_TIME; } else if(askpw == 1) { mode = TIMEOUT; } else { JSS_throw(env, TOKEN_EXCEPTION); goto finish; } finish: return mode; } /************************************************************************ * * P K 1 1 T o k e n . g e t L o g i n T i m e o u t M i n u t e s */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_getLoginTimeoutMinutes (JNIEnv *env, jobject this) { PK11SlotInfo *slot; int askpw; int timeout=0; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); finish: return timeout; } /************************************************************************ * * P K 1 1 T o k e n . s e t L o g i n M o d e * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_setLoginMode (JNIEnv *env, jobject this, jint mode) { PK11SlotInfo *slot; int askpw, timeout; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); if(mode == EVERY_TIME) { askpw = -1; } else if(mode == ONE_TIME) { askpw = 0; } else if(mode == TIMEOUT) { askpw = 1; } else { JSS_throw(env, TOKEN_EXCEPTION); goto finish; } PK11_SetSlotPWValues(slot, askpw, timeout); finish: ; } /************************************************************************ * * P K 1 1 T o k e n . s e t L o g i n T i m e o u t M i n u t e s * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_setLoginTimeoutMinutes (JNIEnv *env, jobject this, jint newTimeout) { PK11SlotInfo *slot; int askpw, timeout; PR_ASSERT(env!=NULL && this!=NULL); if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return; } PR_ASSERT(slot!=NULL); PK11_GetSlotPWValues(slot, &askpw, &timeout); PK11_SetSlotPWValues(slot, askpw, newTimeout); } /************************************************************************ * * P K 1 1 T o k e n . i s P r e s e n t * * Returns true if this token is present in the slot */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_isPresent (JNIEnv *env, jobject this) { PK11SlotInfo *slot; jboolean retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ retval = JNI_FALSE; goto finish; } PR_ASSERT(slot != NULL); if(PK11_IsPresent(slot) == PR_TRUE) { retval = JNI_TRUE; } else { retval = JNI_FALSE; } finish: return retval; } /************************************************************************ * * P K 1 1 T o k e n . P W I n i t a b l e * * Make sure this token can be initialized. Currently we only check the * internal module, since it can't be initialized more than once. * Presumably most tokens can have their PINs initialized arbitrarily * many times. */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_PWInitable (JNIEnv *env, jobject this) { PK11SlotInfo *slot=NULL; jboolean initable=JNI_FALSE; PR_ASSERT(env!=NULL && this!=NULL); /* * Convert Java objects to native objects */ if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } PR_ASSERT(slot!=NULL); if(slot != PK11_GetInternalKeySlot()) { /* We don't know about other tokens */ initable = JNI_TRUE; } else { if(PK11_NeedUserInit(slot)) { initable = JNI_TRUE; } else { /* Internal module only allows one init, after this you * need to do a changePIN */ initable = JNI_FALSE; } } finish: return initable; } /************************************************************************ * * P K 1 1 T o k e n . i n i t P a s s w o r d * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_initPassword (JNIEnv *env, jobject this, jbyteArray ssopw, jbyteArray userpw) { PK11SlotInfo *slot=NULL; char *szSsopw=NULL, *szUserpw=NULL; jboolean ssoIsCopy, userIsCopy; SECStatus initResult; PRErrorCode error; PR_ASSERT(env!=NULL && this!=NULL && ssopw!=NULL && userpw!=NULL); /* * Convert Java objects to native objects */ if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } szSsopw = (char*) (*env)->GetByteArrayElements(env, ssopw, &ssoIsCopy); szUserpw = (char*) (*env)->GetByteArrayElements(env, userpw, &userIsCopy); PR_ASSERT(slot!=NULL && szSsopw!=NULL && szUserpw!=NULL); /* * If we're on the internal module, make sure we can still be * initialized. */ if(slot == PK11_GetInternalKeySlot() && !PK11_NeedUserInit(slot)) { JSS_nativeThrowMsg(env, ALREADY_INITIALIZED_EXCEPTION, "Netscape Internal Key Token is already initialized"); goto finish; } /* * Initialize the PIN */ initResult = PK11_InitPin(slot, szSsopw, szUserpw); if(initResult != SECSuccess) { error = PR_GetError(); } /* * Throw exception if an error occurred */ if(initResult != SECSuccess) { if(error == SEC_ERROR_BAD_PASSWORD) { JSS_nativeThrowMsg( env, INCORRECT_PASSWORD_EXCEPTION, "Incorrect security officer PIN" ); } else { JSS_nativeThrowMsg( env, TOKEN_EXCEPTION, "Unable to initialize PIN" ); } } finish: /* * Free native objects */ if(szSsopw) { if(ssoIsCopy) { JSS_wipeCharArray(szSsopw); } /* JNI_ABORT means don't copy back changes */ (*env)->ReleaseByteArrayElements(env, ssopw, (jbyte*)szSsopw, JNI_ABORT); } if(szUserpw) { if(userIsCopy) { JSS_wipeCharArray(szUserpw); } (*env)->ReleaseByteArrayElements(env, userpw, (jbyte*)szUserpw, JNI_ABORT); } return; } /************************************************************************ * * P K 1 1 T o k e n . p a s s w o r d I s I n i t i a l i z e d * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_passwordIsInitialized (JNIEnv *env, jobject this) { PK11SlotInfo *slot=NULL; jboolean isInitialized = JNI_FALSE; PR_ASSERT(env!=NULL && this!=NULL); /* * Convert Java arguments to C */ if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); if(slot == PK11_GetInternalKeySlot()) { /* special case for our Key slot */ isInitialized = ! PK11_NeedPWInit(); } else { isInitialized = ! PK11_NeedUserInit(slot); } finish: return isInitialized; } /************************************************************************ * * P K 1 1 T o k e n . c h a n g e P a s s w o r d * */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_changePassword (JNIEnv *env, jobject this, jbyteArray oldPIN, jbyteArray newPIN) { PK11SlotInfo *slot=NULL; char *szOldPIN=NULL, *szNewPIN=NULL; jboolean oldIsCopy, newIsCopy; SECStatus changeResult; PRErrorCode error; PR_ASSERT(env!=NULL && this!=NULL && oldPIN!=NULL && newPIN!=NULL); /* * Convert Java objects to native objects */ if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception was thrown */ goto finish; } szOldPIN= (char*) (*env)->GetByteArrayElements(env, oldPIN, &oldIsCopy); szNewPIN= (char*) (*env)->GetByteArrayElements(env, newPIN, &newIsCopy); PR_ASSERT(slot!=NULL && szOldPIN!=NULL && szNewPIN!=NULL); /* * Change the PIN */ changeResult = PK11_ChangePW(slot, szOldPIN, szNewPIN); if(changeResult != SECSuccess) { error = PR_GetError(); } /* * Throw exception if an error occurred */ if(changeResult != SECSuccess) { if(error == SEC_ERROR_BAD_PASSWORD) { JSS_nativeThrowMsg( env, INCORRECT_PASSWORD_EXCEPTION, "Incorrect PIN" ); } else { JSS_nativeThrowMsg( env, TOKEN_EXCEPTION, "Unable to change PIN" ); } } finish: /* Free native objects */ if(szOldPIN) { if(oldIsCopy) { JSS_wipeCharArray(szOldPIN); } /* JNI_ABORT means don't copy back changes */ (*env)->ReleaseByteArrayElements(env, oldPIN, (jbyte*)szOldPIN, JNI_ABORT); } if(szNewPIN) { if(newIsCopy) { JSS_wipeCharArray(szNewPIN); } (*env)->ReleaseByteArrayElements(env, newPIN, (jbyte*)szNewPIN, JNI_ABORT); } return; } typedef enum { SSOPW, USERPW } pwType; /************************************************************************ * * p a s s w o r d I s C o r r e c t * * Checks the given password, which could be an SSO or a user password. * Returns JNI_TRUE if the password is correct, JNI_FALSE if it isn't, * and may throw an exception if something goes wrong on the token. */ static jboolean passwordIsCorrect (JNIEnv *env, jobject this, jbyteArray password, pwType type) { PK11SlotInfo *slot = NULL; char *pwBytes=NULL; jboolean isCopy; jboolean pwIsCorrect = JNI_FALSE; SECStatus status; int error; PR_ASSERT(env!=NULL && this!=NULL && password!=NULL); /* * Convert Java args to C */ if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } pwBytes = (char*) (*env)->GetByteArrayElements(env, password, &isCopy); PR_ASSERT(slot!=NULL && pwBytes != NULL); /* * Do the check */ if(type == SSOPW) { status = PK11_CheckSSOPassword(slot, pwBytes); } else { status = PK11_CheckUserPassword(slot, pwBytes); } if(status == SECSuccess) { pwIsCorrect = JNI_TRUE; } else { error = PR_GetError(); if(error == SEC_ERROR_BAD_PASSWORD) { /* just wrong password */ pwIsCorrect = JNI_FALSE; } else { /* some token problem */ JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "Unable to check password"); goto finish; } } finish: /* Free native objects */ if(pwBytes != NULL) { if(isCopy) { JSS_wipeCharArray(pwBytes); } /* JNI_ABORT means don't copy back changes */ (*env)->ReleaseByteArrayElements(env, password, (jbyte*)pwBytes, JNI_ABORT); } return pwIsCorrect; } /************************************************************************ * * P K 1 1 T o k e n . u s e r P a s s w o r d I s C o r r e c t * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_userPasswordIsCorrect (JNIEnv *env, jobject this, jbyteArray password) { return passwordIsCorrect(env, this, password, USERPW); } /************************************************************************ * * P K 1 1 T o k e n . S S O P a s s w o r d I s C o r r e c t * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_SSOPasswordIsCorrect (JNIEnv *env, jobject this, jbyteArray password) { return passwordIsCorrect(env, this, password, SSOPW); } /************************************************************************ * * P K 1 1 T o k e n . g e t N a m e * * Returns the name of this token. */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_getName (JNIEnv *env, jobject this) { char *szName; PK11SlotInfo *slot; jstring name; jstring retval; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL ); /* an exception was thrown */ retval = NULL; goto finish; } PR_ASSERT(slot != NULL); szName = PK11_GetTokenName(slot); /* NULL C string converts to empty Java string */ if(szName == NULL) { szName = ""; } name = (*env)->NewStringUTF(env, szName); /* name could be NULL, if an OutOfMemoryError occurred. In that case, * we just return NULL and let the exception be thrown in Java */ #ifdef DEBUG if(name == NULL) { /* Make sure there is an exception before we return NULL */ PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); } #endif retval = name; finish: return retval; } /************************************************************************ * * T o k e n P r o x y . r e l e a s e N a t i v e R e s o u r c e s * * Free the PK11SlotInfo structure that underlies my token. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_pkcs11_TokenProxy_releaseNativeResources (JNIEnv *env, jobject this) { PK11SlotInfo *slot; PR_ASSERT(env!=NULL && this!=NULL); if(JSS_getPtrFromProxy(env, this, (void**)&slot) != PR_SUCCESS) { PR_ASSERT( PR_FALSE ); goto finish; } /* * PK11Token never stores a null pointer in its TokenProxy member, * but PK11Cert may store a null pointer in its TokenProxy member. * (A temporary certificate has a null slot pointer.) */ if(slot != NULL) { /* this actually only frees the data structure if we were the last * reference to it */ PK11_FreeSlot(slot); } finish: return; } /************************************************************************ * * J S S _ g e t T o k e n S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given token. * * tokenObject: A reference to a Java PK11Token * ptr: address of a PK11SlotInfo* that will be loaded with the PK11SlotInfo * pointer of the given token. * returns: PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getTokenSlotPtr(JNIEnv *env, jobject tokenObject, PK11SlotInfo **ptr) { PR_ASSERT(env != NULL && tokenObject != NULL && ptr != NULL); /* * Get the pointer from the PK11Token, which has a Token Proxy member */ PR_ASSERT(sizeof(PK11SlotInfo*) == sizeof(void*)); return JSS_getPtrFromProxyOwner(env, tokenObject, PK11TOKEN_PROXY_FIELD, PK11TOKEN_PROXY_SIG, (void**)ptr); } /********************************************************************** * * PK11Token.doesAlgorithm * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_doesAlgorithm (JNIEnv *env, jobject this, jobject alg) { PK11SlotInfo *slot; CK_MECHANISM_TYPE mech; jboolean doesMech = JNI_FALSE; if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } PR_ASSERT(slot != NULL); mech = JSS_getPK11MechFromAlg(env, alg); /* not an assertion, some algorithms don't have Mechanism yet */ /*PR_ASSERT( mech != CKM_INVALID_MECHANISM ); */ if( PK11_DoesMechanism(slot, mech) == PR_TRUE) { doesMech = JNI_TRUE; } /* HACK...exceptions */ if( PK11_IsInternal(slot) && mech == CKM_PBA_SHA1_WITH_SHA1_HMAC ) { /* Although the internal slot doesn't actually do this mechanism, * we do it by hand in PK11KeyGenerator.c */ doesMech = JNI_TRUE; } finish: return doesMech; } /*********************************************************************** * * PK11Token.isWritable * */ JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_isWritable (JNIEnv *env, jobject this) { PK11SlotInfo *slot; if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { return JNI_FALSE; /* an exception was thrown, so it doesn't matter */ } PR_ASSERT(slot != NULL); return ! PK11_IsReadOnly(slot); } #define ZERO_SECITEM(item) {(item).len=0; (item).data=NULL;} int PK11_NumberObjectsFor(PK11SlotInfo*, CK_ATTRIBUTE*, int); /************************************************************************ * * P K 1 1 T o k e n . getCertRequest */ JNIEXPORT jstring JNICALL Java_org_mozilla_jss_pkcs11_PK11Token_generatePK10 (JNIEnv *env, jobject this, jstring subject, jint keysize, jstring keyType, jbyteArray P, jbyteArray Q, jbyteArray G) { PK11SlotInfo *slot; const char* c_subject=NULL; jboolean isCopy = JNI_FALSE; unsigned char *b64request=NULL; SECItem p, q, g; PQGParams *dsaParams=NULL; const char* c_keyType; jboolean k_isCopy = JNI_FALSE; SECOidTag signType = SEC_OID_UNKNOWN; PK11RSAGenParams rsaParams; void *params = NULL; PR_ASSERT(env!=NULL && this!=NULL); /* get keytype */ c_keyType = (*env)->GetStringUTFChars(env, keyType, &k_isCopy); if (0 == PL_strcasecmp(c_keyType, KEYTYPE_RSA_STRING)) { signType = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; if( keysize == -1 ) { rsaParams.keySizeInBits = DEFAULT_RSA_KEY_SIZE; } else { rsaParams.keySizeInBits = keysize; } rsaParams.pe = DEFAULT_RSA_PUBLIC_EXPONENT; params = (void *)&rsaParams; } else if (0 == PL_strcasecmp(c_keyType, KEYTYPE_DSA_STRING)) { signType = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; if (P==NULL || Q==NULL || G ==NULL) { /* shouldn't happen */ JSS_throw(env, INVALID_PARAMETER_EXCEPTION); } else { /* caller supplies PQG */ /* zero these so we can free them indiscriminately later */ ZERO_SECITEM(p); ZERO_SECITEM(q); ZERO_SECITEM(g); if( JSS_ByteArrayToOctetString(env, P, &p) || JSS_ByteArrayToOctetString(env, Q, &q) || JSS_ByteArrayToOctetString(env, G, &g) ) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); goto finish; } dsaParams = PK11_PQG_NewParams(&p, &q, &g); if(dsaParams == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } } params = (void *)dsaParams; } else if (0 == PL_strcasecmp(c_keyType, KEYTYPE_EC_STRING)) { signType = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; /* get ec param */ } else { JSS_throw(env, INVALID_PARAMETER_EXCEPTION); } if( JSS_PK11_getTokenSlotPtr(env, this, &slot) != PR_SUCCESS) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); /* an exception occurred */ goto finish; } PR_ASSERT(slot != NULL); if(PK11_IsLoggedIn(slot, NULL) != PR_TRUE) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "token not logged in"); } /* get subject */ c_subject = (*env)->GetStringUTFChars(env, subject, &isCopy); /* call GenerateCertRequest() */ GenerateCertRequest(env, signType, c_subject, slot, &b64request, params); finish: if (isCopy == JNI_TRUE) { /* release memory */ (*env)->ReleaseStringUTFChars(env, subject, c_subject); } if (k_isCopy == JNI_TRUE) { /* release memory */ (*env)->ReleaseStringUTFChars(env, keyType, c_keyType); } if (signType == SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) { SECITEM_FreeItem(&p, PR_FALSE); SECITEM_FreeItem(&q, PR_FALSE); SECITEM_FreeItem(&g, PR_FALSE); PK11_PQG_DestroyParams(dsaParams); } if (b64request == NULL) { return NULL; } else { /* convert to String */ return (*env)->NewStringUTF(env, (const char *)b64request); } } /* * generate keypairs and further the request * the real thing will need keytype and pqg numbers (for DSA) */ void GenerateCertRequest(JNIEnv *env, SECOidTag signType, const char *subject, PK11SlotInfo *slot, unsigned char **b64request, void *params) { CERTCertificateRequest *req; SECKEYPrivateKey *privk = NULL; SECKEYPublicKey *pubk = NULL; SECStatus rv; PRArenaPool *arena; SECItem result_der, result; SECItem * VARIABLE_MAY_NOT_BE_USED blob; CK_MECHANISM_TYPE signMech; CK_MECHANISM_TYPE keygenMech; #ifdef DEBUG printf("in GenerateCertRequest(), subject=%s, ", subject); #endif /* * Use the tables to reduce the code of adding new * types of keys. */ signMech = PK11_AlgtagToMechanism(signType); if (signMech == CKM_INVALID_MECHANISM) { #ifdef DEBUG printf("Error getting KEYGEN Mechanism."); #endif } keygenMech = PK11_GetKeyGen(signMech); if( JSS_PK11_generateKeyPair(env, keygenMech, slot, &pubk, &privk, params, PR_FALSE, -1, -1) != SECSuccess) { #ifdef DEBUG printf("Error generating keypair."); #endif } #ifdef DEBUG printf("before make_cert_request"); #endif req = make_cert_request (env, subject, pubk); #ifdef DEBUG printf("after make_cert_request"); #endif if (req == NULL) { return; } result_der.len = 0; result_der.data = NULL; #ifdef DEBUG printf("before SEC_ASN1EncodeItem"); #endif /* der encode the request */ blob = SEC_ASN1EncodeItem(req->arena, &result_der, req, SEC_ASN1_GET(CERT_CertificateRequestTemplate)); /* sign the request */ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( !arena ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); return; } rv = SEC_DerSignData(arena, &result, result_der.data, result_der.len, privk, signType); if (rv) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "signing of data failed"); PORT_FreeArena(arena, PR_FALSE); return; } *b64request = (unsigned char*) BTOA_DataToAscii(result.data, result.len); PORT_FreeArena(arena, PR_FALSE); #ifdef DEBUG printf("data = %s\n", *b64request); #endif } /****************************************************************** * * m a k e _ c e r t _ r e q u e s t */ static CERTCertificateRequest* make_cert_request(JNIEnv *env, const char *subject, SECKEYPublicKey *pubk) { CERTName *subj = NULL; CERTSubjectPublicKeyInfo *spki = NULL; CERTCertificateRequest *req = NULL; /* Create info about public key */ spki = SECKEY_CreateSubjectPublicKeyInfo(pubk); if (!spki) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "unable to create subject public key"); goto finish; } subj = CERT_AsciiToName ((char *)subject); if(subj == NULL) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "Invalid data in certificate description"); goto finish; } /* Generate certificate request */ req = CERT_CreateCertificateRequest(subj, spki, 0); if (!req) { JSS_nativeThrowMsg(env, TOKEN_EXCEPTION, "unable to make certificate request"); goto finish; } #ifdef DEBUG printf("certificate request generated\n"); #endif finish: if (subj) { CERT_DestroyName(subj); } if (spki) { SECKEY_DestroySubjectPublicKeyInfo(spki); } return req; } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11Token.java000066400000000000000000000412351326145000000215730ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import java.util.*; import org.mozilla.jss.util.*; import org.mozilla.jss.crypto.*; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.InvalidParameterException; /** * A PKCS #11 token. Currently, these can only be obtained from the * CryptoManager class. * * @author nicolson * @version $Revision$ $Date$ * @see org.mozilla.jss.CryptoManager */ public final class PK11Token implements CryptoToken { //////////////////////////////////////////////////// // exceptions //////////////////////////////////////////////////// /** * Thrown if the operation requires that the token be logged in, and it * isn't. */ static public class NotInitializedException extends IncorrectPasswordException { public NotInitializedException() {} public NotInitializedException(String mesg) {super(mesg);} } //////////////////////////////////////////////////// // public routines //////////////////////////////////////////////////// public org.mozilla.jss.crypto.Signature getSignatureContext(SignatureAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { Assert._assert(algorithm!=null); return Tunnel.constructSignature( algorithm, new PK11Signature(this, algorithm) ); } public JSSMessageDigest getDigestContext(DigestAlgorithm algorithm) throws NoSuchAlgorithmException, java.security.DigestException { if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException(); } return new PK11MessageDigest(this, algorithm); } public Cipher getCipherContext(EncryptionAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException( algorithm+" is not supported by this token"); } return new PK11Cipher(this, algorithm); } public KeyGenerator getKeyGenerator(KeyGenAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { /* NSS is capable of finding the right token to do algorithm, so this call is prematurely bailing if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException( algorithm+" is not supported by this token"); } */ return new PK11KeyGenerator(this, algorithm); } /** * Allows a SymmetricKey to be cloned on a different token. * * @exception SymmetricKey.NotExtractableException If the key material * cannot be extracted from the current token. * @exception InvalidKeyException If the owning token cannot process * the key to be cloned. */ public SymmetricKey cloneKey(SymmetricKey key) throws SymmetricKey.NotExtractableException, InvalidKeyException, TokenException { return PK11KeyGenerator.clone(key, this); } public PK11SymmetricKeyDeriver getSymmetricKeyDeriver() { return new PK11SymmetricKeyDeriver(this); } public KeyWrapper getKeyWrapper(KeyWrapAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { /* NSS is capable of finding the right token to do algorithm, so this call is prematurely bailing if( ! doesAlgorithm(algorithm) ) { throw new NoSuchAlgorithmException( algorithm+" is not supported by this token"); } */ return new PK11KeyWrapper(this, algorithm); } public java.security.SecureRandom getRandomGenerator() throws NotImplementedException, TokenException { throw new NotImplementedException(); } public org.mozilla.jss.crypto.KeyPairGenerator getKeyPairGenerator(KeyPairAlgorithm algorithm) throws NoSuchAlgorithmException, TokenException { Assert._assert(algorithm!=null); return new KeyPairGenerator(algorithm, new PK11KeyPairGenerator(this, algorithm)); } public native boolean isLoggedIn() throws TokenException; public native boolean needsLogin() throws TokenException; /** * Log into the token. If you are already logged in, this method has * no effect, even if the PIN is wrong. * * @param callback A callback to use to obtain the password, or a * Password object. * @exception NotInitializedException The token has not yet been * initialized. * @exception IncorrectPasswordException The specified password * was incorrect. */ public void login(PasswordCallback callback) throws NotInitializedException, IncorrectPasswordException, TokenException { if(callback == null) { callback = new NullPasswordCallback(); } nativeLogin(callback); } protected native void nativeLogin(PasswordCallback callback) throws NotInitializedException, IncorrectPasswordException, TokenException; /** * @return true if the token is writable, false if it is read-only. * Writable tokens can have their keys generated on the internal token * and then moved out. */ public native boolean isWritable(); /** * Determines if the given token is present on the system. * This would return false, for example, for a smart card reader * that didn't have a card inserted. */ public native boolean isPresent(); /** * Log out of the token. * * @exception TokenException If you are already logged in, or an * unspecified error occurs. */ public native void logout() throws TokenException; public native int getLoginMode() throws TokenException; public native void setLoginMode(int mode) throws TokenException; public native int getLoginTimeoutMinutes() throws TokenException; public native void setLoginTimeoutMinutes(int timeoutMinutes) throws TokenException; /** * Determines whether this is a removable token. For example, a smart card * is removable, while the Netscape internal module and a hardware * accelerator card are not removable. * @return true if the token is removable, false otherwise. */ //public native boolean isRemovable(); /** * Initialize PIN. This sets the user's new PIN, using the current * security officer PIN for authentication. * * @param ssopwcb The security officer's current password callback. * @param userpwcb The user's new password callback. * @exception IncorrectPasswordException If the security officer PIN is * incorrect. * @exception AlreadyInitializedException If the password hasn't already * been set. * @exception TokenException If the PIN was already initialized, * or there was an unspecified error in the token. */ public void initPassword(PasswordCallback ssopwcb, PasswordCallback userpwcb) throws IncorrectPasswordException, AlreadyInitializedException, TokenException { byte[] ssopwArray = null; byte[] userpwArray = null; Password ssopw=null; Password userpw=null; PasswordCallbackInfo pwcb = makePWCBInfo(); if(ssopwcb==null) { ssopwcb = new NullPasswordCallback(); } if(userpwcb==null) { userpwcb = new NullPasswordCallback(); } try { // Make sure the password hasn't already been set, doing special // checks for the internal module if(!PWInitable()) { throw new AlreadyInitializedException(); } // Verify the SSO Password, except on internal module if( isInternalKeyStorageToken() ) { ssopwArray = new byte[] {0}; } else { ssopw = ssopwcb.getPasswordFirstAttempt(pwcb); ssopwArray = Tunnel.getPasswordByteCopy(ssopw); while( ! SSOPasswordIsCorrect(ssopwArray) ) { Password.wipeBytes(ssopwArray); ssopw.clear(); ssopw = ssopwcb.getPasswordAgain(pwcb); ssopwArray = Tunnel.getPasswordByteCopy(ssopw); } } // Now change the PIN userpw = userpwcb.getPasswordFirstAttempt(pwcb); userpwArray = Tunnel.getPasswordByteCopy(userpw); initPassword(ssopwArray, userpwArray); } catch (PasswordCallback.GiveUpException e) { throw new IncorrectPasswordException(e.toString()); } finally { // zero-out the arrays if(ssopwArray != null) { Password.wipeBytes(ssopwArray); } if(ssopw != null) { ssopw.clear(); } if(userpwArray != null) { Password.wipeBytes(userpwArray); } if(userpw != null) { userpw.clear(); } } } /** * Make sure the PIN can be initialized. This is mainly to check the * internal module. */ protected native boolean PWInitable() throws TokenException; protected native boolean SSOPasswordIsCorrect(byte[] ssopw) throws TokenException, AlreadyInitializedException; protected native void initPassword(byte[] ssopw, byte[] userpw) throws IncorrectPasswordException, AlreadyInitializedException, TokenException; /** * Determine whether the token has been initialized yet. */ public native boolean passwordIsInitialized() throws TokenException; /** * Change password. This changes the user's PIN after it has already * been initialized. * * @param oldPINcb The user's old PIN callback. * @param newPINcb The new PIN callback. * @exception IncorrectPasswordException If the old PIN is incorrect. * @exception TokenException If some other error occurs on the token. * */ public void changePassword(PasswordCallback oldPINcb, PasswordCallback newPINcb) throws IncorrectPasswordException, TokenException { byte[] oldPW = null; byte[] newPW = null; Password oldPIN=null; Password newPIN=null; PasswordCallbackInfo pwcb = makePWCBInfo(); if(oldPINcb==null) { oldPINcb = new NullPasswordCallback(); } if(newPINcb==null) { newPINcb = new NullPasswordCallback(); } try { // Verify the old password oldPIN = oldPINcb.getPasswordFirstAttempt(pwcb); oldPW = Tunnel.getPasswordByteCopy(oldPIN); if( ! userPasswordIsCorrect(oldPW) ) { do { Password.wipeBytes(oldPW); oldPIN.clear(); oldPIN = oldPINcb.getPasswordAgain(pwcb); oldPW = Tunnel.getPasswordByteCopy(oldPIN); } while( ! userPasswordIsCorrect(oldPW) ); } // Now change the PIN newPIN = newPINcb.getPasswordFirstAttempt(pwcb); newPW = Tunnel.getPasswordByteCopy(newPIN); changePassword(oldPW, newPW); } catch (PasswordCallback.GiveUpException e) { throw new IncorrectPasswordException(e.toString()); } finally { if(oldPW != null) { Password.wipeBytes(oldPW); } if(oldPIN != null) { oldPIN.clear(); } if(newPW != null) { Password.wipeBytes(newPW); } if(newPIN != null) { newPIN.clear(); } } } protected PasswordCallbackInfo makePWCBInfo() { return new TokenCallbackInfo(getName()); } /** * Check the given password, return true if it's right, false if it's * wrong. */ protected native boolean userPasswordIsCorrect(byte[] pw) throws TokenException; /** * Change the password on the token from the old one to the new one. */ protected native void changePassword(byte[] oldPIN, byte[] newPIN) throws IncorrectPasswordException, TokenException; public native String getName(); public java.security.Provider getProvider() { Assert.notYetImplemented("Providers not implemented by PK11Token yet"); return null; } public CryptoStore getCryptoStore() { return cryptoStore; } /** * Determines whether this token is capable of performing the given * PKCS #11 mechanism. */ /* public boolean doesMechanism(Mechanism mech) { return doesMechanismNative(mech.getValue()); } */ /** * Deep-comparison operator. * * @return true if these tokens point to the same underlying native token. * false otherwise, or if compare is null. */ public boolean equals(Object obj) { if(obj==null) { return false; } else { if( ! (obj instanceof PK11Token) ) { return false; } return tokenProxy.equals(((PK11Token)obj).tokenProxy); } } //protected native boolean doesMechanismNative(int mech); /** * Determines whether this token is capable of performing the given * algorithm. */ public native boolean doesAlgorithm(Algorithm alg); /** * Generates a PKCS#10 certificate request including Begin/End brackets * @param subject subject dn of the certificate * @param keysize size of the key * @param keyType "rsa" or "dsa" * @param P The DSA prime parameter * @param Q The DSA sub-prime parameter * @param G The DSA base parameter * @return String that represents a PKCS#10 b64 encoded blob with * begin/end brackets */ public String generateCertRequest(String subject, int keysize, String keyType, byte[] P, byte[] Q, byte[] G) throws TokenException, InvalidParameterException, PQGParamGenException { if (keyType.equalsIgnoreCase("dsa")) { if ((P == null) && (Q == null) && (G == null)) { PQGParams pqg; try { pqg = PQGParams.generate(keysize); } catch (PQGParamGenException e) { throw e; } byte[] p = PQGParams.BigIntegerToUnsignedByteArray(pqg.getP()); byte[] q = PQGParams.BigIntegerToUnsignedByteArray(pqg.getQ()); byte[] g = PQGParams.BigIntegerToUnsignedByteArray(pqg.getG()); P = p; Q = q; G = g; String pk10String; try { pk10String = generatePK10(subject, keysize, keyType, p, q, g); } catch (TokenException e) { throw e; } catch (InvalidParameterException e) { throw e; } return ("-----BEGIN NEW CERTIFICATE REQUEST-----\n"+ pk10String + "\n-----END NEW CERTIFICATE REQUEST-----"); } else if ((P == null) || (Q == null) || (G == null)) { throw new InvalidParameterException("need all P, Q, and G"); } } String pk10String; try { pk10String = generatePK10(subject, keysize, keyType, P, Q, G); } catch (TokenException e) { throw e; } catch (InvalidParameterException e) { throw e; } return ("-----BEGIN NEW CERTIFICATE REQUEST-----\n"+ pk10String + "\n-----END NEW CERTIFICATE REQUEST-----"); } protected native String generatePK10(String subject, int keysize, String keyType, byte[] P, byte[] Q, byte[] G) throws TokenException, InvalidParameterException; //////////////////////////////////////////////////// // construction and finalization //////////////////////////////////////////////////// /* * Default constructor should never be called. */ protected PK11Token() { Assert._assert(false); } /** * Creates a new PK11Token. Should only be called from PK11Token's * native code. * @param pointer A byte array containing a pointer to a PKCS #11 slot. */ protected PK11Token(byte[] pointer, boolean internal, boolean keyStorage) { Assert._assert(pointer!=null); tokenProxy = new TokenProxy(pointer); mIsInternalCryptoToken = internal; mIsInternalKeyStorageToken = keyStorage; cryptoStore = new PK11Store(tokenProxy); } /* protected PK11Token(TokenProxy proxy) { Assert._assert(proxy!=null); this.tokenProxy = proxy; } */ public TokenProxy getProxy() { return tokenProxy; } /** * @return true if this is the internal token used for bulk crypto. */ public boolean isInternalCryptoToken() { return mIsInternalCryptoToken; } protected boolean mIsInternalCryptoToken; /** * @return true if this is the internal key storage token. */ public boolean isInternalKeyStorageToken() { return mIsInternalKeyStorageToken; } protected boolean mIsInternalKeyStorageToken; ////////////////////////////////////////////////// // Private Data ////////////////////////////////////////////////// protected TokenProxy tokenProxy; protected PK11Store cryptoStore; } /** * This class just hard-wires the type to be TOKEN so we don't have to mess * with Java constants in native code. */ class TokenCallbackInfo extends PasswordCallbackInfo { public TokenCallbackInfo(String name) { super(name, TOKEN); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/PK11TokenCert.java000066400000000000000000000012741326145000000224100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.*; /** * A user certificate that lives on a PKCS #11 token. */ public final class PK11TokenCert extends PK11Cert implements TokenCertificate { public byte[] getUniqueID() { return super.getUniqueID(); } public CryptoToken getOwningToken() { return super.getOwningToken(); } PK11TokenCert(byte[] certPtr, byte[] slotPtr, String nickname) { super(certPtr, slotPtr, nickname); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/TokenProxy.java000066400000000000000000000012371326145000000222360ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.util.NativeProxy; import org.mozilla.jss.util.Debug; public final class TokenProxy extends NativeProxy { public TokenProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { Debug.trace(Debug.OBNOXIOUS, "Finalizing a TokenProxy"); super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/Tunnel.java000066400000000000000000000022321326145000000213550ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs11; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.SignatureSpi; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.util.Password; final class Tunnel { private static class CryptoTunnel extends org.mozilla.jss.crypto.Tunnel { public static Signature constructSignature(SignatureAlgorithm alg, SignatureSpi engine) { return ConstructSignature(alg, engine); } } private static class UtilTunnel extends org.mozilla.jss.util.Tunnel { public static byte[] getPasswordByteCopy(Password pw) { return GetPasswordByteCopy(pw); } } static Signature constructSignature(SignatureAlgorithm alg, SignatureSpi engine) { return CryptoTunnel.constructSignature(alg, engine); } static byte[] getPasswordByteCopy(Password pw) { return UtilTunnel.getPasswordByteCopy(pw); } } jss-4.4.3/jss/org/mozilla/jss/pkcs11/config.mk000066400000000000000000000004201326145000000210400ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/pkcs11/manifest.mn000066400000000000000000000017421326145000000214140ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 REQUIRES = nspr20 nss PACKAGE = org/mozilla/jss/pkcs11 # These are meant to be used within Ninja only. PRIVATE_EXPORTS = pk11util.h \ $(NULL) CSRCS = \ PK11Cert.c \ PK11Cipher.c \ PK11KeyGenerator.c \ PK11KeyPairGenerator.c \ PK11KeyWrapper.c \ PK11MessageDigest.c \ PK11Module.c \ PK11PrivKey.c \ PK11PubKey.c \ PK11Signature.c \ PK11SecureRandom.c \ PK11Store.c \ PK11SymKey.c \ PK11Token.c \ PK11SymmetricKeyDeriver.c \ $(NULL) LIBRARY_NAME = jsspkcs11 jss-4.4.3/jss/org/mozilla/jss/pkcs11/pk11util.h000066400000000000000000000426241326145000000211010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* need to include these first: * * certt.h * nspr.h * jni.h * secmodt.h */ #ifndef JSS_PK11_UTIL_H #define JSS_PK11_UTIL_H PR_BEGIN_EXTERN_C /*===================================================================== K E Y S =====================================================================*/ /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P r i v K e y * privk: will be eaten by the wrapper and set to NULL. * Returns: a new PK11PrivKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapPrivKey(JNIEnv *env, SECKEYPrivateKey **privk); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P u b K e y * privk: will be eaten by the wrapper and set to NULL. * Returns: a new PK11PubKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapPubKey(JNIEnv *env, SECKEYPublicKey **pubk); /************************************************************************** * Given a PrivateKey object, extracts the SECKEYPrivateKey* and stores it * at the given address. * * privkObject: A JNI reference to a PrivateKey object. * ptr: Address of a SECKEYPrivateKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPrivKeyPtr(JNIEnv *env, jobject privkObject, SECKEYPrivateKey** ptr); /*********************************************************************** * Given a PublicKey object, extracts the SECKEYPublicKey* and stores it * at the given address. * * pubkObject: A JNI reference to a PublicKey object. * ptr: Address of a SECKEYPublicKey* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getPubKeyPtr(JNIEnv *env, jobject pubkObject, SECKEYPublicKey** ptr); /*********************************************************************** * J S S _ P K 1 1 _ g e t S y m K e y P t r * * Given a Java PK11SymKey, extracts the C PK11SymKey and stores it at * the given address. */ PRStatus JSS_PK11_getSymKeyPtr(JNIEnv *env, jobject symKeyObject, PK11SymKey **ptr); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p S y m K e y * symKey: will be stored in a Java wrapper. * Returns: a new PK11SymKey, or NULL if an exception occurred. */ jobject JSS_PK11_wrapSymKey(JNIEnv *env, PK11SymKey **symKey); /*********************************************************************** * JSS_PK11_getKeyType * * Converts a PrivateKey.KeyType object to a PKCS #11 key type. * * INPUTS * keyTypeObj * A org.mozilla.jss.crypto.PrivateKey.KeyType object. * RETURNS * The key type, or nullKey if an exception occurred. */ KeyType JSS_PK11_getKeyType(JNIEnv *env, jobject keyTypeObj); /*********************************************************************** * JSS_PK11_generateKeyPair * * Create a new key pair based on the passed in mechanism and parameters * * INPUTS * mechanism * A PKCS#11 KeyPair Mechanism * slot * Slot to generate the keypair in. * pubk * returned public key * privk * returned private key key * param * PKCS #11 mechanism parameters * temporary * boolean to say if the key is temporary or permanent * sensitive * int to say if the key should be sensitive or not (-1 is default) * extractable * int to say if the key should be extractable or not (-1 is default) * RETURNS * The SECStatus, SECSuccess of success, SECFailure on failure */ SECStatus JSS_PK11_generateKeyPair(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privK, void *params, PRBool temporary, jint senstive, jint extractable); SECStatus JSS_PK11_generateKeyPair_withOpFlags(JNIEnv *env, CK_MECHANISM_TYPE mechanism, PK11SlotInfo *slot, SECKEYPublicKey **pubk, SECKEYPrivateKey **privk, void *params, PRBool temporary, jint sensitive, jint extractable, jint op_flags, jint op_flags_mask); /*===================================================================== C E R T I F I C A T E S =====================================================================*/ /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t P t r * * Given a PK11Cert object, extracts the CERTCertificate* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a CERTCertificate* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertPtr(JNIEnv *env, jobject certObject, CERTCertificate **ptr); /****************************************************************** * * J S S _ P K 1 1 _ g e t C e r t S l o t P t r * * Given a PK11Cert object, extracts the PK11SlotInfo* and * stores it at the given address. * * certObject: A JNI reference to a JSS Certificate object. * ptr: Address of a PK11SlotInfo* that will receive the pointer. * Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCertSlotPtr(JNIEnv *env, jobject certObject, PK11SlotInfo **ptr); /************************************************************************* * * J S S _ P K 1 1 _ f i n d C e r t A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertificate * JSS_PK11_findCertAndSlotFromNickname(char *nickname, void *wincx, PK11SlotInfo **ppSlot); /*************************************************************************** * * J S S _ P K 1 1 _ f i n d C e r t s A n d S l o t F r o m N i c k n a m e * * A variant of NSS's PK11_FindCertsFromNickname function that also * returns a PK11SlotInfo* in *ppSlot. * * If nickname is of the format "token:nickname", the slot that * contains the specified token is returned. Otherwise the internal * key slot (which contains the permanent database token) is returned. */ CERTCertList * JSS_PK11_findCertsAndSlotFromNickname(char *nickname, void *wincx, PK11SlotInfo **ppSlot); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t A n d N i c k n a m e * * Builds a PK11Cert object from a CERTCertificate, a PK11SlotInfo, and * a nickname. * ppCert: Pointer to pointer to CERTCertificate. The CERTCertificate * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertificate again. To enforce this, *ppCert * will be set to NULL whether the functions fails or succeeds. * ppSlot: Pointer to pointer to PK11SlotInfo. The PK11SlotInfo * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this PK11SlotInfo again. To enforce this, *ppSlot * will be set to NULL whether the functions fails or succeeds. * nickname: the cert instance's nickname. * Returns: a new Java PK11Cert object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlotAndNickname(JNIEnv *env, CERTCertificate **ppCert, PK11SlotInfo **ppSlot, const char *nickname); /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t A n d S l o t * * Builds a PK11Cert object from a CERTCertificate and a PK11SlotInfo. * ppCert: Pointer to pointer to CERTCertificate. The CERTCertificate * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertificate again. To enforce this, *ppCert * will be set to NULL whether the functions fails or succeeds. * ppSlot: Pointer to pointer to PK11SlotInfo. The PK11SlotInfo * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this PK11SlotInfo again. To enforce this, *ppSlot * will be set to NULL whether the functions fails or succeeds. * Returns: a new Java PK11Cert object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCertAndSlot(JNIEnv *env, CERTCertificate **ppCert, PK11SlotInfo **ppSlot); /**************************************************************** * * J S S _ P K 1 1 _ w r a p C e r t * * Builds a PK11Cert object from a CERTCertificate. * ppCert: Pointer to pointer to CERTCertificate. The CERTCertificate * will be wrapped in a Java certificate. If this fails, it * will be deleted. In any case, the caller should never worry about, * or use, this CERTCertificate again. To enforce this, *ppCert * will be set to NULL whether the functions fails or succeeds. * Returns: a new Java PK11Cert object, or NULL if an exception was thrown. * * Use JSS_PK11_wrapCertAndSlot instead if it is important for the PK11Cert * object to have the correct slot pointer or the slot pointer is readily * available. */ jobject JSS_PK11_wrapCert(JNIEnv *env, CERTCertificate **ppCert); /*===================================================================== S T O R E S =====================================================================*/ /************************************************************************ * * J S S _ g e t S t o r e S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given PK11Store. * * INPUTS * store * A reference to a Java PK11Store * slot * address of a PK11SlotInfo* that will be loaded with * the PK11SlotInfo pointer of the given token. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getStoreSlotPtr(JNIEnv *env, jobject store, PK11SlotInfo **slot); /*===================================================================== T O K E N S =====================================================================*/ /****************************************************************** ** ** J S S _ P K 1 1 _ m a k e C r y p t o T o k e n F r o m P K 1 1 ** ** Returns a new CryptoToken object, or NULL if an exception was thrown. **/ jobject JSS_PK11_makeCryptoTokenFromPK11(JNIEnv *env, jobject pk11token); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 T o k e n * * Create a PK11Token object from a PKCS #11 slot. * * slot is a pointer to a PKCS #11 slot, which must not be NULL. It will * be eaten by the wrapper and set to NULL. * * Returns a new PK11Token object, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapPK11Token(JNIEnv *env, PK11SlotInfo **slot); /************************************************************************ * * J S S _ P K 1 1 _ g e t T o k e n S l o t P t r * * Retrieve the PK11SlotInfo pointer of the given token. * * tokenObject: A reference to a Java PK11Token * ptr: address of a PK11SlotInfo* that will be loaded with the PK11SlotInfo * pointer of the given token. * returns: PR_SUCCESS if the operation was successful, PR_FAILURE if an * exception was thrown. */ PRStatus JSS_PK11_getTokenSlotPtr(JNIEnv *env, jobject tokenObject, PK11SlotInfo **ptr); /*===================================================================== M O D U L E S =====================================================================*/ /*********************************************************************** * * J S S _ P K 1 1 _ w r a p P K 1 1 M o d u l e * * Turns a SECMODModule* C structure into a PK11Module Java object. * * INPUTS * ptr * Address of a SECMODModule *. This pointer will be copied * into the new Java object, then set to NULL. * RETURNS * A new Java PK11Module object, or NULL if an exception was thrown. * In any case, the ptr parameter is eaten. */ jobject JSS_PK11_wrapPK11Module(JNIEnv *env, SECMODModule **module); /*********************************************************************** * * J S S _ P K 1 1 _ g e t M o d u l e P t r * * Retrieve the SECMODModule pointer of the given PK11Module. * * INPUTS * module * A reference to a Java PK11Module. * ptr * Address of a SECMODModule * that will be loaded with the * SECMODModule pointer of the given PK11Module. * RETURNS * PR_FAILURE if an exception was thrown, or PR_SUCCESS if the * peration succeeded. */ PRStatus JSS_PK11_getModulePtr(JNIEnv *env, jobject module, SECMODModule **ptr); /*===================================================================== C O N T E X T S =====================================================================*/ typedef enum { SGN_CONTEXT, VFY_CONTEXT } SigContextType; typedef struct SigContextProxyStr SigContextProxy; /*********************************************************************** * J S S _ P K 1 1 _ g e t S i g C o n t e x t * * Extracts the context pointer from a ContextProxy. * proxy: a non-NULL SigContextProxy object. * ptr: address of a SGNContext* or VFYContext* where the pointer will * be stored. * type: address of a SigContextType where the type of context will * be stored. * Returns: PR_SUCCESS, unless an exception was thrown. */ PRStatus JSS_PK11_getSigContext(JNIEnv *env, jobject proxy, void**pContext, SigContextType* pType); /********************************************************************** * * J S S _ P K 1 1 _ m a k e S i g C o n t e x t P r o x y * * Wraps a context in a ContextProxy. * * ctxt: address of a SGNContext* or VFYContext* that must not be NULL. * It will be eaten by the wrapper and set to NULL. * type: the type of context, SGN_CONTEXT or VFY_CONTEXT. * Returns: a new ContextProxy object wrapping the given context, * or NULL if an exception was thrown. */ jobject JSS_PK11_wrapSigContextProxy(JNIEnv *env, void **ctxt, SigContextType type); /*********************************************************************** * * J S S _ P K 1 1 _ g e t C i p h e r C o n t e x t * * Extracts the PK11Context from a CipherContextProxy. * * proxy * A CipherContextProxy. * * pContext * Address of a PK11Context*, which will be filled with the pointer * extracted from the CipherContextProxy. * * RETURNS * PR_SUCCESS for success, or PR_FAILURE if an exception was thrown. */ PRStatus JSS_PK11_getCipherContext(JNIEnv *env, jobject proxy, PK11Context **pContext); /*********************************************************************** * * J S S _ P K 1 1 _ w r a p C i p h e r C o n t e x t P r o x y * * Wraps a PK11Context in a CipherContextProxy. * * context * address of a pointer to a PK11Context, which must not be NULL. * It will be eaten by the wrapper and set to NULL, even if the * function returns NULL. * * RETURNS * A new CipherContextProxy, or NULL if an exception was thrown. */ jobject JSS_PK11_wrapCipherContextProxy(JNIEnv *env, PK11Context **context); /*===================================================================== P K C S # 1 1 H A C K S =====================================================================*/ /*********************************************************************** * * J S S _ P K 1 1 _ g e t N e w S e s s i o n * * Creates a new session. If one cannot be created, the common shared session * is returned, and *owner is set to PR_FALSE. Otherwise, the new * session is returned and *owner is set to PR_TRUE. * * slot * The slot on which to open a session. * owner * Pointer to a PRBool which will set to PR_TRUE if a new session was * created, and to PR_FALSE if the shared session was returned. * * RETURNS * A session that can be used for cryptographic operations. If *owner * is false, the session is not owned by the called but rather is shared. */ CK_SESSION_HANDLE JSS_PK11_getNewSession(PK11SlotInfo *slot, PRBool *owner); /*********************************************************************** * * J S S _ P K 1 1 _ c l o s e S e s s i o n * * Closes a session that was returned by JSS_PK11_GetNewSession. * * slot * The slot on which this session lives. * * session * The session to close. * * owner * As returned by JSS_PK11_GetNewSession. PR_TRUE if the session was * created especially for the caller, PR_FALSE if it is the common * shared session. */ void JSS_PK11_closeSession(PK11SlotInfo *slot, CK_SESSION_HANDLE session, PRBool owner); /*********************************************************************** * * J S S _ P K 1 1 _ g e t E r r o r S t r i n g * * Returns a simple error string for a given PKCS #11 error. */ char* JSS_PK11_getErrorString(CK_RV crv); PR_END_EXTERN_C #endif jss-4.4.3/jss/org/mozilla/jss/pkcs12/000077500000000000000000000000001326145000000172475ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkcs12/AuthenticatedSafes.java000066400000000000000000000436221326145000000236650ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs12; import org.mozilla.jss.util.Debug; import java.io.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkcs7.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.*; import org.mozilla.jss.CryptoManager; import java.security.*; import java.security.spec.AlgorithmParameterSpec; /** * An AuthenticatedSafes, which is a SEQUENCE of * SafeContents. */ public class AuthenticatedSafes implements ASN1Value { private SEQUENCE sequence; /** * The default number of hash iterations (1) when performing PBE keygen. */ public static final int DEFAULT_ITERATIONS = 1; /** * Salt length is variable with PKCS #12. NSS uses 16 bytes, MSIE * uses 20. We'll use 20 to get the 4 extra bytes of security. */ private static final int SALT_LENGTH = 20; /** * The default PBE key generation algorithm: SHA-1 with RC2 40-bit CBC. */ public static final PBEAlgorithm DEFAULT_KEY_GEN_ALG = PBEAlgorithm.PBE_SHA1_RC2_40_CBC; // security dynamics has a weird way of packaging things, we'll // work with it for debugging private static final boolean ACCEPT_SECURITY_DYNAMICS = false; /** * Default constructor, creates an empty AuthenticatedSafes. */ public AuthenticatedSafes() { sequence = new SEQUENCE(); } /** * Creates an AuthenticatedSafes from a SEQUENCE of ContentInfo. * @param sequence A non-null sequence of ContentInfo. */ public AuthenticatedSafes(SEQUENCE sequence) { if( sequence==null) { throw new IllegalArgumentException("parameter is null"); } if( Debug.DEBUG ) { for( int i = 0; i < sequence.size(); i++ ) { if( ! (sequence.elementAt(i) instanceof ContentInfo) ) { throw new IllegalArgumentException( "element "+i+" of sequence is not a ContentInfo"); } } } this.sequence = sequence; } /** * Returns the raw SEQUENCE which constitutes this * AuthenticatedSafes. The elements of this sequence are some * form of SafeContents, wrapped in a ContentInfo or * an EncryptedData. */ public SEQUENCE getSequence() { return sequence; } /** * Returns the size of the sequence, which is the number of SafeContents * in this AuthenticatedSafes. */ public int getSize() { return sequence.size(); } /** * Returns true if the SafeContents at the given index in the * AuthenticatedSafes is encrypted. If it is encrypted, a password * must be supplied to getSafeContentsAt when accessing * this SafeContents. */ public boolean safeContentsIsEncrypted(int index) { ContentInfo ci = (ContentInfo) sequence.elementAt(index); return ci.getContentType().equals(ContentInfo.ENCRYPTED_DATA); } /** * Returns the SafeContents at the given index in the AuthenticatedSafes, * decrypting it if necessary. * *

The algorithm used to extract encrypted SafeContents does not * conform to version 1.0 of the spec. Instead, it conforms to the * draft 1.0 spec, because this is what Communicator and MSIE seem * to conform to. This looks like an implementation error that has * become firmly entrenched to preserve interoperability. The draft * spec dictates that the encrypted content in the EncryptedContentInfo * is the DER encoding of a SafeContents. This is simple enough. The * 1.0 final spec says that the SafeContents is wrapped in a ContentInfo, * then the ContentInfo is BER encoded, then the value octets (not the * tag or length) are encrypted. No wonder people stayed with the old way. * * @param password The password to use to decrypt the SafeContents if * it is encrypted. If the SafeContents is known to not be encrypted, * this parameter can be null. If the password is incorrect, the * decoding will fail somehow, probably with an InvalidBERException, * BadPaddingException, or IllegalBlockSizeException. * @param index The index of the SafeContents to extract. * @return A SafeContents object, which is merely a * SEQUENCE of SafeBags. * @exception IllegalArgumentException If no password was provided, * but the SafeContents is encrypted. */ public SEQUENCE getSafeContentsAt(Password password, int index) throws IllegalStateException, CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { ContentInfo ci = (ContentInfo) sequence.elementAt(index); if( ci.getContentType().equals(ContentInfo.ENCRYPTED_DATA) ) { // SafeContents is encrypted if( password == null ) { // can't decrypt if we don't have a password throw new IllegalStateException("No password to decode "+ "encrypted SafeContents"); } EncryptedContentInfo encCI = (EncryptedContentInfo) ((EncryptedData)ci.getInterpretedContent()). getEncryptedContentInfo(); // this should be a BER-encoded SafeContents byte[] decrypted = encCI.decrypt(password, new PasswordConverter()); //print_byte_array(decrypted); try { SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( SafeBag.getTemplate() ); return (SEQUENCE) ASN1Util.decode(seqt, decrypted); } catch(InvalidBERException e) { if( ACCEPT_SECURITY_DYNAMICS ) { // try the security dynamics approach ContentInfo.Template cit = ContentInfo.getTemplate(); ci = (ContentInfo) ASN1Util.decode(cit, decrypted); if( ! ci.getContentType().equals(ContentInfo.DATA) ) { throw new InvalidBERException(""); } OCTET_STRING os = (OCTET_STRING) ci.getInterpretedContent(); SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( SafeBag.getTemplate() ); return (SEQUENCE) ASN1Util.decode(seqt, os.toByteArray()); } else { throw e; } } } else if( ci.getContentType().equals(ContentInfo.DATA) ) { // This SafeContents is not encrypted SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( SafeBag.getTemplate() ); return (SEQUENCE) ASN1Util.decode(seqt, ((OCTET_STRING)ci.getInterpretedContent()). toByteArray() ); } else { throw new InvalidBERException("AuthenticatedSafes element is"+ " neither a Data or an EncryptedData"); } } static void print_byte_array(byte[] bytes) { int online=0; for(int i=0; i < bytes.length; i++, online++) { if( online > 25 ) { System.out.println(""); online=0; } System.out.print(Integer.toHexString(bytes[i]&0xff) + " "); } System.out.println(""); } /** * Returns the decrypted content from the encrypted content info. private static byte[] decryptEncryptedContentInfo(EncryptedContentInfo eci, Password pass) throws IllegalStateException,CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { OCTET_STRING encryptedContent = eci.getEncryptedContent(); if( encryptedContent == null ) { return null; } // get the key gen parameters AlgorithmIdentifier algid = eci.getContentEncryptionAlgorithm(); KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID( algid.getOID() ); ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } byte[] encodedParams = ASN1Util.encode(params); PBEParameter pbeParams = (PBEParameter) ASN1Util.decode( PBEParameter.getTemplate(), encodedParams ); PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); kg.setCharToByteConverter( new PasswordConverter() ); kg.initialize( kgp ); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = keyGenAlgToEncryptionAlg(kgAlg); AlgorithmParameterSpec algParams; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); } else { algParams = null; } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams ); return cipher.doFinal( encryptedContent.toByteArray() ); } */ /** * Appends an unencrypted SafeContents to the end of the AuthenticatedSafes. */ public void addSafeContents(SEQUENCE safeContents) { checkSafeContents(safeContents); ContentInfo ci = new ContentInfo( ASN1Util.encode(safeContents) ); sequence.addElement(ci); } /** * Verifies that each element is a SafeBag. Throws an * IllegalArgumentException otherwise. */ private static void checkSafeContents(SEQUENCE safeContents) { int size = safeContents.size(); for( int i = 0; i < size; i++) { if( ! (safeContents.elementAt(i) instanceof SafeBag) ) { throw new IllegalArgumentException( "Element "+i+" of SafeContents is not a SafeBag"); } } } /** * Encrypts a SafeContents and adds it to the AuthenticatedSafes. * * @param keyGenAlg The algorithm used to generate a key from the password. * Must be a PBE algorithm. DEFAULT_KEY_GEN_ALG is * usually fine here. It only provides 40-bit security, but if the * private key material is packaged in its own * EncryptedPrivateKeyInfo, the security of the SafeContents * is not as important. * @param password The password to use to generate the encryption key * and IV. * @param salt The salt to use to generate the key and IV. If null is * passed in, the salt will be generated randomly, which is usually * the right thing to do. * @param iterationCount The number of hash iterations to perform when * generating the key and IV. Use DEFAULT_ITERATIONS unless * you want to be clever. * @param safeContents A SafeContents, which is a SEQUENCE of SafeBags. * Each element of the sequence must in fact be an instance of * SafeBag. */ public void addEncryptedSafeContents(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, SEQUENCE safeContents) throws CryptoManager.NotInitializedException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException { try { // generate salt if necessary if( salt == null ) { // generate random salt JSSSecureRandom rand = CryptoManager.getInstance(). createPseudoRandomNumberGenerator(); salt = new byte[SALT_LENGTH]; rand.nextBytes(salt); } EncryptedContentInfo encCI = EncryptedContentInfo.createPBE(keyGenAlg, password, salt, iterationCount, new PasswordConverter(), ASN1Util.encode(safeContents)); EncryptedData encData = new EncryptedData(encCI); ContentInfo ci = new ContentInfo(encData); sequence.addElement( ci ); } catch( CharConversionException e ) { Assert.notReached("CharConversionException while converting password"); } } /* private static EncryptedContentInfo createEncryptedContentInfo(Password password, byte[] salt, int iterationCount, KeyGenAlgorithm keyGenAlg, SEQUENCE safeContents) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, BadPaddingException, IllegalBlockSizeException { try { // check key gen algorithm if( ! keyGenAlg.isPBEAlg() ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } CryptoManager cman = CryptoManager.getInstance(); // generate salt if necessary if( salt == null ) { // generate random salt JSSSecureRandom rand = cman.createPseudoRandomNumberGenerator(); salt = new byte[SALT_LENGTH]; rand.nextBytes(salt); } // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); kg.setCharToByteConverter( new PasswordConverter() ); kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = keyGenAlgToEncryptionAlg(keyGenAlg); AlgorithmParameterSpec params=null; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( ASN1Util.encode(safeContents), encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedContentInfo EncryptedContentInfo encCI = new EncryptedContentInfo( ContentInfo.DATA, encAlgID, new OCTET_STRING(encrypted) ); return encCI; } catch( CharConversionException e ) { Assert.notReached("Unable to convert password characters"); return null; } } */ /* private static EncryptionAlgorithm keyGenAlgToEncryptionAlg(KeyGenAlgorithm kgAlg) throws NoSuchAlgorithmException { if( kgAlg==KeyGenAlgorithm.PBE_MD2_DES_CBC || kgAlg==KeyGenAlgorithm.PBE_MD5_DES_CBC || kgAlg==KeyGenAlgorithm.PBE_SHA1_DES_CBC) { return EncryptionAlgorithm.DES_CBC; } else if( kgAlg==KeyGenAlgorithm.PBE_SHA1_RC4_128 || kgAlg==KeyGenAlgorithm.PBE_SHA1_RC4_40 ) { return EncryptionAlgorithm.RC4; } else if( kgAlg==KeyGenAlgorithm.PBE_SHA1_DES3_CBC ) { return EncryptionAlgorithm.DES3_CBC; } else if( kgAlg==KeyGenAlgorithm.PBE_SHA1_RC2_128 || kgAlg==KeyGenAlgorithm.PBE_SHA1_RC2_40 ) { return EncryptionAlgorithm.RC2_CBC; } else { throw new NoSuchAlgorithmException(kgAlg.toString()); } } */ /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template class for decoding an AuthenticatedSafes from its * BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.OF_Template seqt; public Template() { seqt = new SEQUENCE.OF_Template( ContentInfo.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new AuthenticatedSafes(seq); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs12/CertBag.java000066400000000000000000000121661326145000000214270ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs12; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.util.Assert; /** * A PKCS #12 cert bag. */ public class CertBag implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Cert Type OIDs /////////////////////////////////////////////////////////////////////// private static final OBJECT_IDENTIFIER CERT_TYPES = OBJECT_IDENTIFIER.PKCS9.subBranch(22); public static final OBJECT_IDENTIFIER X509_CERT_TYPE = CERT_TYPES.subBranch(1); public static final OBJECT_IDENTIFIER SDSI_CERT_TYPE = CERT_TYPES.subBranch(2); /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER certType; private ANY cert; private SEQUENCE sequence; /** * Returns the certType field of the CertBag. Currently defined types are: *

    *
  • X509Certificate (X509_CERT_TYPE) *
  • SDSICertificate (SDSI_CERT_TYPE) *
*/ public OBJECT_IDENTIFIER getCertType() { return certType; } /** * Returns the cert field of the CertBag. */ public ANY getCert() { return cert; } /** * Returns the cert field of the CertBag based on its type. *
    *
  • If the type is X509_CERT_TYPE, returns * and OCTET_STRING which is the DER-encoding of an X.509 certificate. *
  • If the type is SDSI_CERT_TYPE, returns * an IA5String. *
  • For all other types, returns an ANY. *
* * @exception InvalidBERException If the cert is not encoded correctly. */ public ASN1Value getInterpretedCert() throws InvalidBERException { if( certType.equals(X509_CERT_TYPE) ) { return cert.decodeWith(OCTET_STRING.getTemplate()); } else if( certType.equals(SDSI_CERT_TYPE) ) { return cert.decodeWith(IA5String.getTemplate()); } else { return cert; } } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private CertBag() { } /** * Creates a CertBag from a type and a cert. */ public CertBag(OBJECT_IDENTIFIER certType, ASN1Value cert) { if( certType==null || cert==null ) { throw new IllegalArgumentException("certType or cert is null"); } this.certType = certType; if( cert instanceof ANY ) { this.cert = (ANY) cert; } else { try { byte[] encoded = ASN1Util.encode(cert); this.cert = (ANY) ASN1Util.decode( ANY.getTemplate(), encoded); } catch(InvalidBERException e) { Assert.notReached("converting ASN1Value to ANY failed"); } } sequence = new SEQUENCE(); sequence.addElement(this.certType); sequence.addElement(new EXPLICIT(new Tag(0), this.cert) ); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template class for decoding CertBags from their BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( new EXPLICIT.Template( new Tag(0), ANY.getTemplate() ) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new CertBag( (OBJECT_IDENTIFIER) seq.elementAt(0), ((EXPLICIT)seq.elementAt(1)).getContent() ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs12/MacData.java000066400000000000000000000151521326145000000214100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs12; import java.io.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.pkcs7.*; import org.mozilla.jss.util.*; import java.security.*; import org.mozilla.jss.pkix.primitive.AlgorithmIdentifier; public class MacData implements ASN1Value { private DigestInfo mac; private OCTET_STRING macSalt; private INTEGER macIterationCount; private static final int DEFAULT_ITERATIONS = 1; // 20 is the length of SHA-1 hash output private static final int SALT_LENGTH = 20; public DigestInfo getMac() { return mac; } public OCTET_STRING getMacSalt() { return macSalt; } public INTEGER getMacIterationCount() { return macIterationCount; } public MacData() { } /** * Creates a MacData from the given parameters. * * @param macIterationCount 1 is the default and should be used for * maximum compatibility. null can also be used, in which case * the macIterationCount will be omitted from the structure * (and the default value of 1 will be implied). */ public MacData(DigestInfo mac, OCTET_STRING macSalt, INTEGER macIterationCount) { if( mac==null || macSalt==null || macIterationCount==null ) { throw new IllegalArgumentException("null parameter"); } this.mac = mac; this.macSalt = macSalt; this.macIterationCount = macIterationCount; } /** * Creates a MacData by computing a HMAC on the given bytes. An HMAC * is a message authentication code, which is a keyed digest. It proves * not only that data has not been tampered with, but also that the * entity that created the HMAC possessed the symmetric key. * * @param password The password used to generate a key using a * PBE mechanism. * @param macSalt The salt used as input to the PBE key generation * mechanism. If null is passed in, new random salt will be created. * @param iterations The iteration count for creating the PBE key. * @param toBeMACed The data on which the HMAC will be computed. * @exception CryptoManager.NotInitializedException If the crypto subsystem * has not been initialized yet. * @exception TokenException If an error occurs on a crypto token. */ public MacData( Password password, byte[] macSalt, int iterations, byte[] toBeMACed ) throws CryptoManager.NotInitializedException, DigestException, TokenException, CharConversionException { try { CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); if(macSalt == null) { JSSSecureRandom rand = cm.createPseudoRandomNumberGenerator(); macSalt = new byte[ SALT_LENGTH ]; rand.nextBytes(macSalt); } // generate key from password and salt KeyGenerator kg = token.getKeyGenerator( KeyGenAlgorithm.PBA_SHA1_HMAC); PBEKeyGenParams params = new PBEKeyGenParams(password, macSalt, iterations); kg.setCharToByteConverter(new PasswordConverter()); kg.initialize(params); SymmetricKey key = kg.generate(); // perform the digesting JSSMessageDigest digest = token.getDigestContext(HMACAlgorithm.SHA1); digest.initHMAC(key); byte[] digestBytes = digest.digest(toBeMACed); // put everything into a DigestInfo AlgorithmIdentifier algID = new AlgorithmIdentifier( DigestAlgorithm.SHA1.toOID() ); this.mac = new DigestInfo( algID, new OCTET_STRING(digestBytes)); this.macSalt = new OCTET_STRING(macSalt); this.macIterationCount = new INTEGER(iterations); } catch( NoSuchAlgorithmException e ) { Assert.notReached("SHA-1 HMAC algorithm not found on internal "+ " token ("+ e.toString() + ")"); } catch( InvalidAlgorithmParameterException e ) { Assert.notReached("Invalid PBE algorithm parameters"); } catch( java.lang.IllegalStateException e ) { Assert.notReached("IllegalStateException"); } catch( InvalidKeyException e ) { Assert.notReached("Invalid key exception"); } } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { return TAG; } private static final Tag TAG = SEQUENCE.TAG; public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(mac); seq.addElement(macSalt); if( ! macIterationCount.equals(new INTEGER(DEFAULT_ITERATIONS)) ) { // 1 is the default, only include this element if it is not // the default seq.addElement(macIterationCount); } seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static final Template getTemplate() { return templateInstance; } /** * A Template for decoding a MacData from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( DigestInfo.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); seqt.addElement( INTEGER.getTemplate(), new INTEGER(DEFAULT_ITERATIONS) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new MacData( (DigestInfo) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1), (INTEGER) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs12/Makefile000066400000000000000000000035521326145000000207140ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/pkcs12/PFX.java000066400000000000000000000422221326145000000205510ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs12; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkcs7.*; import org.mozilla.jss.pkix.cert.*; import java.io.*; import org.mozilla.jss.util.Password; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.primitive.Attribute; import org.mozilla.jss.crypto.*; import java.security.*; import org.mozilla.jss.pkix.cert.Certificate; /** * The top level ASN.1 structure for a PKCS #12 blob. * *

The general procedure for creating a PFX blob is as follows:

    * *
  • Create instances of SafeBag containing things such as * private keys, certificates, or arbitrary secrets. *
  • Store the SafeBags in one or more SEQUENCEs. Each SEQUENCE is * called a SafeContents. *
  • Create an AuthenticatedSafes. Store each SafeContents into the * AuthenticatedSafes with addEncryptedSafeContents or * addSafeContents. *

    Standard procedure for browsers is for the AuthenticatedSafes to contain * two instances of SafeContents, one encrypted and the other not. * Anything you want encrypted can go in the encrypted SafeContents, * and anything you want in plaintext can go in the regular SafeContents. * Keep in mind that private key SafeBags usually consist of an * EncryptedPrivateKeyInfo, which has its own (strong) encryption, * in which case it is not essential that the SafeContents containing * the private key also be encrypted. *

  • Create a PFX containing the AuthenticatedSafes instance, using the * PFX(AuthenticatedSafes) constructor. *
  • Add a MAC to the PFX so it can be verified, using * PFX.computeMacData. *
* * To decode a PFX,
    * *
  • Use a PFX.Template to decode the ASN.1 into a * PFX object. *
  • Check the output of PFX.verifyAuthSafes to verify * the MAC on the PFX. *
  • Use PFX.getAuthSafes to extract the AuthenticatedSafes * instance. *
  • Use AuthenticatedSafes.getSafeContentsAt to grab the * SafeContents objects in the AuthenticatedSafes. *
  • Each SafeContents is a SEQUENCE of SafeBags, each of which may * contain a private key, cert, or arbitrary secret. *
*/ public class PFX implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER version; private AuthenticatedSafes authSafes; private MacData macData; // may be null private byte[] encodedAuthSafes; // may be null // currently we are on version 3 of the standard private static final INTEGER VERSION = new INTEGER(3); /** * The default number of iterations to use when generating the MAC. * Currently, it is 1. */ public static final int DEFAULT_ITERATIONS = 1; public INTEGER getVersion() { return version; } public AuthenticatedSafes getAuthSafes() { return authSafes; } /** * Returns the MacData of this PFX, which is used to verify the contents. * This field is optional. If it is not present, null is returned. */ public MacData getMacData() { return macData; } private void setEncodedAuthSafes(byte[] encodedAuthSafes) { this.encodedAuthSafes = encodedAuthSafes; } /** * Verifies the HMAC on the authenticated safes, using the password * provided. * * @param password The password to use to compute the HMAC. * @param reason If supplied, the reason for the verification failure * will be appended to this StringBuffer. * @return true if the MAC verifies correctly, false otherwise. If * this PFX does not contain a MacData, returns false. */ public boolean verifyAuthSafes(Password password, StringBuffer reason) throws CryptoManager.NotInitializedException { try { if(reason == null) { // this is just so we don't get a null pointer exception reason = new StringBuffer(); } if( macData == null ) { reason.append("No MAC present in PFX"); return false; } if( encodedAuthSafes == null ) { // We weren't decoded from a template, we were constructed, // so just verify the encoding of the AuthSafes provided to // the constructor. encodedAuthSafes = ASN1Util.encode(authSafes); } // create a new MacData based on the encoded Auth Safes DigestInfo macDataMac = macData.getMac(); MacData testMac = new MacData( password, macData.getMacSalt().toByteArray(), macData.getMacIterationCount().intValue(), encodedAuthSafes ); if( testMac.getMac().equals(macDataMac) ) { return true; } else { reason.append("Digests do not match"); return false; } } catch( java.security.DigestException e ) { e.printStackTrace(); reason.append("A DigestException occurred"); return false; } catch( TokenException e ) { reason.append("A TokenException occurred"); return false; } catch( CharConversionException e ) { reason.append("An exception occurred converting the password from"+ " chars to bytes"); return false; } } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private PFX() { } /** * Creates a PFX with the given parameters. */ public PFX( INTEGER version, AuthenticatedSafes authSafes, MacData macData) { if( version==null || authSafes==null ) { throw new IllegalArgumentException("null parameter"); } this.version = version; this.authSafes = authSafes; this.macData = macData; } /** * Creates a PFX with the default version. */ public PFX( AuthenticatedSafes authSafes, MacData macData ) { this( VERSION, authSafes, macData ); } /** * Creates a PFX with the default version and no MacData. The MacData * can be added later with computeMacData. * @see #computeMacData */ public PFX( AuthenticatedSafes authSafes ) { this( VERSION, authSafes, null ); } /** * Computes the macData field and adds it to the PFX. The macData field * is a Message Authentication Code of the AuthenticatedSafes, and * is used to prove the authenticity of the PFX. * * @param password The password to be used to create the password-based MAC. * @param salt The salt to be used. If null is passed in, a new salt * will be created from a random source. * @param iterationCount The iteration count for the key generation. * Use DEFAULT_ITERATIONS unless there's a need to be clever. */ public void computeMacData(Password password, byte[] salt, int iterationCount) throws CryptoManager.NotInitializedException, DigestException, TokenException, CharConversionException { macData = new MacData( password, salt, iterationCount, ASN1Util.encode(authSafes) ); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { return TAG; } private static final Tag TAG = SEQUENCE.TAG; public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(version); seq.addElement( new ContentInfo( ASN1Util.encode(authSafes) ) ); if(macData != null) { seq.addElement(macData); } seq.encode(implicitTag, ostream); } /** * A Template for decoding a BER-encoded PFX. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = SEQUENCE.getTemplate(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( ContentInfo.getTemplate() ); seqt.addOptionalElement( MacData.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); ContentInfo authSafesCI = (ContentInfo) seq.elementAt(1); if( ! authSafesCI.getContentType().equals(ContentInfo.DATA) ) { throw new InvalidBERException( "ContentInfo containing AuthenticatedSafes does not have"+ " content-type DATA"); } OCTET_STRING authSafesOS = (OCTET_STRING) authSafesCI.getInterpretedContent(); AuthenticatedSafes authSafes = (AuthenticatedSafes) ASN1Util.decode( AuthenticatedSafes.getTemplate(), authSafesOS.toByteArray() ); PFX pfx = new PFX( (INTEGER) seq.elementAt(0), authSafes, (MacData) seq.elementAt(2) ); // record the encoding of the auth safes so we can verify the // MAC later. We can't just re-encode the AuthSafes because // it is BER, and the re-encoding might be different from // the original encoding. pfx.setEncodedAuthSafes(authSafesOS.toByteArray()); return pfx; } } public static void main(String []args) { try { if( args.length != 2 ) { System.out.println("Usage: PFX "); System.exit(-1); } FileInputStream fis = new FileInputStream(args[1]); int certfile = 0; CryptoManager.initialize( args[0] ); // Decode the P12 file PFX.Template pfxt = new PFX.Template(); PFX pfx = (PFX) pfxt.decode(new BufferedInputStream(fis, 2048)); System.out.println("Decoded PFX"); // now peruse it for interesting info System.out.println("Version: "+pfx.getVersion()); AuthenticatedSafes authSafes = pfx.getAuthSafes(); SEQUENCE asSeq = authSafes.getSequence(); System.out.println("AuthSafes has "+ asSeq.size()+" SafeContents"); System.out.println("Enter password: "); Password pass = Password.readPasswordFromConsole(); // get new password System.out.println("Enter new password:"); Password newPass = Password.readPasswordFromConsole(); // verify the PFX StringBuffer sb = new StringBuffer(); if( pfx.verifyAuthSafes(pass, sb) ) { System.out.println("AuthSafes verifies correctly"); } else { System.out.println("AuthSafes failed to verify because: "+ sb); } // get new AuthSafes ready AuthenticatedSafes newAuthSafes = new AuthenticatedSafes(); for(int i=0; i < asSeq.size(); i++) { SEQUENCE safeContents = authSafes.getSafeContentsAt(pass,i); System.out.println("\n\nSafeContents #"+i+" has "+ safeContents.size()+" bags"); for(int j=0; j < safeContents.size(); j++) { SafeBag safeBag = (SafeBag) safeContents.elementAt(j); System.out.println("\nBag "+j+" has type "+ safeBag.getBagType() ); SET attribs = safeBag.getBagAttributes(); if( attribs == null ) { System.out.println("Bag has no attributes"); } else { for(int b=0; b < attribs.size(); b++) { Attribute a = (Attribute) attribs.elementAt(b); if( a.getType().equals(SafeBag.FRIENDLY_NAME)) { BMPString bs = (BMPString) ((ANY)a.getValues(). elementAt(0)).decodeWith( BMPString.getTemplate()); System.out.println("Friendly Name: "+bs); } else if(a.getType().equals(SafeBag.LOCAL_KEY_ID)){ OCTET_STRING os =(OCTET_STRING) ((ANY)a.getValues(). elementAt(0)).decodeWith( OCTET_STRING.getTemplate()); System.out.println("LocalKeyID:"); AuthenticatedSafes. print_byte_array(os.toByteArray()); } else { System.out.println("Unknown attribute type"); } } } ASN1Value val = safeBag.getInterpretedBagContent(); if( val instanceof PrivateKeyInfo ) { System.out.println("content is PrivateKeyInfo"); } else if( val instanceof EncryptedPrivateKeyInfo ) { EncryptedPrivateKeyInfo epki = ((EncryptedPrivateKeyInfo)val); System.out.println( "content is EncryptedPrivateKeyInfo, algoid:" + epki.getEncryptionAlgorithm().getOID()); PrivateKeyInfo pki = epki.decrypt(pass, new PasswordConverter() ); byte[] salt = new byte[20]; JSSSecureRandom rand = CryptoManager.getInstance(). getSecureRNG(); rand.nextBytes(salt); epki = EncryptedPrivateKeyInfo.createPBE( PBEAlgorithm.PBE_SHA1_DES3_CBC, newPass, salt, 1, new PasswordConverter(), pki); // replace the old safe bag with the new safeContents.insertElementAt( new SafeBag( safeBag.getBagType(), epki, safeBag.getBagAttributes()), j); safeContents.removeElementAt(j+1); } else if( val instanceof CertBag ) { System.out.println(" content is CertBag"); CertBag cb = (CertBag) val; if( cb.getCertType().equals(CertBag.X509_CERT_TYPE)) { OCTET_STRING os = (OCTET_STRING)cb.getInterpretedCert(); FileOutputStream fos = new FileOutputStream( "cert"+(certfile++)+".der"); os.encode(fos); fos.close(); Certificate cert = (Certificate) ASN1Util.decode(Certificate.getTemplate(), os.toByteArray()); cert.getInfo().print(System.out); } else { System.out.println("Unrecognized cert type"); } } else { System.out.println("content is ANY"); } } // Add the new safe contents to the authsafes if( authSafes.safeContentsIsEncrypted(i) ) { newAuthSafes.addEncryptedSafeContents( authSafes.DEFAULT_KEY_GEN_ALG, newPass, null, authSafes.DEFAULT_ITERATIONS, safeContents); } else { newAuthSafes.addSafeContents( safeContents ); } } // Create new PFX from new authsafes PFX newPfx = new PFX(newAuthSafes); newPfx.computeMacData(newPass, null, DEFAULT_ITERATIONS); FileOutputStream fos = new FileOutputStream("newjss.p12"); newPfx.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs12/PasswordConverter.java000066400000000000000000000020501326145000000236010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs12; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.util.Assert; /** * Converts password chars to bytes. The output format is big-endian Unicode, * with two zero bytes of null-termination at the end. */ public final class PasswordConverter implements KeyGenerator.CharToByteConverter { public byte[] convert(char[] chars) { byte[] bytes = new byte[ (chars.length+1) * 2 ]; int c; // char index int b; // byte index for(c=0, b=0; c < chars.length; c++) { bytes[b++] = (byte) ((chars[c] & 0xff00) >>> 8); bytes[b++] = (byte) (chars[c] & 0xff); } bytes[b++] = 0; bytes[b++] = 0; Assert._assert(b == bytes.length); return bytes; } } jss-4.4.3/jss/org/mozilla/jss/pkcs12/SafeBag.java000066400000000000000000000330501326145000000214030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs12; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.*; import java.security.*; import java.security.MessageDigest; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; /** * A PKCS #12 SafeBag structure. */ public final class SafeBag implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER bagType; private ANY bagContent; private SET bagAttributes; // may be null public OBJECT_IDENTIFIER getBagType() { return bagType; } /** * Returns the contents of this bag as an ANY. */ public ANY getBagContent() { return bagContent; } /** * Returns the bagContent interpreted by type. * @return If type is KeyBag, a PrivateKeyInfo. *
If type is PKCS-8ShroudedKeyBag, an EncryptedPrivateKeyInfo. *
If type is CertBag, a CertBag. *
For any other type, returns an ANY. */ public ASN1Value getInterpretedBagContent() throws InvalidBERException { if( bagType.equals(KEY_BAG) ) { return bagContent.decodeWith(PrivateKeyInfo.getTemplate()); } else if( bagType.equals(PKCS8_SHROUDED_KEY_BAG)) { return bagContent.decodeWith(EncryptedPrivateKeyInfo.getTemplate()); } else if( bagType.equals(CERT_BAG) ) { return bagContent.decodeWith(CertBag.getTemplate()); } else { return bagContent; } } /** * Returns the attributes of this bag. May return null if this bag * has no attributes. Each element of the set is a * org.mozilla.jss.pkix.primitive.Attribute. */ public SET getBagAttributes() { return bagAttributes; } /////////////////////////////////////////////////////////////////////// // OIDs /////////////////////////////////////////////////////////////////////// /** * The OID branch for PKCS #12, version 1.0. */ public static final OBJECT_IDENTIFIER PKCS12_VERSION_1= OBJECT_IDENTIFIER.PKCS12.subBranch(10); /** * The OID branch for the PKCS #12 bag types. */ public static final OBJECT_IDENTIFIER PKCS12_BAG_IDS = PKCS12_VERSION_1.subBranch(1); /** * A bag containing a private key. The bag content is a KeyBag, * which is equivalent to a PKCS #8 PrivateKeyInfo */ public static final OBJECT_IDENTIFIER KEY_BAG = PKCS12_BAG_IDS.subBranch(1); /** * A bag containing a private key encrypted a la PKCS #8. The bag * content is a PKCS #8 EncryptedPrivateKeyInfo. */ public static final OBJECT_IDENTIFIER PKCS8_SHROUDED_KEY_BAG = PKCS12_BAG_IDS.subBranch(2); /** * A bag containing a certificate. The bag content is CertBag. */ public static final OBJECT_IDENTIFIER CERT_BAG = PKCS12_BAG_IDS.subBranch(3); /** * A bag containing a certificate revocation list. * The bag content is CRLBag. */ public static final OBJECT_IDENTIFIER CRL_BAG = PKCS12_BAG_IDS.subBranch(4); /** * A bag containing an arbitrary secret. The bag content is * SecretBag. */ public static final OBJECT_IDENTIFIER SECRET_BAG = PKCS12_BAG_IDS.subBranch(5); /** * A bag containing a nested SafeContent . The bag content is * SafeContents, which is merely a SEQUENCE of SafeBag. */ public static final OBJECT_IDENTIFIER SAFE_CONTENTS_BAG = PKCS12_BAG_IDS.subBranch(6); /** * A FriendlyName attribute. The value is a BMPString. */ public static final OBJECT_IDENTIFIER FRIENDLY_NAME = OBJECT_IDENTIFIER.PKCS9.subBranch(20); /** * A LocalKeyID attribute. The value is an octet string. */ public static final OBJECT_IDENTIFIER LOCAL_KEY_ID = OBJECT_IDENTIFIER.PKCS9.subBranch(21); /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private SafeBag() { } /** * Creates a new SafeBag from its components. * * @param bagType The type of this bag. For compatibility, it should * be one of the constants defined in this class. * @param bagContent The contents of the bag. The type of this parameter * is defined by the bagType parameter. * @param bagAttributes A SET of Attributes for this SafeBag. Since * attributes are optional, this parameter may be null. */ public SafeBag(OBJECT_IDENTIFIER bagType, ASN1Value bagContent, SET bagAttributes) { if( bagType==null || bagContent==null ) { throw new IllegalArgumentException("bagType or bagContent is null"); } this.bagType = bagType; try { if( bagContent instanceof ANY ) { this.bagContent = (ANY) bagContent; } else { byte[] encoded = ASN1Util.encode(bagContent); this.bagContent = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded); } } catch( InvalidBERException e ) { Assert.notReached("failed to convert ASN1Value to ANY"); } this.bagAttributes = bagAttributes; } /** * Creates a SafeBag that contains an X.509 Certificate. * The SafeBag will have a localKeyID attribute equal * to the SHA-1 hash of the certificate, and a friendlyName * attribute equal to the supplied string. This is the way Communicator * makes a CertBag. The same localKeyID attribute should be stored * in the matching private key bag. * * @param cert A DER-encoded X.509 certificate. * @param friendlyName Will be stored in the friendlyName * attribute of the SafeBag. Should be the nickname of the cert. */ public static SafeBag createCertBag(byte[] cert, String friendlyName) throws DigestException, NoSuchAlgorithmException, InvalidBERException { return createCertBag(cert, friendlyName, getLocalKeyIDFromCert(cert)); } /** * Creates a SafeBag that contains an X.509 Certificate. * The SafeBag will have the given localKeyID attribute, * and a friendlyName * attribute equal to the supplied string. This is the way Communicator * makes a CertBag. The same localKeyID attribute should be stored * in the matching private key bag. * * @param cert A DER-encoded X.509 certificate. * @param friendlyName Will be stored in the friendlyName * attribute of the SafeBag. Should be the nickname of the cert. * @param localKeyID The bytes to used for the localKeyID. These should * be obtained from the getLocalKeyIDFromCert method. * @exception InvalidBERException If the cert is not a valid DER encoding. * @see #getLocalKeyIDFromCert */ public static SafeBag createCertBag(byte[] cert, String friendlyName, byte[] localKeyID) throws InvalidBERException { try { // create CertBag CertBag cb = new CertBag(CertBag.X509_CERT_TYPE, new ANY(cert) ); // setup attributes SET attributes = new SET(); // friendly name should be cert nickname attributes.addElement(new Attribute( FRIENDLY_NAME, new BMPString(friendlyName) )); attributes.addElement( new Attribute( LOCAL_KEY_ID, new OCTET_STRING(localKeyID) )); return new SafeBag(CERT_BAG, cb, attributes); } catch( CharConversionException e ) { throw new AssertionException("CharConversionException converting"+ " Unicode to BMPString"); } } /** * Computes the LocalKeyID attribute that should be stored with a key * and certificate. * * @param derCert A DER-encoded X.509 certificate. * @return The SHA-1 hash of the cert, which should be used as the * localKeyID attribute for the cert's SafeBag. */ public static final byte[] getLocalKeyIDFromCert(byte[] derCert) throws DigestException, NoSuchAlgorithmException { MessageDigest digester = MessageDigest.getInstance("SHA-1"); return digester.digest(derCert); } /** * Creates a SafeBag containing a PKCS-8ShroudedKeyBag, which is * an EncryptedPrivateKeyInfo. The key will be encrypted using * a triple-DES PBE algorithm, using the supplied password. * * @param privk The PrivateKeyInfo containing the private key. * @param friendlyName The nickname for the key; should be the same * as the nickname of the associated cert. * @param localKeyID The localKeyID for the key; should be the same as * the localKeyID of the associated cert. * @param password The password used to encrypt the private key. */ public static SafeBag createEncryptedPrivateKeyBag(PrivateKeyInfo privk, String friendlyName, byte[] localKeyID, Password password) throws CryptoManager.NotInitializedException, TokenException { try { PBEAlgorithm pbeAlg = PBEAlgorithm.PBE_SHA1_DES3_CBC; final int DEFAULT_ITERATIONS = 1; byte[] salt = new byte[pbeAlg.getSaltLength()]; JSSSecureRandom rand = CryptoManager.getInstance().getSecureRNG(); rand.nextBytes(salt); EncryptedPrivateKeyInfo epki= EncryptedPrivateKeyInfo.createPBE( PBEAlgorithm.PBE_SHA1_DES3_CBC, password, salt, DEFAULT_ITERATIONS, new PasswordConverter(), privk); SET attributes = new SET(); attributes.addElement(new Attribute( FRIENDLY_NAME, new BMPString(friendlyName) )); attributes.addElement( new Attribute( LOCAL_KEY_ID, new OCTET_STRING(localKeyID) )); return new SafeBag(PKCS8_SHROUDED_KEY_BAG , epki, attributes); } catch(java.security.NoSuchAlgorithmException e) { throw new AssertionException( "Unable to find PBE algorithm: "+e); } catch(java.security.InvalidKeyException e) { throw new AssertionException( "InvalidKeyException while creating EncryptedContentInfo: "+e); } catch(java.security.InvalidAlgorithmParameterException e) { throw new AssertionException( "InvalidAlgorithmParameterException while creating"+ " EncryptedContentInfo: "+e); } catch(java.io.CharConversionException e) { throw new AssertionException( "CharConversionException while creating EncryptedContentInfo: "+ e); } } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement( bagType ); seq.addElement( new EXPLICIT(new Tag(0), bagContent) ); if( bagAttributes!=null ) { seq.addElement( bagAttributes ); } seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding SafeBags. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( new EXPLICIT.Template( new Tag(0), ANY.getTemplate() ) ); seqt.addOptionalElement( new SET.OF_Template( Attribute.getTemplate() ) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new SafeBag( (OBJECT_IDENTIFIER) seq.elementAt(0), ((EXPLICIT)seq.elementAt(1)).getContent(), (SET) seq.elementAt(2) ); } catch( InvalidBERException e ) { throw new InvalidBERException(e, "SafeBag"); } } } } jss-4.4.3/jss/org/mozilla/jss/pkcs12/SecretBag.java000066400000000000000000000073151326145000000217570ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs12; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import java.io.*; public class SecretBag implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER secretType; private ANY secret; private SEQUENCE sequence; /** * Returns the type of secret stored in the SecretBag. */ public OBJECT_IDENTIFIER getSecretType() { return secretType; } /** * Returns the secret stored in the SecretBag. */ public ANY getSecret() { return secret; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private SecretBag() { } /** * Creates a SecretBag with the given secret type and secret. Neither * may be null. */ public SecretBag(OBJECT_IDENTIFIER secretType, ASN1Value secret) { if( secretType==null || secret==null ) { throw new IllegalArgumentException("SecretBag parameter is null"); } this.secretType = secretType; if( secret instanceof ANY ) { this.secret = (ANY) secret; } else { byte[] encoded = ASN1Util.encode(secret); try { this.secret = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded); } catch(InvalidBERException e) { Assert.notReached("Failed to convert ASN1Value to ANY"); } } sequence = new SEQUENCE(); sequence.addElement(secretType); sequence.addElement( new EXPLICIT(new Tag(0), this.secret) ); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template class for decoding SecretBags from BER. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( new EXPLICIT.Template( new Tag(0), ANY.getTemplate()) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new SecretBag( (OBJECT_IDENTIFIER)seq.elementAt(0), ((EXPLICIT)seq.elementAt(1)).getContent() ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs12/config.mk000066400000000000000000000003071326145000000210450ustar00rootroot00000000000000# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. jss-4.4.3/jss/org/mozilla/jss/pkcs12/manifest.mn000066400000000000000000000020461326145000000214130ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 PACKAGE = org/mozilla/jss/pkcs12 CLASSES = \ AuthenticatedSafes \ CertBag \ MacData \ PasswordConverter \ PFX \ SafeBag \ SecretBag \ $(NULL) JSRCS = \ AuthenticatedSafes.java \ CertBag.java \ MacData.java \ PasswordConverter.java \ PFX.java \ SafeBag.java \ SecretBag.java \ $(NULL) jss-4.4.3/jss/org/mozilla/jss/pkcs12/package.html000066400000000000000000000005321326145000000215300ustar00rootroot00000000000000 Creating and interpreting PKCS #12 blobs. The PFX class is the top-level structure of a PKCS #12 blob. jss-4.4.3/jss/org/mozilla/jss/pkcs7/000077500000000000000000000000001326145000000171735ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkcs7/Attribute.java000066400000000000000000000055121326145000000220040ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; /** * An Attribute, which has the following ASN.1 * definition (roughly): *
 *      Attribute ::= SEQUENCE {
 *          type        OBJECT IDENTIFIER,
 *          value       SET }
 * 
*/ public class Attribute implements ASN1Value { private OBJECT_IDENTIFIER type; private SET values; public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private Attribute() { } public Attribute(OBJECT_IDENTIFIER type, SET values) { this.type = type; this.values = values; } public Attribute(OBJECT_IDENTIFIER type, ASN1Value value) { this.type = type; this.values = new SET(); values.addElement(value); } public OBJECT_IDENTIFIER getType() { return type; } /** * If this AVA was constructed, returns the SET of ASN1Values passed to the * constructor. If this Attribute was decoded with an Attribute.Template, * returns a SET of ANYs. */ public SET getValues() { return values; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(type); seq.addElement(values); seq.encode(implicit, ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding an Attribute. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement( new OBJECT_IDENTIFIER.Template() ); seqt.addElement( new SET.OF_Template(new ANY.Template())); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this Assert._assert(seq.size() == 2); return new Attribute( (OBJECT_IDENTIFIER) seq.elementAt(0), (SET) seq.elementAt(1)); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs7/ContentInfo.java000066400000000000000000000171441326145000000222730ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; /** * A PKCS #7 ContentInfo structure. */ public class ContentInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; // XXX is this right? public static OBJECT_IDENTIFIER DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 1 }); public static OBJECT_IDENTIFIER SIGNED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 2 }); public static OBJECT_IDENTIFIER ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 3 }); public static OBJECT_IDENTIFIER SIGNED_AND_ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 4 }); public static OBJECT_IDENTIFIER DIGESTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 5 }); public static OBJECT_IDENTIFIER ENCRYPTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 6 }); private OBJECT_IDENTIFIER contentType; private ANY content; private SEQUENCE sequence = new SEQUENCE(); private ContentInfo() {} /** * Creates a ContentInfo with the given type and content. * * @param contentType The contentType of the ContentInfo. * @param content The content of the ContentInfo. May be null * to signify that the optional content field is not present. */ public ContentInfo(OBJECT_IDENTIFIER contentType, ASN1Value content) { this.contentType = contentType; sequence.addElement(contentType); if (content != null) { if( content instanceof ANY ) { this.content = (ANY) content; } else { // convert content to ANY try { this.content = (ANY) ASN1Util.decode(ANY.getTemplate(), ASN1Util.encode(content) ); } catch(InvalidBERException e) { Assert.notReached("InvalidBERException while converting"+ "ASN1Value to ANY"); } } sequence.addElement(new EXPLICIT(new Tag(0),content) ); } } /** * Creates a ContentInfo of type data. */ public ContentInfo(byte[] data) { this( DATA, new OCTET_STRING(data) ); } /** * Creates a ContentInfo of type signedData. */ public ContentInfo(SignedData sd) { this( SIGNED_DATA, sd); } /** * Creates a ContentInfo of type envelopedData. */ public ContentInfo(EnvelopedData ed) { this( ENVELOPED_DATA, ed ); } /** * Creates a ContentInfo of type signedAndEnvelopedData. */ public ContentInfo(SignedAndEnvelopedData sed) { this( SIGNED_AND_ENVELOPED_DATA, sed ); } /** * Creates a ContentInfo of type digestedData. */ public ContentInfo(DigestedData dd) { this( DIGESTED_DATA, dd ); } /** * Creates a ContentInfo of type encryptedData. */ public ContentInfo(EncryptedData ed) { this( ENCRYPTED_DATA, ed ); } /** * Returns the contentType field, which determines what kind of content * is contained in this ContentInfo. It will usually be one of the six * predefined types, but may also be a user-defined type. */ public OBJECT_IDENTIFIER getContentType() { return contentType; } /** * Returns true if the content field is present. */ public boolean hasContent() { return (content != null); } /** * Returns the content, interpreted based on its type. If there is no * content, null is returned. *

If the contentType is * one of the six standard types, the returned object will be of that * type. For example, if the ContentInfo has contentType signedData, * a SignedData object will be returned. If the contentType is data, * an OCTET_STRING will be returned. *

If the contentType is not one of the six standard types, * the returned object will be an ANY. */ public ASN1Value getInterpretedContent() throws InvalidBERException { if(contentType.equals(DATA)) { return content.decodeWith( new OCTET_STRING.Template() ); } else if( contentType.equals(SIGNED_DATA) ) { return content.decodeWith( new SignedData.Template() ); } else if( contentType.equals(ENVELOPED_DATA) ) { return content.decodeWith( new EnvelopedData.Template()); } else if( contentType.equals(SIGNED_AND_ENVELOPED_DATA) ) { return content.decodeWith( new SignedAndEnvelopedData.Template() ); } else if( contentType.equals(DIGESTED_DATA) ) { return content.decodeWith( new DigestedData.Template() ); } else if( contentType.equals(ENCRYPTED_DATA) ) { return content.decodeWith( new EncryptedData.Template()); } else { // unknown type return content; } } /** * Returns the content encoded as an ANY. If there is no content, * null is returned. */ public ANY getContent() { return content; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag,ostream); } public Tag getTag() { return ContentInfo.TAG; } /** * Returns a singleton instance of a decoding template for ContentInfo. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a ContentInfo blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(ContentInfo.TAG)); } private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(0), new ANY.Template() )); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(ContentInfo.TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream ) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() == 2); ASN1Value content; if( seq.elementAt(1) == null ) { content = null; } else { content = ((EXPLICIT)seq.elementAt(1)).getContent(); } return new ContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), content ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkcs7/DigestInfo.java000066400000000000000000000065511326145000000221000ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; import org.mozilla.jss.util.Assert; public class DigestInfo implements ASN1Value { private AlgorithmIdentifier digestAlgorithm; private OCTET_STRING digest; private SEQUENCE sequence; private DigestInfo() { } public DigestInfo(AlgorithmIdentifier digestAlgorithm, OCTET_STRING digest){ if( digestAlgorithm==null || digest==null ) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.digestAlgorithm = digestAlgorithm; sequence.addElement(digestAlgorithm); this.digest = digest; sequence.addElement(digest); } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public OCTET_STRING getDigest() { return digest; } private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public boolean equals(Object obj) { if( obj==null || !(obj instanceof DigestInfo)) { return false; } DigestInfo di = (DigestInfo)obj; return byteArraysAreSame(di.digest.toByteArray(), digest.toByteArray()); } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { Assert._assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding the BER encoding of a DigestInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate()); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream ostream) throws InvalidBERException, IOException { return decode(TAG, ostream); } public ASN1Value decode(Tag implicitTag, InputStream ostream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, ostream); return new DigestInfo( (AlgorithmIdentifier) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs7/DigestedData.java000066400000000000000000000073241326145000000223660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; public class DigestedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private AlgorithmIdentifier digestAlgorithm; private ContentInfo contentInfo; private OCTET_STRING digest; private SEQUENCE sequence; // for DER encoding public INTEGER getVersion() { return version; } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public ContentInfo getContentInfo() { return contentInfo; } public OCTET_STRING getDigest() { return digest; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private DigestedData() { } public DigestedData(INTEGER version, AlgorithmIdentifier digestAlgorithm, ContentInfo contentInfo, OCTET_STRING digest) { if( version==null || digestAlgorithm==null || contentInfo==null || digest==null ) { throw new IllegalArgumentException("DigestedData constructor" +" parameter is null"); } this.version = version; this.digestAlgorithm = digestAlgorithm; this.contentInfo = contentInfo; this.digest = digest; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithm); sequence.addElement(contentInfo); sequence.addElement(digest); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * A Template for decoding BER-encoded DigestData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( ContentInfo.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new DigestedData( (INTEGER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (ContentInfo) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs7/EncryptedContentInfo.java000066400000000000000000000275541326145000000241570ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import org.mozilla.jss.pkix.primitive.*; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; import org.mozilla.jss.crypto.*; import java.security.*; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import org.mozilla.jss.util.Password; import org.mozilla.jss.CryptoManager; /** * The PKCS #7 type EncryptedContentInfo, which encapsulates * encrypted data. */ public class EncryptedContentInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER contentType; private AlgorithmIdentifier contentEncryptionAlgorithm; private OCTET_STRING encryptedContent; // may be null private SEQUENCE sequence = new SEQUENCE(); public OBJECT_IDENTIFIER getContentType() { return contentType; } public AlgorithmIdentifier getContentEncryptionAlgorithm() { return contentEncryptionAlgorithm; } public OCTET_STRING getEncryptedContent() { return encryptedContent; } public boolean hasEncryptedContent() { return (encryptedContent!=null); } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private EncryptedContentInfo() { } /** * Create a EnvelopedData ASN1 object. */ public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { this(contentType, contentEncryptionAlgorithm, encryptedContent, false); } public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent, boolean createHackedCRSCompatibleECI) { this.contentType = contentType; this.contentEncryptionAlgorithm = contentEncryptionAlgorithm; this.encryptedContent = encryptedContent; sequence.addElement(contentType); sequence.addElement(contentEncryptionAlgorithm); if(encryptedContent != null) { if (createHackedCRSCompatibleECI) { sequence.addElement(new EXPLICIT(new Tag(0), encryptedContent)); } else { sequence.addElement(new Tag(0), encryptedContent); } } } public static EncryptedContentInfo createCRSCompatibleEncryptedContentInfo(OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { return new EncryptedContentInfo(contentType, contentEncryptionAlgorithm, encryptedContent, true); } /////////////////////////////////////////////////////////////////////// // Crypto shortcuts /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedContentInfo, where the data is encrypted * with a password-based key. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param toBeEncrypted The bytes to be encrypted and stored in the * EncryptedContentInfo. Before they are encrypted, they will be * padded using PKCS padding. */ public static EncryptedContentInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, byte[] toBeEncrypted) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = (PBEAlgorithm) keyGenAlg; CryptoManager cman = CryptoManager.getInstance(); // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); } else if( encAlg.getParameterClass().equals( RC2ParameterSpec.class ) ) { params = new RC2ParameterSpec(key.getStrength(), kg.generatePBE_IV()); } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( toBeEncrypted, encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedContentInfo EncryptedContentInfo encCI = new EncryptedContentInfo( ContentInfo.DATA, encAlgID, new OCTET_STRING(encrypted) ); return encCI; } catch( IllegalBlockSizeException e ) { Assert.notReached("IllegalBlockSizeException in EncryptedContentInfo" +".createPBE"); } catch( BadPaddingException e ) { Assert.notReached("BadPaddingException in EncryptedContentInfo" +".createPBE"); } return null; } /** * Decrypts the content of an EncryptedContentInfo encrypted with a * PBE key. * * @param pass The password to use in generating the PBE decryption key. * @param charToByteConverter The converter for converting the password * characters into bytes. May be null to use the default. * @return The decrypted contents of the EncryptedContentInfo. The contents * are first unpadded using the PKCS padding mechanism. */ public byte[] decrypt(Password pass, KeyGenerator.CharToByteConverter charToByteConverter) throws IllegalStateException,CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { if( encryptedContent == null ) { return null; } // get the key gen parameters AlgorithmIdentifier algid = contentEncryptionAlgorithm; KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID( algid.getOID() ); if( !(kgAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("KeyGenAlgorithm is not a"+ " PBE algorithm"); } ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } PBEParameter pbeParams; if( params instanceof PBEParameter) { pbeParams = (PBEParameter) params; } else { byte[] encodedParams = ASN1Util.encode(params); pbeParams = (PBEParameter) ASN1Util.decode( PBEParameter.getTemplate(), encodedParams ); } PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize( kgp ); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = ((PBEAlgorithm)kgAlg).getEncryptionAlg(); AlgorithmParameterSpec algParams = null; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); } else if( encAlg.getParameterClass().equals( RC2ParameterSpec.class ) ) { algParams = new RC2ParameterSpec(key.getStrength(), kg.generatePBE_IV()); } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams); return Cipher.unPad(cipher.doFinal( encryptedContent.toByteArray() )); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(EncryptedContentInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addOptionalElement(new Tag(0), new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() ==3); return new EncryptedContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkcs7/EncryptedData.java000066400000000000000000000076331326145000000225760ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import org.mozilla.jss.asn1.*; import java.io.*; /** * The PKCS #7 structure EncryptedData. */ public class EncryptedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER version; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence; /** * The default version number. This should always be used unless * you really know what you are doing. */ public static final INTEGER DEFAULT_VERSION = new INTEGER(0); /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private EncryptedData() { } /** * Creates a new EncryptedData. * * @param version Should usually be DEFAULT_VERSION unless you are being * very clever. */ public EncryptedData( INTEGER version, EncryptedContentInfo encryptedContentInfo ) { if( version == null || encryptedContentInfo == null ) { throw new IllegalArgumentException("null parameter"); } sequence = new SEQUENCE(); this.version = version; sequence.addElement(version); this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(encryptedContentInfo); } /** * Creates an EncryptedData with the default version. */ public EncryptedData( EncryptedContentInfo encryptedContentInfo ) { this( DEFAULT_VERSION, encryptedContentInfo ); } /////////////////////////////////////////////////////////////////////// // Accessor Methods /////////////////////////////////////////////////////////////////////// public INTEGER getVersion() { return version; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A Template for decoding EncryptedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( EncryptedContentInfo.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new EncryptedData( (INTEGER) seq.elementAt(0), (EncryptedContentInfo) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs7/EnvelopedData.java000066400000000000000000000060371326145000000225570ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; public class EnvelopedData implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private SET recipientInfos; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public SET getRecipientInfos() { return recipientInfos; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } private EnvelopedData() { } /** * Create a EnvelopedData ASN1 object. */ public EnvelopedData( INTEGER version, SET recipientInfos, EncryptedContentInfo encryptedContentInfo) { this.version = version; this.recipientInfos = recipientInfos; this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(encryptedContentInfo); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public Tag getTag() { return EnvelopedData.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(EnvelopedData.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new SET.OF_Template(new RecipientInfo.Template())); seqt.addElement(new EncryptedContentInfo.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() ==3); return new EnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (EncryptedContentInfo) seq.elementAt(2) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkcs7/IssuerAndSerialNumber.java000066400000000000000000000072121326145000000242460ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.Assert; /** * An issuer name and serial number, used to uniquely identify a certificate. */ public class IssuerAndSerialNumber implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private Name issuer; private INTEGER serialNumber; private SEQUENCE sequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// // no default constructor private IssuerAndSerialNumber() { } /** * Constructs an IssuerAndSerialNumber from its components. * * @param issuer Must not be null. * @param serialNumber must not be null. */ public IssuerAndSerialNumber(Name issuer, INTEGER serialNumber) { if(issuer==null || serialNumber==null) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public Name getIssuer() { return issuer; } public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// static Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * Returns a singleton template instance. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding an IssuerAndSerialNumber from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( Name.getTemplate() ); seqt.addElement( INTEGER.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 2); return new IssuerAndSerialNumber( (Name) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs7/Makefile000066400000000000000000000035311326145000000206350ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/pkcs7/RecipientInfo.java000066400000000000000000000075051326145000000226030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import org.mozilla.jss.pkix.primitive.*; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; public class RecipientInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier keyEncryptionAlgorithmID; private OCTET_STRING encryptedKey; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public IssuerAndSerialNumber getissuerAndSerialNumber() { return issuerAndSerialNumber; } public AlgorithmIdentifier getKeyEncryptionAlgorithmID() { return keyEncryptionAlgorithmID; } public OCTET_STRING getEncryptedKey() { return encryptedKey; } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } private RecipientInfo() { } /** * Create a RecipientInfo ASN1 object. */ public RecipientInfo( INTEGER version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier keyEncryptionAlgorithmID, OCTET_STRING encryptedKey) { Assert._assert(issuerAndSerialNumber != null); Assert._assert(keyEncryptionAlgorithmID != null); Assert._assert(encryptedKey != null); this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.keyEncryptionAlgorithmID = keyEncryptionAlgorithmID; this.encryptedKey = encryptedKey; sequence.addElement(version); sequence.addElement(issuerAndSerialNumber); sequence.addElement(keyEncryptionAlgorithmID); sequence.addElement(encryptedKey); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a RecipientInfo blob * */ public static class Template implements ASN1Template { public Tag getTag() { return RecipientInfo.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(RecipientInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new IssuerAndSerialNumber.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addElement(new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() ==4); return new RecipientInfo( (INTEGER) seq.elementAt(0), (IssuerAndSerialNumber) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkcs7/SignedAndEnvelopedData.java000066400000000000000000000133241326145000000243310ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; public class SignedAndEnvelopedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET recipientInfos; private SET digestAlgorithms; private EncryptedContentInfo encryptedContentInfo; private SET certificates; // may be null private SET crls; // may be null private SET signerInfos; private SEQUENCE sequence; // for encoding /** * Returns the version number. The current version is 1. */ public INTEGER getVersion() { return version; } /** * Returns a SET of RecipientInfo. */ public SET getRecipientInfos() { return recipientInfos; } /** * Returns a SET of AlgorithmIdentifier. */ public SET getDigestAlgorithms() { return digestAlgorithms; } /** * Returns the encrypted content. */ public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /** * Returns a SET of ANYs. May return null if the * certificates field is not present. */ public SET getCertificates() { return certificates; } /** * Returns a SET of ANYs. May return null if the crls * field is not present. */ public SET getCrls() { return crls; } /** * Returns a SET of SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private SignedAndEnvelopedData() { } public SignedAndEnvelopedData( INTEGER version, SET recipientInfos, SET digestAlgorithms, EncryptedContentInfo encryptedContentInfo, SET certificates, SET crls, SET signerInfos) { if( version==null || recipientInfos==null || digestAlgorithms==null || encryptedContentInfo==null || signerInfos==null ) { throw new IllegalArgumentException( "SignedAndEnvelopedData constructor parameter is null"); } this.version = version; this.recipientInfos = recipientInfos; this.digestAlgorithms = digestAlgorithms; this.encryptedContentInfo = encryptedContentInfo; this.certificates = certificates; this.crls = crls; this.signerInfos = signerInfos; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(digestAlgorithms); sequence.addElement(encryptedContentInfo); if( certificates!=null ) { sequence.addElement(certificates); } if( crls!=null ) { sequence.addElement(crls); } sequence.addElement( signerInfos ); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * A Template class for decoding BER-encoded SignedAndEnvelopedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(new SET.OF_Template(RecipientInfo.getTemplate())); seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate()) ); seqt.addElement(EncryptedContentInfo.getTemplate()); seqt.addOptionalElement(new Tag(0), new SET.OF_Template(ANY.getTemplate())); seqt.addOptionalElement(new Tag(1), new SET.OF_Template(ANY.getTemplate())); seqt.addElement(new SET.OF_Template(SignerInfo.getTemplate())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new SignedAndEnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (SET) seq.elementAt(2), (EncryptedContentInfo) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5), (SET) seq.elementAt(6) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkcs7/SignedData.java000066400000000000000000000324051326145000000220450ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import java.io.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.Certificate; /* CUT THIS??? *

Although all the normal functionality of a SignedData is supported * with high-level methods, there is a low-level API for setting the * individual fields of the structure. Using these calls is an unsupported * way of accomplishing unforeseen tasks. If you have reason to use these * methods, please notify the authors in case it is something that should * be added to the high-level interface. * */ /** * A PKCS #7 SignedData structure. This class implements version 1 * of the spec. *

The certificates field should only contain X.509 certificates. * PKCS #6 extended certificates will fail to decode properly. * @author stevep * @author nicolson */ public class SignedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET digestAlgorithms; private ContentInfo contentInfo; private SET certificates; // [0] optional, may be null private SET crls; // [1] optional, may be null private SET signerInfos; // This class implements version 1 of the spec. private static final INTEGER VERSION = new INTEGER(1); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static void verifyNotNull(Object obj) { if( obj == null ) { throw new IllegalArgumentException(); } } /** * Returns the version of this SignedData. The current version of the * spec is version 1. */ public INTEGER getVersion() { return version; } /** * Low-level function to set the version. * @param version Must not be null. public void setVersion(INTEGER version) { verifyNotNull(version); this.version = version; } */ /** * Returns the digest algorithms used by the signers to digest the * signed content. There may be more than one, if different signers * use different digesting algorithms. */ public SET getDigestAlgorithmIdentifiers() { return digestAlgorithms; } /** * Low-level function to set the digest algorithm identifiers. * @param digestAlgIds Must not be null. public void setDigestAlgorithmIdentifiers(SET digestAlgIds) { verifyNotNull(digestAlgIds); this.digestAlgorithms = digestAlgIds; } */ /** * Returns the ContentInfo containing the signed content. The simple * case is for the content to be of type data, although any * content type can be signed. */ public ContentInfo getContentInfo() { return contentInfo; } /** * Low-level function to set the contentInfo. * @param ci Must not be null. public void setContentInfo(ContentInfo ci) { verifyNotNull(ci); this.contentInfo = ci; } */ /** * Returns the certificates field, which is a SET of * X.509 certificates (org.mozilla.jss.pkix.cert.Certificate). * PKCS #6 Extended Certificates are not supported by this implementation. * Returns null if this optional field is not present. * */ public SET getCertificates() { return certificates; } /** * Low-level function to set the certificates. * @param certs May be null to signify that the certificates * field is not present. public void setCertificates(SET certs) { this.certificates = certs; } */ /** * Returns true if the certificates field is present. */ public boolean hasCertificates() { return (certificates!=null); } /** * Returns the crls field, which contains a SET of certificate * revocation lists represented by ANYs (org.mozilla.jss.asn1.ANY). * */ public SET getCrls() { return crls; } /** * Low-level function to set the crls. * @param certs May be null to signify that the crls * field is not present. public void setCrls(SET crls) { this.crls = crls; } */ /** * Returns true if the crls field is present. */ public boolean hasCrls() { return (crls != null); } /** * Returns the signerInfos field, which is a SET of * org.mozilla.jss.pkcs7.SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /** * Low-level function to set the SignerInfos. * @param signerInfos Must not be null. public void setSignerInfos(SET signerInfos) { verifyNotNull(sis); this.signerInfos = signerInfos; } */ /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Low-level constructor that merely initializes all fields to null. private SignedData() {} */ /** * Create a SignedData ASN1 object. Both certificates and CRLs * are optional. If you pass in a null for either value, that * parameter will not get written in the sequence. * * @param digestAlgorithms A SET of zero or more * algorithm identifiers. The purpose of this item is to list * the digest algorithms used by the various signers to digest * the signed content. This field will also be updated by * the addSigner method. If all the signers are added * with addSigner, it is not necessary to list * the digest algorithms here. *

If null is passed in, the * digestAlgorithms field will be initialized * with an empty SET. * @param contentInfo The content that is being signed. This parameter * may not be null. However, the content * field of the contentInfo may be omitted, in which case the * signatures contained in the SignerInfo structures * are presumed to be on externally-supplied data. * @param certificates A SET of org.mozilla.jss.pkix.cert.Certificate, * the certificates * containing the public keys used to sign the content. It may * also contain elements of the CA chain extending from the leaf * certificates. It is not necessary to include the CA chain, or * indeed to include any certificates, if the certificates are * expected to already be possessed by the recipient. The recipient * can use the issuer and serial number in the SignerInfo structure * to search for the necessary certificates. If this parameter is * null, the certificates field will be * omitted. * @param crls A SET of ASN1Values, which should encode to the ASN1 type * CertificateRevocationList. This implementation does * not interpret CRLs. If this parameter is null, * the crls field will be omitted. * @param signerInfos SignerInfo structures containing signatures * of the content. Additional signerInfos can be added with * the addSigner method. If this parameter is * null, the field will be initialized with an * empty SET. */ public SignedData( SET digestAlgorithms, ContentInfo contentInfo, SET certificates, SET crls, SET signerInfos) { version = VERSION; if(digestAlgorithms == null ) { this.digestAlgorithms = new SET(); } else { this.digestAlgorithms = digestAlgorithms; } verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; if(signerInfos == null) { this.signerInfos = new SET(); } else { this.signerInfos = signerInfos; } } /** * Constructor for creating a SignedData from its encoding. */ SignedData( INTEGER version, SET digestAlgorithms, ContentInfo contentInfo, SET certificates, SET crls, SET signerInfos ) { verifyNotNull(version); this.version = version; verifyNotNull(digestAlgorithms); this.digestAlgorithms = digestAlgorithms; verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; verifyNotNull(signerInfos); this.signerInfos = signerInfos; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Cryptographic functions /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithms); sequence.addElement(contentInfo); if( certificates != null ) { sequence.addElement( new Tag(0), certificates ); } if( crls != null ) { sequence.addElement( new Tag(1), crls ); } sequence.addElement(signerInfos); sequence.encode(tag,ostream); } /** * A template file for decoding a SignedData blob * */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // version seqt.addElement(INTEGER.getTemplate()); // digestAlgorithms seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate())); // content info seqt.addElement(ContentInfo.getTemplate()); // [0] IMPLICIT certificates OPTIONAL seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Certificate.getTemplate())); // [1] IMPLICIT CertificateRevocationLists OPTIONAL seqt.addOptionalElement( new Tag(1), new SET.OF_Template(ANY.getTemplate())); // signerInfos seqt.addElement(new SET.OF_Template(SignerInfo.getTemplate())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 6); return new SignedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (ContentInfo) seq.elementAt(2), (SET) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkcs7/SignerInfo.java000066400000000000000000000760121326145000000221070ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkcs7; import java.io.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.crypto.*; import java.util.Vector; import java.math.BigInteger; import java.io.ByteArrayInputStream; import java.security.InvalidKeyException; import java.security.SignatureException; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import org.mozilla.jss.crypto.*; import org.mozilla.jss.*; import java.security.PublicKey; /* * The high-level interface takes care of all * the logic and cryptography. If you need to use the low-level interface, * please let us know what you are using it for. Perhaps it should be part * of the high-level interface. */ /** * A PKCS #7 SignerInfo. */ public class SignerInfo implements ASN1Value { //////////////////////////////////////////////// // PKCS #9 attributes //////////////////////////////////////////////// private static final OBJECT_IDENTIFIER CONTENT_TYPE = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(3); private static final OBJECT_IDENTIFIER MESSAGE_DIGEST = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(4); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier digestAlgorithm; private SET authenticatedAttributes; // [0] OPTIONAL private AlgorithmIdentifier digestEncryptionAlgorithm; private OCTET_STRING encryptedDigest; private SET unauthenticatedAttributes; // [1] OPTIONAL // we only do version 1 of PKCS #7 private static final INTEGER VERSION = new INTEGER(1); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Retrieves the version number of this SignerInfo. */ public INTEGER getVersion() { return version; } /** * Low-level method to set the version. * It is not normally necessary to call this. Use it at your own risk. public void setVersion(INTEGER version) { this.version = version; } */ /** * Retrieves the issuer and serial number of the certificate whose * private key was used to sign the SignerInfo. */ public IssuerAndSerialNumber getIssuerAndSerialNumber() { return issuerAndSerialNumber; } /** * Low-level method to set the issuerAndSerialNumber. * It is not normally necessary to call this. Use it at your own risk. public void setIssuerAndSerialNumber( IssuerAndSerialNumber iasn ) { this.issuerAndSerialNumber = iasn; } */ /** * Retrieves the DigestAlgorithm used in this SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not recognized * by JSS. */ public DigestAlgorithm getDigestAlgorithm() throws NoSuchAlgorithmException { return DigestAlgorithm.fromOID( digestAlgorithm.getOID() ); } /** * Retrieves the DigestAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestAlgorithmIdentifer() { return digestAlgorithm; } /** * Low-level method to set the digest AlgorithmIdentifier. * It is not normally necessary to call this. Use it at your own risk. public void setDigestAlgorithmIdentifier(AlgorithmIdentifier algid) { this.digestAlgorithm = algid; } */ /** * Retrieves the authenticated attributes, if they exist. * */ public SET getAuthenticatedAttributes() { return authenticatedAttributes; } /** * Returns true if the authenticatedAttributes field is present. */ public boolean hasAuthenticatedAttributes() { return (authenticatedAttributes != null); } /** * Low-level method to set the authenticatedAttributes field. * It is not normally necessary to call this. Use it at your own risk. public void setAuthenticatedAttributes(SET authAttrib) { this.authenticatedAttributes = authAttrib; } */ /** * Returns the raw signature (digest encryption) algorithm used in this * SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not recognized * by JSS. */ public SignatureAlgorithm getDigestEncryptionAlgorithm() throws NoSuchAlgorithmException { return SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); } /** * Returns the DigestEncryptionAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestEncryptionAlgorithmIdentifier() { return digestEncryptionAlgorithm; } /** * Low-level method to set the digestEncryptionAlgorithm field. * It is not normally necessary to call this. Use it at your own risk. public void setDigestEncryptionAlgorithmIdentifier(AlgorithmIdentifier algid) { this.digestEncryptionAlgorithm= algid; } */ /** * Retrieves the encrypted digest. */ public byte[] getEncryptedDigest() { return encryptedDigest.toByteArray(); } /** * Low-level method to set the encryptedDigest field. * It is not normally necessary to call this. Use it at your own risk. public void setEncryptedDigest(byte[] ed) { this.encryptedDigest = new OCTET_STRING(ed); } */ /** * Retrieves the unauthenticated attributes, if they exist. * */ public SET getUnauthenticatedAttributes() { return unauthenticatedAttributes; } /** * Returns true if the unauthenticatedAttributes field is present. */ public boolean hasUnauthenticatedAttributes() { return (unauthenticatedAttributes!=null); } /** * Low-level method to set the unauthenticatedAttributes field. * It is not normally necessary to call this. Use it at your own risk. public void setUnauthenticatedAttributes(SET unauthAttrib) { this.unauthenticatedAttributes = unauthAttrib; } */ /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Low-level default constructor. All fields are initialized to null. * Before this SignerInfo can be processed or used in any way, all of * the fields except authenticatedAttributes and * unauthenticatedAttributes must be non-null. *

It is not normally necessary to call this constructor.Use it at * your own risk. public SignerInfo() { } */ /** * A constructor for creating a new SignerInfo from scratch. * * @param issuerAndSerialNumber The issuer and serial number of the * certificate from which the public key was extracted to create * this SignerInfo. * @param signingAlg The algorithm to be used to sign the content. * This should be a composite algorithm, such as * RSASignatureWithMD5Digest, instead of a raw algorithm, such as * RSASignature. * Note that the digest portion of this algorithm must be the same * algorithm as was used to digest the message content. * @param authenticatedAttributes An optional set of Attributes, which * will be signed along with the message content. This parameter may * be null, or the SET may be empty. DO NOT insert * the PKCS #9 content-type or message-digest attributes. They will * be added automatically if they are necessary. * @param unauthenticatedAttributes An optional set of Attributes, which * will be included in the SignerInfo but not signed. This parameter * may be null, or the SET may be empty. * @param messageDigest The digest of the message contents. The digest * must have been created with the digest algorithm specified by * the signingAlg parameter. * @param contentType The type of the ContentInfo that is being signed. * If it is not data, then the PKCS #9 attributes * content-type and message-digest will be automatically computed and * added to the authenticated attributes. */ public SignerInfo( IssuerAndSerialNumber issuerAndSerialNumber, SET authenticatedAttributes, SET unauthenticatedAttributes, OBJECT_IDENTIFIER contentType, byte[] messageDigest, SignatureAlgorithm signingAlg, PrivateKey signingKey ) throws InvalidKeyException, NoSuchAlgorithmException, CryptoManager.NotInitializedException, SignatureException, TokenException { version = VERSION; this.issuerAndSerialNumber = issuerAndSerialNumber; this.digestAlgorithm = new AlgorithmIdentifier(signingAlg.getDigestAlg().toOID(),null); // if content-type is not data, add message-digest and content-type // to authenticated attributes. if( ! contentType.equals(ContentInfo.DATA) ) { if( authenticatedAttributes == null ) { authenticatedAttributes = new SET(); } Attribute attrib = new Attribute(CONTENT_TYPE, ContentInfo.DATA); authenticatedAttributes.addElement(attrib); attrib = new Attribute(MESSAGE_DIGEST, new OCTET_STRING(messageDigest) ); authenticatedAttributes.addElement(attrib); } digestEncryptionAlgorithm = new AlgorithmIdentifier( signingAlg.getRawAlg().toOID(),null ); if( authenticatedAttributes != null ) { Assert._assert( authenticatedAttributes.size() >= 2 ); this.authenticatedAttributes = authenticatedAttributes; } ////////////////////////////////////////////////// // create encrypted digest (signature) ////////////////////////////////////////////////// // compute the digest byte[] digest=null; DigestAlgorithm digestAlg = signingAlg.getDigestAlg(); if( authenticatedAttributes == null ) { // just use the message digest of the content digest = messageDigest; } else { // digest the contents octets of the authenticated attributes byte[] enc = ASN1Util.encode(authenticatedAttributes); MessageDigest md = MessageDigest.getInstance(digestAlg.toString()); digest = md.digest( enc ); } byte[] toBeSigned; if( signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) { // put the digest in a DigestInfo SEQUENCE digestInfo = new SEQUENCE(); AlgorithmIdentifier digestAlgId = new AlgorithmIdentifier( digestAlg.toOID(),null ); digestInfo.addElement( digestAlgId ); digestInfo.addElement( new OCTET_STRING( digest ) ); toBeSigned = ASN1Util.encode(digestInfo); } else { toBeSigned = digest; } // encrypt the DER-encoded DigestInfo with the private key CryptoToken token = signingKey.getOwningToken(); Signature sig; sig = token.getSignatureContext( signingAlg.getRawAlg() ); sig.initSign(signingKey); sig.update(toBeSigned); encryptedDigest = new OCTET_STRING(sig.sign()); if( unauthenticatedAttributes != null ) { this.unauthenticatedAttributes = unauthenticatedAttributes; } } /** * A constructor for creating a new SignerInfo from its decoding. */ SignerInfo( INTEGER version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier digestAlgorithm, SET authenticatedAttributes, AlgorithmIdentifier digestEncryptionAlgorithm, byte[] encryptedDigest, SET unauthenticatedAttributes) { this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.digestAlgorithm = digestAlgorithm; this.authenticatedAttributes = authenticatedAttributes; this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; this.encryptedDigest = new OCTET_STRING(encryptedDigest); this.unauthenticatedAttributes = unauthenticatedAttributes; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Verification /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any authenticated attributes are present, * they are also validated. The verification algorithm is as follows: * Note that this does not verify the validity of the * the certificate itself, only the signature.

    * *
  • If no authenticated attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If authenticated attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * authenticatedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @exception ObjectNotFoundException If no certificate matching the * the issuer name and serial number can be found. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException, ObjectNotFoundException { CryptoManager cm = CryptoManager.getInstance(); X509Certificate cert = cm.findCertByIssuerAndSerialNumber( ASN1Util.encode(issuerAndSerialNumber.getIssuer()), issuerAndSerialNumber.getSerialNumber() ); verify(messageDigest, contentType, cert.getPublicKey()); } /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any authenticated attributes are present, * they are also validated. The verification algorithm is as follows:
    * *
  • If no authenticated attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If authenticated attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * authenticatedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @param pubkey The public key to use to verify the signature. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( authenticatedAttributes == null ) { verifyWithoutAuthenticatedAttributes(messageDigest, contentType, pubkey); } else { verifyWithAuthenticatedAttributes(messageDigest, contentType, pubkey); } } /** * Verifies that the message digest passed in, when encrypted with the * given public key, matches the encrypted digest in the SignerInfo. */ private void verifyWithoutAuthenticatedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( ! contentType.equals(ContentInfo.DATA) ) { // only data can be signed this way. Everything else has // to go into authenticatedAttributes. throw new SignatureException( "Content-Type is not DATA, but there are"+ " no authenticated attributes"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); byte[] toBeVerified; if( sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) { // create DigestInfo structure SEQUENCE digestInfo = new SEQUENCE(); digestInfo.addElement( new AlgorithmIdentifier(digestAlgorithm.getOID(), null) ); digestInfo.addElement( new OCTET_STRING(messageDigest) ); toBeVerified = ASN1Util.encode(digestInfo); } else { toBeVerified = messageDigest; } CryptoToken token = CryptoManager.getInstance() .getInternalCryptoToken(); Signature sig = token.getSignatureContext(sigAlg); sig.initVerify(pubkey); sig.update(toBeVerified); if( sig.verify(encryptedDigest.toByteArray()) ) { return; // success } else { throw new SignatureException( "Encrypted message digest parameter does not "+ "match encrypted digest in SignerInfo"); } } /** * Verifies a SignerInfo with authenticated attributes. If authenticated * attributes are present, then two particular attributes must * be present:
    *
  • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
  • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
* After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * authenticatedAttributes field. */ private void verifyWithAuthenticatedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { int numAttrib = authenticatedAttributes.size(); if(numAttrib < 2) { throw new SignatureException( "At least two authenticated attributes must be present:"+ " content-type and message-digest"); } // go through the authenticated attributes, verifying the // interesting ones boolean foundContentType = false; boolean foundMessageDigest = false; for( int i = 0; i < numAttrib; i++ ) { if( ! (authenticatedAttributes.elementAt(i) instanceof Attribute)) { throw new SignatureException( "Element of authenticatedAttributes is not an Attribute"); } Attribute attrib = (Attribute) authenticatedAttributes.elementAt(i); if( attrib.getType().equals(CONTENT_TYPE) ) { // content-type. Compare with what was passed in. SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Content-Type attribute "+ " does not have exactly one value"); } ASN1Value val = vals.elementAt(0); OBJECT_IDENTIFIER ctype; try { if( val instanceof OBJECT_IDENTIFIER ) { ctype = (OBJECT_IDENTIFIER) val; } else if( val instanceof ANY ) { ctype = (OBJECT_IDENTIFIER) ((ANY)val).decodeWith( OBJECT_IDENTIFIER.getTemplate() ); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type authenticated attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Content-Type authenticated attribute does not have "+ "OBJECT IDENTIFIER value"); } // compare the content type in the attribute to the // contentType parameter if( ! ctype.equals( contentType ) ) { throw new SignatureException( "Content-type in authenticated attributes does not "+ "match content-type being verified"); } // content type is A-OK foundContentType = true; } else if( attrib.getType().equals(MESSAGE_DIGEST) ) { SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Message-digest attribute does not have"+ " exactly one value"); } ASN1Value val = vals.elementAt(0); byte[] mdigest; try { if( val instanceof OCTET_STRING ) { mdigest = ((OCTET_STRING)val).toByteArray(); } else if( val instanceof ANY ) { OCTET_STRING os; os = (OCTET_STRING) ((ANY)val).decodeWith( OCTET_STRING.getTemplate() ); mdigest = os.toByteArray(); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type authenticated attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Message-digest attribute does not"+ " have OCTET STRING value"); } // compare the message digest in the attribute to the // message digest being verified if( ! byteArraysAreSame(mdigest, messageDigest) ) { throw new SignatureException( "Message-digest attribute does not"+ " match message digest being verified"); } // message digest is A-OK foundMessageDigest = true; } // we don't care about other attributes } if( !foundContentType ) { throw new SignatureException( "Authenticated attributes does not contain"+ " PKCS #9 content-type attribute"); } if( !foundMessageDigest ) { throw new SignatureException( "Authenticate attributes does not contain"+ " PKCS #9 message-digest attribute"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID(digestEncryptionAlgorithm.getOID()); // All the authenticated attributes are present and correct. // Now verify the signature. CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); Signature sig = token.getSignatureContext( sigAlg ); sig.initVerify(pubkey); // verify the contents octets of the DER encoded authenticated attribs byte[] toBeDigested; toBeDigested = ASN1Util.encode(authenticatedAttributes); MessageDigest md = MessageDigest.getInstance( DigestAlgorithm.fromOID(digestAlgorithm.getOID()).toString() ); byte[] digest = md.digest(toBeDigested); byte[] toBeVerified; if( sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature ) { // create DigestInfo structure SEQUENCE digestInfo = new SEQUENCE(); digestInfo.addElement( new AlgorithmIdentifier(digestAlgorithm.getOID(),null) ); digestInfo.addElement( new OCTET_STRING(digest) ); toBeVerified = ASN1Util.encode(digestInfo); } else { toBeVerified = digest; } sig.update( toBeVerified ); if( ! sig.verify(encryptedDigest.toByteArray()) ) { // signature is invalid throw new SignatureException("encryptedDigest was not the correct"+ " signature of the contents octets of the DER-encoded"+ " authenticated attributes"); } // SUCCESSFULLY VERIFIED } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { Assert._assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER-encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement( version ); sequence.addElement( issuerAndSerialNumber ); sequence.addElement( digestAlgorithm ); if( authenticatedAttributes != null ) { sequence.addElement( new Tag(0), authenticatedAttributes ); } sequence.addElement( digestEncryptionAlgorithm ); sequence.addElement( encryptedDigest ); if( unauthenticatedAttributes != null ) { sequence.addElement( new Tag(1), unauthenticatedAttributes ); } sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a SignerInfo blob * */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // serial number seqt.addElement(INTEGER.getTemplate()); // vn // issuerAndSerialNumber seqt.addElement(IssuerAndSerialNumber.getTemplate()); // issuer + sernum // digestAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // digest alg // authenticatedAttributes seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Attribute.getTemplate())); // digestEncryptionAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // dig encr alg // encryptedDigest seqt.addElement(OCTET_STRING.getTemplate()); // encr digest // unauthenticated attributes seqt.addOptionalElement( new Tag(1), new SET.OF_Template(Attribute.getTemplate())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() == 7); return new SignerInfo( (INTEGER) seq.elementAt(0), (IssuerAndSerialNumber) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (SET) seq.elementAt(3), (AlgorithmIdentifier) seq.elementAt(4), ((OCTET_STRING) seq.elementAt(5)).toByteArray(), (SET) seq.elementAt(6) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkcs7/manifest.mn000066400000000000000000000021751326145000000213420ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 PACKAGE = org/mozilla/jss/pkcs7 CLASSES = \ ContentInfo \ DigestedData \ DigestInfo \ EncryptedContentInfo \ EncryptedData \ EnvelopedData \ IssuerAndSerialNumber \ RecipientInfo \ SignedAndEnvelopedData \ SignedData \ SignerInfo \ $(NULL) JSRCS = \ ContentInfo.java \ DigestedData.java \ DigestInfo.java \ EncryptedContentInfo.java \ EncryptedData.java \ EnvelopedData.java \ IssuerAndSerialNumber.java \ RecipientInfo.java \ SignedAndEnvelopedData.java \ SignedData.java \ SignerInfo.java \ $(NULL) jss-4.4.3/jss/org/mozilla/jss/pkcs7/package.html000066400000000000000000000004321326145000000214530ustar00rootroot00000000000000 Creating and interpeting PKCS #7 blobs. jss-4.4.3/jss/org/mozilla/jss/pkix/000077500000000000000000000000001326145000000171175ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkix/cert/000077500000000000000000000000001326145000000200545ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkix/cert/Certificate.java000066400000000000000000000267131326145000000231520ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cert; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import java.security.cert.CertificateException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.SignatureException; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.security.PublicKey; import java.security.KeyPair; import java.util.Date; import java.util.Calendar; import java.io.BufferedInputStream; import java.io.FileInputStream; /** * An X.509 signed certificate. */ public class Certificate implements ASN1Value { private CertificateInfo info; private byte[] infoEncoding; private byte[] signature; private AlgorithmIdentifier algId; SEQUENCE sequence; private Certificate() { } Certificate(CertificateInfo info, byte[] infoEncoding, AlgorithmIdentifier algId, byte[] signature) throws IOException { this.info = info; this.infoEncoding = infoEncoding; this.algId = algId; this.signature = signature; // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Creates and signs an X.509 Certificate. * @param info A CertificateInfo (TBSCertificate), which specifies * the actual information of the certificate. * @param privKey The private key with which to sign the certificate. * @param signingAlg The algorithm to use to sign the certificate. * It must match the algorithm specified in the CertificateInfo. * @exception IOException If an error occurred while encoding the * certificate. * @exception CryptoManager.NotInitializedException Because this * operation involves cryptography (signing), CryptoManager must * be initialized before calling it. * @exception TokenException If an error occurs on a PKCS #11 token. * @exception NoSuchAlgorithmException If the OID for the signing algorithm * cannot be located. * @exception CertificateException If the signing algorithm specified * as a parameter does not match the one in the certificate info. * @exception InvalidKeyException If the key does not match the signing * algorithm. * @exception SignatureException If an error occurs while signing the * certificate. */ public Certificate(CertificateInfo info, java.security.PrivateKey privKey, SignatureAlgorithm signingAlg) throws IOException, CryptoManager.NotInitializedException, TokenException, NoSuchAlgorithmException, CertificateException, InvalidKeyException, SignatureException { // make sure key is a Ninja private key if( !(privKey instanceof PrivateKey) ) { throw new InvalidKeyException("Private Key is does not belong to"+ " this provider"); } PrivateKey priv = (PrivateKey)privKey; // create algId and compare to the one in the cert info if(signingAlg.getSigningAlg() == SignatureAlgorithm.RSASignature) { algId = new AlgorithmIdentifier( signingAlg.toOID(), null ); } else { algId = new AlgorithmIdentifier( signingAlg.toOID() ); } if( ! info.getSignatureAlgId().getOID().equals(algId.getOID()) ) { throw new CertificateException("Signing Algorithm does not match"+ " the one specified in the CertificateInfo"); } // encode the cert info this.info = info; infoEncoding = ASN1Util.encode(info); // sign the info encoding CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = priv.getOwningToken(); Signature sig = token.getSignatureContext(signingAlg); sig.initSign(priv); sig.update(infoEncoding); signature = sig.sign(); // bundle everything into a SEQUENCE sequence = new SEQUENCE(); sequence.addElement( info ); sequence.addElement( algId ); sequence.addElement( new BIT_STRING( signature, 0 ) ); } /** * Verifies the signature on this certificate. Does not indicate * that the certificate is valid at any specific time. */ public void verify() throws InvalidKeyException, CryptoManager.NotInitializedException, NoSuchAlgorithmException, CertificateException, SignatureException, InvalidKeyFormatException { verify( info.getSubjectPublicKeyInfo().toPublicKey() ); } /** * Verifies the signature on this certificate, using the given public key. * Does not indicate the certificate is valid at any specific time. */ public void verify(PublicKey key) throws InvalidKeyException, NoSuchAlgorithmException, CertificateException, SignatureException { try { CryptoManager cm = CryptoManager.getInstance(); verify(key, cm.getInternalCryptoToken()); } catch( CryptoManager.NotInitializedException e ) { throw new SignatureException("CryptoManager not initialized"); } } /** * Verifies the signature on this certificate, using the given public * key and CryptoToken. Does not indicate the certificate is valid at * any specific time. */ public void verify(PublicKey key, CryptoToken token) throws NoSuchAlgorithmException, CertificateException, SignatureException, InvalidKeyException { try { Signature sig = token.getSignatureContext( SignatureAlgorithm.fromOID( info.getSignatureAlgId().getOID() ) ); sig.initVerify(key); sig.update(infoEncoding); if( ! sig.verify(signature) ) { throw new CertificateException("Signature is invalid"); } } catch(TokenException e) { throw new SignatureException("PKCS #11 token error: " + e.getMessage()); } } /** * Returns the information (TBSCertificate) contained in this certificate. */ public CertificateInfo getInfo() { return info; } private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); //seqt.addElement( CertificateInfo.getTemplate() ); seqt.addElement( new ANY.Template() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); ANY infoAny = (ANY)seq.elementAt(0); byte[] infoEncoding = infoAny.getEncoded(); CertificateInfo info = (CertificateInfo) infoAny.decodeWith( CertificateInfo.getTemplate() ); // although signature is a bit string, all algorithms we use // will produce an octet string. BIT_STRING bs = (BIT_STRING) seq.elementAt(2); if( bs.getPadCount() != 0 ) { throw new InvalidBERException("signature does not fall into"+ " an integral number of bytes"); } byte[] signature = bs.getBits(); return new Certificate( info, infoEncoding, (AlgorithmIdentifier) seq.elementAt(1), signature ); } } public static void main(String argv[]) { try { if(argv.length > 2 || argv.length < 1) { System.out.println("Usage: Certificate []"); System.exit(0); } CryptoManager.initialize( argv[0] ); CryptoManager cm = CryptoManager.getInstance(); // read in a cert BufferedInputStream bis = new BufferedInputStream( new FileInputStream(argv[1]) ); Certificate cert = (Certificate) Certificate.getTemplate().decode(bis); CertificateInfo info = cert.getInfo(); info.print(System.out); //X509Certificate hardcore = cm.findCertByNickname("Hardcore"); //PublicKey key = hardcore.getPublicKey(); cert.verify(); System.out.println("verified"); FileOutputStream fos = new FileOutputStream("certinfo.der"); info.encode(fos); fos.close(); // make a new public key CryptoToken token = cm.getInternalKeyStorageToken(); KeyPairGenerator kpg = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpg.initialize(512); System.out.println("Generating a new key pair..."); KeyPair kp = kpg.genKeyPair(); System.out.println("Generated key pair"); // set the certificate's public key info.setSubjectPublicKeyInfo(kp.getPublic()); // increment serial number int newSerial = info.getSerialNumber().intValue() + 1; info.setSerialNumber( new INTEGER(newSerial) ); // make new Name Name name = new Name(); name.addCommonName("Stra\u00dfenverk\u00e4ufer 'R' Us"); name.addCountryName("US"); name.addOrganizationName("Some Corporation"); name.addOrganizationalUnitName("some org unit?"); name.addLocalityName("Silicon Valley"); name.addStateOrProvinceName("California"); info.setIssuer(name); info.setSubject(name); // set validity Calendar cal = Calendar.getInstance(); cal.set(1997, Calendar.APRIL, 1); info.setNotBefore( cal.getTime() ); cal.set(2010, Calendar.APRIL, 1); info.setNotAfter( cal.getTime() ); System.out.println("About to create a new cert..."); // create a new cert from this certinfo Certificate genCert = new Certificate(info, kp.getPrivate(), SignatureAlgorithm.RSASignatureWithMD5Digest); System.out.println("Created new cert"); genCert.verify(); System.out.println("Cert verifies!"); fos = new FileOutputStream("gencert.der"); genCert.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cert/CertificateInfo.java000066400000000000000000000370671326145000000237720ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cert; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.*; import java.security.cert.CertificateException; import java.security.PublicKey; import java.util.Calendar; import java.util.Date; import java.util.TimeZone; import java.io.InputStream; import java.io.PrintStream; import java.io.OutputStream; import java.io.IOException; /** * A TBSCertificate (to-be-signed certificate), the actual information in * a certificate apart from the signature. */ public class CertificateInfo implements ASN1Value { /** * An X.509 Certificate version. */ public static class Version { private Version() { } private Version(int vers, String string) { versionNumber = vers; this.string = string; } int versionNumber; String string; public boolean equals(Object obj) { if(obj == null || !(obj instanceof Version)) { return false; } return ((Version)obj).versionNumber == versionNumber; } public int getNumber() { return versionNumber; } /** * Creates a version number from its numeric encoding. */ public static Version fromInt(int versionNum) throws InvalidBERException { if( versionNum == 0 ) { return v1; } else if( versionNum == 1) { return v2; } else if( versionNum == 2) { return v3; } else { throw new InvalidBERException("Unrecognized version number"); } } public String toString() { return string; } public static final Version v1 = new Version(0, "v1"); public static final Version v2 = new Version(1, "v2"); public static final Version v3 = new Version(2, "v3"); } public static final Version v1 = Version.v1; public static final Version v2 = Version.v2; public static final Version v3 = Version.v3; // the last year for using UTCTime static final int UTCTIME_CUTOFF_YEAR = 2049; private Version version = v1; private INTEGER serialNumber; private AlgorithmIdentifier signatureAlgId; private Name issuer; private Date notBefore; private Date notAfter; private Name subject; private SubjectPublicKeyInfo subjectPublicKeyInfo; private BIT_STRING issuerUniqueIdentifier; // may be null private BIT_STRING subjectUniqueIdentifier; // may be null private SEQUENCE extensions; // if no extensions, size() == 0. Never null. /** * Creates a CertificateInfo with the required fields. */ public CertificateInfo(Version version, INTEGER serialNumber, AlgorithmIdentifier signatureAlgId, Name issuer, Date notBefore, Date notAfter, Name subject, SubjectPublicKeyInfo subjectPublicKeyInfo) { setVersion(version); setSerialNumber(serialNumber); setSignatureAlgId(signatureAlgId); setIssuer(issuer); setNotBefore(notBefore); setNotAfter(notAfter); setSubject(subject); setSubjectPublicKeyInfo(subjectPublicKeyInfo); extensions = new SEQUENCE(); } public void setVersion(Version version) { verifyNotNull(version); this.version = version; } public Version getVersion() { return version; } public void setSerialNumber(INTEGER serialNumber) { verifyNotNull(serialNumber); this.serialNumber = serialNumber; } public INTEGER getSerialNumber() { return serialNumber; } public void setSignatureAlgId(AlgorithmIdentifier signatureAlgId) { verifyNotNull(signatureAlgId); this.signatureAlgId = signatureAlgId; } public AlgorithmIdentifier getSignatureAlgId() { return signatureAlgId; } public void setIssuer(Name issuer) { verifyNotNull(issuer); this.issuer = issuer; } public Name getIssuer() { return issuer; } public void setNotBefore(Date notBefore) { verifyNotNull(notBefore); this.notBefore = notBefore; } public Date getNotBefore() { return notBefore; } public void setNotAfter(Date notAfter) { verifyNotNull(notAfter); this.notAfter = notAfter; } public Date getNotAfter() { return notAfter; } public void setSubject(Name subject) { verifyNotNull(subject); this.subject = subject; } public Name getSubject() { return subject; } public void setSubjectPublicKeyInfo( SubjectPublicKeyInfo subjectPublicKeyInfo) { verifyNotNull(subjectPublicKeyInfo); this.subjectPublicKeyInfo = subjectPublicKeyInfo; } /** * Extracts the SubjectPublicKeyInfo from the given public key and * stores it in the CertificateInfo. * * @exception InvalidBERException If an error occurs decoding the * the information extracted from the public key. */ public void setSubjectPublicKeyInfo( PublicKey pubk ) throws InvalidBERException, IOException { verifyNotNull(pubk); setSubjectPublicKeyInfo( new SubjectPublicKeyInfo(pubk) ); } public SubjectPublicKeyInfo getSubjectPublicKeyInfo() { return subjectPublicKeyInfo; } /** * @exception CertificateException If the certificate is a v1 certificate. */ public void setIssuerUniqueIdentifier(BIT_STRING issuerUniqueIdentifier) throws CertificateException { if(version==v1) { throw new CertificateException("issuerUniqueIdentifier cannot"+ " be specified for v1 certificate"); } verifyNotNull(issuerUniqueIdentifier); this.issuerUniqueIdentifier = issuerUniqueIdentifier; } public boolean hasIssuerUniqueIdentifier() { return (issuerUniqueIdentifier!=null); } /** * Should only be called if this field is present. */ public BIT_STRING getIssuerUniqueIdentifier() { Assert._assert(issuerUniqueIdentifier != null); return issuerUniqueIdentifier; } /** * @exception CertificateException If the certificate is a v1 certificate. */ public void setSubjectUniqueIdentifier(BIT_STRING subjectUniqueIdentifier) throws CertificateException { if(version==v1) { throw new CertificateException("subjectUniqueIdentifier cannot"+ " be specified for v1 certificate"); } verifyNotNull(subjectUniqueIdentifier); this.subjectUniqueIdentifier = subjectUniqueIdentifier; } public boolean hasSubjectUniqueIdentifier() { return (subjectUniqueIdentifier!=null); } public BIT_STRING getSubjectUniqueIdentifier() { Assert._assert(subjectUniqueIdentifier != null); return subjectUniqueIdentifier; } public boolean hasExtensions() { return extensions.size() > 0; } /** * Returns the extensions of this certificate. The sequence may be * empty, but this method will never return null. */ public SEQUENCE getExtensions() { return extensions; } /** * Linearly searches the extension list for an extension with the given * object identifier. If it finds one, returns true. Otherwise, * returns false. */ public boolean isExtensionPresent(OBJECT_IDENTIFIER oid) { return ( getExtension(oid) != null ); } /** * Linearly searches the extension list for an extension with the given * object identifier. It returns the first one it finds. If none are found, * returns null. */ public Extension getExtension(OBJECT_IDENTIFIER oid) { int numExtensions = extensions.size(); for( int i=0; i < numExtensions; ++i) { Extension ext = (Extension) extensions.elementAt(i); if( oid.equals(ext.getExtnId()) ) { return ext; } } return null; } /** * @exception CertificateException If the certificate is not a v3 * certificate. */ public void setExtensions(SEQUENCE extensions) throws CertificateException { if(version != v3) { throw new CertificateException("extensions can only be added to"+ " v3 certificates"); } if( Debug.DEBUG ) { int size = extensions.size(); for(int i=0; i < size; i++) { Assert._assert(extensions.elementAt(i) instanceof Extension); } } verifyNotNull(extensions); this.extensions = extensions; } /** * @exception CertificateException If the certificate is not a v3 * certificate. */ public void addExtension(Extension extension) throws CertificateException { if(version != v3) { throw new CertificateException("extensions can only be added to"+ " v3 certificates"); } extensions.addElement(extension); } private void verifyNotNull(Object obj) { if( obj == null ) { throw new NullPointerException(); } } static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); if( version != v1 ) { // v1 is the default seq.addElement(new EXPLICIT( new Tag(0), new INTEGER(version.getNumber()) ) ); } seq.addElement(serialNumber); seq.addElement(signatureAlgId); seq.addElement(issuer); SEQUENCE validity = new SEQUENCE(); validity.addElement( encodeValidityDate(notBefore) ); validity.addElement( encodeValidityDate(notAfter) ); seq.addElement(validity); seq.addElement(subject); seq.addElement(subjectPublicKeyInfo); if( issuerUniqueIdentifier != null ) { seq.addElement(new Tag(1), issuerUniqueIdentifier); } if( subjectUniqueIdentifier != null ) { seq.addElement(new Tag(2), subjectUniqueIdentifier); } if( extensions.size() > 0 ) { seq.addElement(new EXPLICIT(new Tag(3), extensions) ); } seq.encode(implicitTag, ostream); } /** * Returns the correct ASN1Value (UTCTime or GeneralizedTime) to represent * the given certificate validity date. */ private static ASN1Value encodeValidityDate(Date d) { Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") ); cal.setTime(d); if( cal.get(Calendar.YEAR) <= UTCTIME_CUTOFF_YEAR) { return new UTCTime(d); } else { return new GeneralizedTime(d); } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public void print(PrintStream ps) throws IOException, InvalidBERException { ps.println("CertificateInfo:"); ps.println("Version: "+version); ps.println("Serial Number: "+serialNumber); ps.println("Sig OID: "+signatureAlgId.getOID()); ps.println("Issuer: "+issuer.getRFC1485()); ps.println("Not Before: "+notBefore); ps.println("Not After: "+notAfter); ps.println("Subject: "+subject.getRFC1485()); } /** * Template class for decoding a CertificateInfo. */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); EXPLICIT.Template versionTemp = EXPLICIT.getTemplate( new Tag(0), INTEGER.getTemplate() ); EXPLICIT defVersion = new EXPLICIT(new Tag(0), new INTEGER(v1.getNumber()) ); seqt.addElement( versionTemp, defVersion ); seqt.addElement(INTEGER.getTemplate()); //serial number seqt.addElement(AlgorithmIdentifier.getTemplate()); //signatureAlgId seqt.addElement(Name.getTemplate()); // issuer // deal with validity SEQUENCE.Template validity = new SEQUENCE.Template(); CHOICE.Template timeChoice = CHOICE.getTemplate(); timeChoice.addElement( UTCTime.getTemplate() ); timeChoice.addElement( GeneralizedTime.getTemplate() ); validity.addElement( timeChoice ); // notBefore validity.addElement( timeChoice ); // notAfter seqt.addElement(validity); seqt.addElement(Name.getTemplate()); //subject seqt.addElement(SubjectPublicKeyInfo.getTemplate()); seqt.addOptionalElement( new Tag(1), BIT_STRING.getTemplate() ); seqt.addOptionalElement( new Tag(2), BIT_STRING.getTemplate() ); // deal with extensions SEQUENCE.OF_Template extnTemp = new SEQUENCE.OF_Template( Extension.getTemplate() ); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(3), extnTemp) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); EXPLICIT exp = (EXPLICIT) seq.elementAt(0); Version version = Version.fromInt( ((INTEGER)exp.getContent()).intValue() ); SEQUENCE validity = (SEQUENCE) seq.elementAt(4); CHOICE choice = (CHOICE)validity.elementAt(0); Date notBefore = ((TimeBase)choice.getValue()).toDate(); choice = (CHOICE)validity.elementAt(1); Date notAfter = ((TimeBase)choice.getValue()).toDate(); CertificateInfo cinfo = new CertificateInfo( version, (INTEGER) seq.elementAt(1), // serial num (AlgorithmIdentifier) seq.elementAt(2), //sigAlgId (Name) seq.elementAt(3), // issuer notBefore, notAfter, (Name) seq.elementAt(5), // subject (SubjectPublicKeyInfo) seq.elementAt(6) ); if( seq.elementAt(7) != null ) { cinfo.setIssuerUniqueIdentifier( (BIT_STRING)seq.elementAt(7) ); } if( seq.elementAt(8) != null ) { cinfo.setSubjectUniqueIdentifier( (BIT_STRING)seq.elementAt(8)); } if( seq.elementAt(9) != null ) { exp = (EXPLICIT)seq.elementAt(9); cinfo.setExtensions( (SEQUENCE) exp.getContent() ); } return cinfo; } catch( CertificateException e ) { throw new InvalidBERException(e.getMessage()); } } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cert/Extension.java000066400000000000000000000054521326145000000227010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cert; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; public class Extension implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private OBJECT_IDENTIFIER extnId; /** * Returns the extension identifier. */ public OBJECT_IDENTIFIER getExtnId() { return extnId; } private boolean critical; public boolean getCritical() { return critical; } private OCTET_STRING extnValue; public OCTET_STRING getExtnValue() { return extnValue; } private Extension() { } public Extension( OBJECT_IDENTIFIER extnId, boolean critical, OCTET_STRING extnValue ) { this.extnId = extnId; this.critical = critical; this.extnValue = extnValue; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement( extnId ); if( critical == true ) { // false is default, so we only code true seq.addElement( new BOOLEAN(true) ); } seq.addElement( extnValue ); seq.encode(implicit, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( BOOLEAN.getTemplate(), new BOOLEAN(false) ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag t) { return TAG.equals(t); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); return new Extension( (OBJECT_IDENTIFIER) seq.elementAt(0), ((BOOLEAN) seq.elementAt(1)).toBoolean(), (OCTET_STRING) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cert/SubjectKeyIdentifier.java000066400000000000000000000060761326145000000250030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cert; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; /** * Represent the Subject Key Identifier Extension. * * This extension, if present, provides a means of identifying the particular * public key used in an application. This extension by default is marked * non-critical. * *

Extensions are additional attributes which can be inserted in a X509 * v3 certificate. For example a "Driving License Certificate" could have * the driving license number as a extension. * *

Extensions are represented as a sequence of the extension identifier * (Object Identifier), a boolean flag stating whether the extension is to * be treated as being critical and the extension value itself (this is again * a DER encoding of the extension value). * * @author Michelle Zhao * @version 1.0 * @see Extension */ public class SubjectKeyIdentifier extends Extension { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private OCTET_STRING keyIdentifier; private static OBJECT_IDENTIFIER OID = new OBJECT_IDENTIFIER("2.5.29.14"); /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// /** * Constructs an SubjectKeyIdentifier from its components. * * @param keyIdentifier must not be null. */ public SubjectKeyIdentifier(OCTET_STRING keyIdentifier) { super(OID,false,keyIdentifier); } public SubjectKeyIdentifier(boolean critical, OCTET_STRING keyIdentifier) { super(OID,critical,keyIdentifier); } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OBJECT_IDENTIFIER.getTemplate() ); seqt.addElement( BOOLEAN.getTemplate(), new BOOLEAN(false) ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag t) { return TAG.equals(t); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); Assert._assert( ((OBJECT_IDENTIFIER) seq.elementAt(0)).equals(OID) ); return new SubjectKeyIdentifier( ((BOOLEAN) seq.elementAt(1)).toBoolean(), (OCTET_STRING) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cert/package.html000066400000000000000000000004671326145000000223440ustar00rootroot00000000000000 Encoding and decoding X.509 certificates and certificate extensions. jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/000077500000000000000000000000001326145000000176615ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/BodyPartReference.java000066400000000000000000000144651326145000000241010ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2004 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.util.Assert; import org.mozilla.jss.asn1.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.BitSet; /** * CMC BodyPartReference: *

 *      BodyPartReference::= CHOICE { 
 *          bodyPartID       BodyPartID
 *          bodyPartPath     SEQUENCE SIZE (1..MAX) OF BodyPartID, 
 *     } 
 *
 * @author Christina Fu (cfu)
 * 
*/ public class BodyPartReference implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /** * The type of BodyPartReference. */ public static class Type { private Type() { } static Type BodyPartID = new Type(); static Type BodyPartPath = new Type(); } public static Type BodyPartID = Type.BodyPartID; public static Type BodyPartPath = Type.BodyPartPath; /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private Type type; private INTEGER bodyPartID; private SEQUENCE bodyPartPath; /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private BodyPartReference() { } /** * @param type The type of the BodyPartReference * @param bodyPartID A BodyPartID. * @param bodyPartPath The sequence of bodyPartIDs. */ public BodyPartReference(Type type, INTEGER bodyPartID, SEQUENCE bodyPartPath) { this.bodyPartID = bodyPartID; this.bodyPartPath = bodyPartPath; } /** * Adds a BodyPartID to the bodyPartPath SEQUENCE. */ public void addBodyPartId(int id) { INTEGER id1 = new INTEGER(id); Assert._assert(id1.compareTo(BODYIDMAX) <= 0); bodyPartPath.addElement( id1 ); } /////////////////////////////////////////////////////////////////////// // member access /////////////////////////////////////////////////////////////////////// /** * Returns the type of BodyPartReference:
    *
  • BodyPartID *
  • BodyPartPath *
*/ public Type getType() { return type; } public INTEGER getBodyPartID() { return bodyPartID; } public SEQUENCE getBodyPartPath() { return bodyPartPath; } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { //return the subType's tag if (type == BodyPartID ) { return INTEGER.TAG; } else { Assert._assert( type == BodyPartPath); return SEQUENCE.TAG; } } public void encode(OutputStream ostream) throws IOException { if (type == BodyPartID ) { bodyPartID.encode(ostream); } else { Assert._assert( type == BodyPartPath); bodyPartPath.encode(ostream); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { encode(ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a BodyPartReference. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( INTEGER.getTemplate() ); choicet.addElement( new SEQUENCE.OF_Template(INTEGER.getTemplate()) ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE c = (CHOICE) choicet.decode(istream); if( c.getTag().equals(INTEGER.TAG) ) { return new BodyPartReference(BodyPartID, (INTEGER) c.getValue() , null); } else { Assert._assert( c.getTag().equals(SEQUENCE.TAG) ); return new BodyPartReference(BodyPartPath, null, (SEQUENCE) c.getValue()); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { //A CHOICE cannot be implicitly tagged return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/CMCCertId.java000066400000000000000000000114341326145000000222240ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMC CMCCertId. *
 * The definition of IssuerSerial comes from RFC 3281.
 * CMCCertId ::= SEQUENCE {
 *      issuer      GeneralNames,
 *      serial      INTEGER 
 *      issuerUID   UniqueIdentifier OPTIONAL}
 * 
*/ public class CMCCertId implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private SEQUENCE issuer; private INTEGER serial; private BIT_STRING issuerUID; private SEQUENCE sequence; /** * Returns the issuer field as an SEQUENCE of * ANY. The actual type of the field is GeneralNames. */ public SEQUENCE getIssuer() { return issuer; } /** * Returns the serial field. */ public INTEGER getSerial() { return serial; } /** * Returns the issuerUID field. */ public BIT_STRING getIssuerUID() { return issuerUID; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private CMCCertId() { } /** * Constructs a new CMCCertId from its components. The * uniqueIdentifier component may be null. */ public CMCCertId(SEQUENCE issuer, INTEGER serial, BIT_STRING issuerUID) { if (issuer == null || serial == null) { throw new IllegalArgumentException( "parameter to CMCCertId constructor is null"); } if (issuer.size() == 0) { throw new IllegalArgumentException( "issuer parameter to CMCCertId constructor is empty"); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serial = serial; sequence.addElement(serial); if (issuerUID != null) { sequence.addElement(issuerUID); } } /** * Constructs a new CMCCertId from its components. The * issuerUID component may be null. */ public CMCCertId(ANY issuer, INTEGER serial, BIT_STRING issuerUID) { if (issuer == null || serial == null) { throw new IllegalArgumentException( "parameter to CMCCertId constructor is null"); } sequence = new SEQUENCE(); this.issuer = new SEQUENCE(); this.issuer.addElement(issuer); sequence.addElement(this.issuer); this.serial = serial; sequence.addElement(serial); if (issuerUID != null) { sequence.addElement(issuerUID); } } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a CMCCertId. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new SEQUENCE.OF_Template(ANY.getTemplate())); seqt.addElement( INTEGER.getTemplate() ); seqt.addOptionalElement(BIT_STRING.getTemplate()); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new CMCCertId((SEQUENCE)seq.elementAt(0), (INTEGER)seq.elementAt(1), (BIT_STRING)seq.elementAt(2)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/CMCStatusInfo.java000066400000000000000000000145721326145000000231570ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.util.Assert; import org.mozilla.jss.asn1.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.BitSet; /** * CMC CMCStatusInfo: *
 *     CMCStatusInfo ::= SEQUENCE {
 *          cMCStatus           CMCStatus,
 *          bodyList            SEQUENCE SIZE (1..MAX) OF BodyPartID,
 *          statusString        UTF8String OPTIONAL,
 *          otherInfo           CHOICE {
 *            failInfo            CMCFailInfo,
 *            pendInfo            PendInfo } OPTIONAL
 *     }
 *     PendInfo ::= SEQUENCE {
 *          pendToken           OCTET STRING,
 *          pendTime            GeneralizedTime
 *     }
 * 
*/ public class CMCStatusInfo implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER status; private SEQUENCE bodyList; private UTF8String statusString; private OtherInfo otherInfo; // CMCStatus constants public static final int SUCCESS = 0; public static final int RESERVED = 1; public static final int FAILED = 2; public static final int PENDING = 3; public static final int NOSUPPORT = 4; public static final int CONFIRM_REQUIRED = 5; public static final String[] STATUS = {"success", "reserved", "failed", "pending", "not supported", "confirm required"}; /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private CMCStatusInfo() { } /** * @param status A CMCStatus constant. * @param bodyList The sequence of bodyPartID. */ public CMCStatusInfo(int status, SEQUENCE bodyList) { this.status = new INTEGER(status); this.bodyList = bodyList; this.statusString = null; this.otherInfo = null; } /** * @param status A CMCStatus constant. * @param bodyList The sequence of bodyPartID. * @param statusString A String. * @param otherInfo The OtherInfo choice. */ public CMCStatusInfo(int status, SEQUENCE bodyList, String statusString, OtherInfo otherInfo) { this.status = new INTEGER(status); this.bodyList = bodyList; if (statusString != null){ try{ this.statusString = new UTF8String(statusString); }catch (Exception e){} }else this.statusString = null; this.otherInfo = otherInfo; } /** * Create a CMCStatusInfo from decoding. * @param status A CMCStatus constant. * @param bodyList The sequence of bodyPartID. * @param statusString A UTF8String. * @param otherInfo A CHOICE. */ public CMCStatusInfo(INTEGER status, SEQUENCE bodyList, UTF8String statusString, OtherInfo otherInfo) { this.status = status; this.bodyList = bodyList; this.statusString = statusString; this.otherInfo = otherInfo; } /** * Sets the statusString field. May be null, since this * field is optional. */ public void setStatusString(String statusString) { if (statusString != null){ try{ this.statusString = new UTF8String(statusString); }catch (Exception e){} }else{ this.statusString = null; } } /** * Adds a BodyPartID to the bodyList SEQUENCE. */ public void addBodyPartID(int id) { INTEGER id1 = new INTEGER(id); Assert._assert(id1.compareTo(BODYIDMAX) <= 0); bodyList.addElement( id1 ); } /////////////////////////////////////////////////////////////////////// // member access /////////////////////////////////////////////////////////////////////// public int getStatus() { return status.intValue(); } public SEQUENCE getBodyList() { return bodyList; } public String getStatusString() { if (statusString != null) return statusString.toString(); return null; } public OtherInfo getOtherInfo() { return otherInfo; } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(status); seq.addElement(bodyList); if( statusString != null ) { seq.addElement( statusString ); } if ( otherInfo != null) { seq.addElement( otherInfo ); } seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( new SEQUENCE.OF_Template(INTEGER.getTemplate()) ); seqt.addOptionalElement( UTF8String.getTemplate()); seqt.addOptionalElement( OtherInfo.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { CMCStatusInfo psi; SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new CMCStatusInfo((INTEGER)seq.elementAt(0), (SEQUENCE)seq.elementAt(1), (UTF8String)seq.elementAt(2), (OtherInfo)seq.elementAt(3)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/CMCStatusInfoV2.java000066400000000000000000000217151326145000000233640ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.util.Assert; import org.mozilla.jss.asn1.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.BitSet; /** * CMCStatusInfoV2 replaces CMCStatusInfo in rfc 5272 * CMC CMCStatusInfoV2: *
 *     CMCStatusInfoV2 ::= SEQUENCE { 
 *          cMCStatus           CMCStatus, 
 *          bodyList            SEQUENCE SIZE (1..MAX)
 *                                       BodyPartReference,
 *          statusString        UTF8String OPTIONAL, 
 *          otherInfo           CHOICE {  // defined in updated OtherInfo
 *            failInfo            CMCFailInfo, 
 *            pendInfo            PendInfo,
 *            extendedFailInfo       SEQUENCE {
 *              failInfoOID            OBJECT IDENTIFIER,
 *              failInfoValue          AttributeValue
 *            } OPTIONAL 
 *         }
 *     } 
 *     PendInfo ::= SEQUENCE { 
 *          pendToken           OCTET STRING, 
 *          pendTime            GeneralizedTime 
 *     }
 *
 * @author Christina Fu (cfu)
 * 
*/ public class CMCStatusInfoV2 implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER status; private SEQUENCE bodyList; private UTF8String statusString; private OtherInfo otherInfo; // CMCStatus constants public static final int SUCCESS = 0; public static final int RESERVED = 1; public static final int FAILED = 2; public static final int PENDING = 3; public static final int NOSUPPORT = 4; public static final int CONFIRM_REQUIRED = 5; public static final int POP_REQUIRED = 6; public static final int PARTIAL = 7; public static final String[] STATUS = {"success", "reserved", "failed", "pending", "not supported", "confirm required", "pop required", "partial"}; /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private CMCStatusInfoV2() { } /** * @param status A CMCStatus constant. * @param bodyList The sequence of BodyPartReference. */ public CMCStatusInfoV2(int status, SEQUENCE bodyList) { this.status = new INTEGER(status); this.bodyList = bodyList; this.statusString = null; this.otherInfo = null; } /** * @param status A CMCStatus constant. * @param bodyList The sequence of BodyPartReference. * @param statusString A String. * @param otherInfo The OtherInfo choice. */ public CMCStatusInfoV2(int status, SEQUENCE bodyList, String statusString, OtherInfo otherInfo) { this.status = new INTEGER(status); this.bodyList = bodyList; if (statusString != null){ try { this.statusString = new UTF8String(statusString); } catch (Exception e){} } else this.statusString = null; this.otherInfo = otherInfo; } /** * Create a CMCStatusInfoV2 from decoding. * @param status A CMCStatus constant. * @param bodyList The sequence of BodyPartReference. * @param statusString A UTF8String. * @param otherInfo A CHOICE. */ public CMCStatusInfoV2(INTEGER status, SEQUENCE bodyList, UTF8String statusString, OtherInfo otherInfo) { this.status = status; this.bodyList = bodyList; this.statusString = statusString; this.otherInfo = otherInfo; } /** * Sets the statusString field. May be null, since this * field is optional. */ public void setStatusString(String statusString) { if (statusString != null){ try { this.statusString = new UTF8String(statusString); } catch (Exception e){} } else{ this.statusString = null; } } /** * Adds a BodyPartID to the bodyList SEQUENCE. */ public void addBodyPartID(int id) { INTEGER id1 = new INTEGER(id); Assert._assert(id1.compareTo(BODYIDMAX) <= 0); bodyList.addElement( id1 ); } /////////////////////////////////////////////////////////////////////// // member access /////////////////////////////////////////////////////////////////////// public int getStatus() { return status.intValue(); } public SEQUENCE getBodyList() { return bodyList; } public String getStatusString() { if (statusString != null) return statusString.toString(); return null; } public OtherInfo getOtherInfo() { return otherInfo; } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(status); seq.addElement(bodyList); if( statusString != null ) { seq.addElement( statusString ); } if ( otherInfo != null) { seq.addElement( otherInfo ); } seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( new SEQUENCE.OF_Template(INTEGER.getTemplate()) ); seqt.addOptionalElement( UTF8String.getTemplate()); seqt.addOptionalElement( OtherInfo.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { CMCStatusInfoV2 psi; SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new CMCStatusInfoV2((INTEGER)seq.elementAt(0), (SEQUENCE)seq.elementAt(1), (UTF8String)seq.elementAt(2), (OtherInfo)seq.elementAt(3)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/DecryptedPOP.java000066400000000000000000000125151326145000000230320ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; /** * CMC DecryptedPOP: *
 *     DecryptedPOP ::= SEQUENCE {
 *         bodyPartID      BodyPartID,
 *         thePOPAlgID     AlgorithmIdentifier,
 *         thePOP         OCTET STRING
 *     }
 * 
* * @author Christina Fu (cfu) */ public class DecryptedPOP implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER bodyPartID; private AlgorithmIdentifier thePOPAlgID; private OCTET_STRING thePOP; private SEQUENCE sequence; // for DER encoding /** * Returns the bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } public AlgorithmIdentifier getThePOPAlgID() { return thePOPAlgID; } public OCTET_STRING getWitness() { return thePOP; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private DecryptedPOP() { } public DecryptedPOP( INTEGER bodyPartID, AlgorithmIdentifier thePOPAlgID, OCTET_STRING thePOP) { if( bodyPartID==null || thePOPAlgID==null || thePOP==null ) { throw new IllegalArgumentException("DecryptedPOP constructor" +" parameter is null"); } this.bodyPartID = bodyPartID; this.thePOPAlgID = thePOPAlgID; this.thePOP = thePOP; sequence = new SEQUENCE(); sequence.addElement(bodyPartID); sequence.addElement(thePOPAlgID); sequence.addElement(thePOP); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding BER-encoded DecryptedPOP items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new DecryptedPOP( (INTEGER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/EncryptedPOP.java000066400000000000000000000141651326145000000230470ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cms.*; import java.io.*; /** * CMC EncryptedPOP: *
 *     EncryptedPOP ::= SEQUENCE {
 *         request       TaggedRequest,
 *         cms             ContentInfo,
 *         thePOPAlgID     AlgorithmIdentifier,
 *         witnessAlgID    AlgorithmIdentifier,
 *         witness         OCTET STRING
 *     }
 * 
* * @author Christina Fu (cfu) */ public class EncryptedPOP implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private TaggedRequest request; private ContentInfo cms; private AlgorithmIdentifier thePOPAlgID; private AlgorithmIdentifier witnessAlgID; private OCTET_STRING witness; private SEQUENCE sequence; // for DER encoding public TaggedRequest getRequest() { return request; } public ContentInfo getContentInfo() { return cms; } public AlgorithmIdentifier getThePOPAlgID() { return thePOPAlgID; } public AlgorithmIdentifier getWitnessAlgID() { return witnessAlgID; } public OCTET_STRING getWitness() { return witness; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private EncryptedPOP() { } public EncryptedPOP( TaggedRequest request, ContentInfo cms, AlgorithmIdentifier thePOPAlgID, AlgorithmIdentifier witnessAlgID, OCTET_STRING witness) { if( request==null || cms==null || thePOPAlgID==null || witnessAlgID==null || witness==null ) { throw new IllegalArgumentException("EncryptedPOP constructor" +" parameter is null"); } this.request = request; this.cms = cms; this.thePOPAlgID = thePOPAlgID; this.witnessAlgID = witnessAlgID; this.witness = witness; sequence = new SEQUENCE(); sequence.addElement(request); sequence.addElement(cms); sequence.addElement(thePOPAlgID); sequence.addElement(witnessAlgID); sequence.addElement(witness); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding BER-encoded EncryptedPOP items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( TaggedRequest.getTemplate() ); seqt.addElement( ContentInfo.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new EncryptedPOP( (TaggedRequest) seq.elementAt(0), (ContentInfo) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (AlgorithmIdentifier) seq.elementAt(3), (OCTET_STRING) seq.elementAt(4) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/ExtendedFailInfo.java000066400000000000000000000113561326145000000237020ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; /** * ExtendedFailInfo per rfc 5272 * It is to be used in CMCStatusInfoV2 as a CHOICE of otherInfo * *
 *      ExtendedFailInfo ::= SEQUENCE {
 *          failInfoOID        OBJECT IDENTIFIER,
 *          failInfoValue       ANY DEFINED BY failInfoOID }
 * 
* * @author Christina Fu (cfu) */ public class ExtendedFailInfo implements ASN1Value { private OBJECT_IDENTIFIER failInfoOID; private ANY failInfoValue; public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private ExtendedFailInfo() { } public ExtendedFailInfo(OBJECT_IDENTIFIER failInfoOID, ASN1Value failInfoValue) { this.failInfoOID = failInfoOID; if( failInfoValue instanceof ANY ) { this.failInfoValue = (ANY) failInfoValue; } else { byte[] encoded = ASN1Util.encode(failInfoValue); try { this.failInfoValue = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded); } catch( InvalidBERException e ) { Assert.notReached("InvalidBERException while decoding as ANY"); } } } public OBJECT_IDENTIFIER getOID() { return failInfoOID; } /** * Returns the failInfoValue of this ExtendedFailInfo, encoded as an ANY. */ public ANY getValue() { return failInfoValue; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(failInfoOID); seq.addElement(failInfoValue); seq.encode(implicit, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding an ExtendedFailInfo. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement( new OBJECT_IDENTIFIER.Template() ); seqt.addElement( new ANY.Template() ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this Assert._assert(seq.size() == 2); return new ExtendedFailInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/GetCert.java000066400000000000000000000067231326145000000220710ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMC GetCert. *
 * GetCert ::= SEQUENCE {
 *      issuerName      GeneralName,
 *      serialNumber    INTEGER }
 * 
*/ public class GetCert implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private ANY issuerName; private INTEGER serialNumber; private SEQUENCE sequence; /** * Returns the issuerName field as an ANY. * The actual type of the field is GeneralName. */ public ANY getIssuer() { return issuerName; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private GetCert() { } /** * Constructs a new GetCert from its components. Neither * component may be null. */ public GetCert(ANY issuerName, INTEGER serialNumber) { if( issuerName == null || serialNumber == null ) { throw new IllegalArgumentException( "parameter to GetCert constructor is null"); } sequence = new SEQUENCE(); this.issuerName = issuerName; sequence.addElement(issuerName); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a GetCert. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addElement( INTEGER.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new GetCert( (ANY) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/IdentityProofV2.java000066400000000000000000000125401326145000000235350ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; /** * CMC IdentityProofV2: * per rfc 5272 *
 *     IdentityProofV2 ::= SEQUENCE {
 *         hashAlgID      AlgorithmIdentifier,
 *         macAlgId       AlgorithmIdentifier,
 *         witness        OCTET STRING
 *     }
 * 
* * @author Christina Fu (cfu) */ public class IdentityProofV2 implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private AlgorithmIdentifier hashAlgID; private AlgorithmIdentifier macAlgId; private OCTET_STRING witness; private SEQUENCE sequence; // for DER encoding public AlgorithmIdentifier getHashAlgID() { return hashAlgID; } public AlgorithmIdentifier getMacAlgId() { return macAlgId; } public OCTET_STRING getWitness() { return witness; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private IdentityProofV2() { } public IdentityProofV2( AlgorithmIdentifier hashAlgID, AlgorithmIdentifier macAlgId, OCTET_STRING witness) { if( hashAlgID==null || macAlgId==null || witness==null ) { throw new IllegalArgumentException("IdentityProofV2 constructor" +" parameter is null"); } this.hashAlgID = hashAlgID; this.macAlgId = macAlgId; this.witness = witness; sequence = new SEQUENCE(); sequence.addElement(hashAlgID); sequence.addElement(macAlgId); sequence.addElement(witness); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding BER-encoded IdentityProofV2 items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new IdentityProofV2( (AlgorithmIdentifier) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/LraPopWitness.java000066400000000000000000000075661326145000000233140ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.util.Assert; import org.mozilla.jss.asn1.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.BitSet; /** * CMC LraPopWitness: *
 *      LraPopWitness::= SEQUENCE { 
 *          pkiDataBodyid       BodyPartID
 *          bodyids             SEQUENCE SIZE (1..MAX) OF BodyPartID, 
 *     } 
 * 
*/ public class LraPopWitness implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER pkiDataBodyid; private SEQUENCE bodyIds; private SEQUENCE sequence; /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private LraPopWitness() { } /** * @param pkiDataBodyid A PKI data BodyPartID. * @param bodyIds The sequence of bodyPartIDs. */ public LraPopWitness(INTEGER pkiDataBodyid, SEQUENCE bodyIds) { if (pkiDataBodyid == null || bodyIds == null) throw new IllegalArgumentException( "parameter to LraPopWitness constructor is null"); sequence = new SEQUENCE(); this.pkiDataBodyid = pkiDataBodyid; sequence.addElement(pkiDataBodyid); this.bodyIds = bodyIds; sequence.addElement(bodyIds); } /** * Adds a BodyPartID to the bodyIds SEQUENCE. */ public void addBodyPartId(int id) { INTEGER id1 = new INTEGER(id); Assert._assert(id1.compareTo(BODYIDMAX) <= 0); bodyIds.addElement( id1 ); } /////////////////////////////////////////////////////////////////////// // member access /////////////////////////////////////////////////////////////////////// public INTEGER getPKIDataBodyid() { return pkiDataBodyid; } public SEQUENCE getBodyIds() { return bodyIds; } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( new SEQUENCE.OF_Template(INTEGER.getTemplate()) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new LraPopWitness((INTEGER)seq.elementAt(0), (SEQUENCE)seq.elementAt(1)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/OtherInfo.java000066400000000000000000000214101326145000000224170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.util.Assert; /** * CMCStatusInfoV2 OtherInfo: * *
 *   OtherInfo ::= CHOICE { 
 *       failInfo INTEGER, 
 *       pendInfo PendInfo,
 *       extendedFailInfo       SEQUENCE {  // ExtendedFailInfo
 *           failInfoOID            OBJECT IDENTIFIER,
 *           failInfoValue          AttributeValue
 *       } OPTIONAL
 *   }
 * 
* * @author Christina Fu (cfu) - updated for rfc5272 */ public class OtherInfo implements ASN1Value { // CMCFailInfo constants public static final int BAD_ALG = 0; public static final int BAD_MESSAGE_CHECK = 1; public static final int BAD_REQUEST = 2; public static final int BAD_TIME = 3; public static final int BAD_CERT_ID = 4; public static final int UNSUPORTED_EXT = 5; public static final int MUST_ARCHIVE_KEYS = 6; public static final int BAD_IDENTITY = 7; public static final int POP_REQUIRED = 8; public static final int POP_FAILED = 9; public static final int NO_KEY_REUSE = 10; public static final int INTERNAL_CA_ERROR = 11; public static final int TRY_LATER = 12; public static final int authDataFail = 13; public static final String[] FAIL_INFO = { "bad algorithm", "bad message check", "bad request", "bad time", "bad certificate id", "unsupported extensions", "must archive keys", "bad identity", "POP required", "POP failed", "no key reuse", "internal ca error", "try later", "authenticated data fail"}; /** * The type of OtherInfo. */ public static class Type { private Type() { } static Type FAIL = new Type(); static Type PEND = new Type(); static Type EXTENDED = new Type(); } public static Type FAIL = Type.FAIL; public static Type PEND = Type.PEND; public static Type EXTENDED = Type.EXTENDED; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private Type type; private INTEGER failInfo; // if type == FAIL private PendInfo pendInfo; // if type == PEND private ExtendedFailInfo extendedFailInfo; // if type == EXTENDED /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// // no default constructor public OtherInfo() { } /** * Constructs a OtherInfo from its components. * * @param type The type of the otherInfo. * @param failInfo the CMCFailInfo code. * @param pendInfo the pending information. * * Note: kept for backward compatibility for now; new code don't use */ public OtherInfo(Type type, INTEGER failInfo, PendInfo pendInfo) { if (type == null) { throw new IllegalArgumentException("OtherInfo constructor" +" parameter is null"); } if ( type == FAIL ) { if (failInfo == null) { throw new IllegalArgumentException("OtherInfo constructor" +" parameter failInfo is null"); } } else { Assert._assert( type == PEND ); if (pendInfo == null) { throw new IllegalArgumentException("OtherInfo constructor" +" parameter pendInfo is null"); } } this.type = type; this.failInfo = failInfo; this.pendInfo = pendInfo; } /** * Constructs a OtherInfo from its components. * * @param type The type of the otherInfo. * @param failInfo the CMCFailInfo code. * @param pendInfo the pending information. * @param extendedFailInfo the extendedFailInfo information. */ public OtherInfo(Type type, INTEGER failInfo, PendInfo pendInfo, ExtendedFailInfo extendedFailInfo) { if (type == null) { throw new IllegalArgumentException("OtherInfo constructor" +" parameter is null"); } if ( type == FAIL ) { if (failInfo == null) { throw new IllegalArgumentException("OtherInfo constructor" +" parameter failInfo is null"); } } else if ( type == PEND ) { if (pendInfo == null) { throw new IllegalArgumentException("OtherInfo constructor" +" parameter pendInfo is null"); } } else { Assert._assert( type == EXTENDED ); if (extendedFailInfo == null) { throw new IllegalArgumentException("OtherInfo constructor" +" parameter extendedFailInfo is null"); } } this.type = type; this.failInfo = failInfo; this.pendInfo = pendInfo; this.extendedFailInfo = extendedFailInfo; } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// /** * Returns the type of OtherInfo:
    *
  • FAIL *
  • PEND *
  • EXTENDED *
*/ public Type getType() { return type; } /** * If type == FAIL, returns the failInfo field. Otherwise, * returns null. */ public INTEGER getFailInfo() { return failInfo; } /** * If type == PEND, returns the pendInfo field. Otherwise, * returns null. */ public PendInfo getPendInfo() { return pendInfo; } /** * If type == EXTENDED, returns the extendedFailInfo field. Otherwise, * returns null. */ public ExtendedFailInfo getExtendedFailInfo() { return extendedFailInfo; } /////////////////////////////////////////////////////////////////////// // DER decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { // return the subType's tag if( type == FAIL ) { return INTEGER.TAG; } else if( type == PEND ){ return PendInfo.TAG; } else { Assert._assert( type == EXTENDED ); return ExtendedFailInfo.TAG; } } public void encode(OutputStream ostream) throws IOException { if( type == FAIL ) { failInfo.encode(ostream); } else if( type == PEND ){ pendInfo.encode(ostream); } else { Assert._assert( type == EXTENDED ); extendedFailInfo.encode(ostream); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged " +implicitTag.getNum()); encode(ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a OtherInfo. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( INTEGER.getTemplate() ); choicet.addElement( PendInfo.getTemplate() ); choicet.addElement( ExtendedFailInfo.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE c = (CHOICE) choicet.decode(istream); if( c.getTag().equals(INTEGER.TAG) ) { return new OtherInfo(FAIL, (INTEGER) c.getValue() , null, null); } else if( c.getTag().equals(PendInfo.TAG) ) { return new OtherInfo(PEND, null, (PendInfo) c.getValue(), null); } else { Assert._assert( c.getTag().equals(ExtendedFailInfo.TAG) ); return new OtherInfo(EXTENDED, null, null, (ExtendedFailInfo) c.getValue()); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged"); return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/OtherMsg.java000066400000000000000000000076631326145000000222700ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMC OtherMsg. *
 * The definition of OtherMsg comes from RFC 2797.
 * OtherMsg ::= SEQUENCE {
 *      bodyPartID      BodyPartID,
 *      otherMsgType    Object Identifier,
 *      otherMsgValue   ANY defined by otherMsgType}
 * 
*/ public class OtherMsg implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private INTEGER bodyPartID; private OBJECT_IDENTIFIER otherMsgType; private ANY otherMsgValue; private SEQUENCE sequence; /** * Returns the bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } /** * Returns the otherMsgType field. */ public OBJECT_IDENTIFIER getOtherMsgType() { return otherMsgType; } /** * Returns the otherMsgValue field. */ public ANY getOtherMsgValue() { return otherMsgValue; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private OtherMsg() { } /** * Constructs a new OtherMsg from its components. */ public OtherMsg(INTEGER bodyPartID, OBJECT_IDENTIFIER otherMsgType, ANY otherMsgValue) { if (bodyPartID == null || otherMsgType == null || otherMsgValue == null) { throw new IllegalArgumentException( "parameter to OtherMsg constructor is null"); } sequence = new SEQUENCE(); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.otherMsgType = otherMsgType; sequence.addElement(otherMsgType); this.otherMsgValue = otherMsgValue; sequence.addElement(otherMsgValue); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a OtherMsg. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(OBJECT_IDENTIFIER.getTemplate()); seqt.addElement(ANY.getTemplate()); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new OtherMsg((INTEGER)seq.elementAt(0), (OBJECT_IDENTIFIER)seq.elementAt(1), (ANY)seq.elementAt(2)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/OtherReqMsg.java000066400000000000000000000132141326145000000227250ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 2004 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMC OtherReqMsg. *
 * OtherReqMsg is to be used by the "orm" field of the TaggedRequest per
 *     definition in RFC 5272.
 *
 * OtherReqMsg ::= SEQUENCE {
 *      bodyPartID      BodyPartID,
 *      requestMessageType    Object Identifier,
 *      requestMessageValue   ANY defined by requestMessageType}
 * 
* * @author Christina Fu (cfu) */ public class OtherReqMsg implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private INTEGER bodyPartID; private OBJECT_IDENTIFIER requestMessageType; private ANY requestMessageValue; private SEQUENCE sequence; /** * Returns the bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } /** * Returns the requestMessageType field. */ public OBJECT_IDENTIFIER getOtherReqMsgType() { return requestMessageType; } /** * Returns the requestMessageValue field. */ public ANY getOtherReqMsgValue() { return requestMessageValue; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private OtherReqMsg() { } /** * Constructs a new OtherReqMsg from its components. */ public OtherReqMsg(INTEGER bodyPartID, OBJECT_IDENTIFIER requestMessageType, ANY requestMessageValue) { if (bodyPartID == null || requestMessageType == null || requestMessageValue == null) { throw new IllegalArgumentException( "parameter to OtherReqMsg constructor is null"); } sequence = new SEQUENCE(); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.requestMessageType = requestMessageType; sequence.addElement(requestMessageType); this.requestMessageValue = requestMessageValue; sequence.addElement(requestMessageValue); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a OtherReqMsg. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(OBJECT_IDENTIFIER.getTemplate()); seqt.addElement(ANY.getTemplate()); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new OtherReqMsg((INTEGER)seq.elementAt(0), (OBJECT_IDENTIFIER)seq.elementAt(1), (ANY)seq.elementAt(2)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/PKIData.java000066400000000000000000000112701326145000000217420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.Assert; /** * A PKIData for CMC full enrollment request. * PKIData ::= SEQUENCE { * controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute, * reqSequence SEQUENCE SIZE(0..MAX) OF TaggedRequest, * cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, * otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg * } */ public class PKIData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private SEQUENCE controlSequence; private SEQUENCE reqSequence; private SEQUENCE cmsSequence; private SEQUENCE otherMsgSequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// // no default constructor private PKIData() { } /** * Constructs a PKIData from its components. * * @param controlSequence Sequence of TagggedAttribute. * @param reqSequence Sequence of TagggedRequest. * @param cmsSequence Sequence of TagggedContentInfo. * @param otherMsgSequence Sequence of OtherMsg. */ public PKIData(SEQUENCE controlSequence, SEQUENCE reqSequence, SEQUENCE cmsSequence, SEQUENCE otherMsgSequence) { sequence = new SEQUENCE(); this.controlSequence = controlSequence; sequence.addElement(controlSequence); this.reqSequence = reqSequence; sequence.addElement(reqSequence); this.cmsSequence = cmsSequence; sequence.addElement(cmsSequence); this.otherMsgSequence = otherMsgSequence; sequence.addElement(otherMsgSequence); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public SEQUENCE getControlSequence() { return controlSequence; } public SEQUENCE getReqSequence() { return reqSequence; } public SEQUENCE getCmsSequence() { return cmsSequence; } public SEQUENCE getOtherMsgSequence() { return otherMsgSequence; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// static Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an PKIData from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new SEQUENCE.OF_Template(TaggedAttribute.getTemplate()) ); seqt.addElement( new SEQUENCE.OF_Template(TaggedRequest.getTemplate()) ); seqt.addElement( new SEQUENCE.OF_Template(new ANY.Template()) ); seqt.addElement( new SEQUENCE.OF_Template(new ANY.Template()) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 4); return new PKIData( (SEQUENCE) seq.elementAt(0), (SEQUENCE) seq.elementAt(1), (SEQUENCE) seq.elementAt(2), (SEQUENCE) seq.elementAt(3)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/PendInfo.java000066400000000000000000000100321326145000000222220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.util.Assert; import java.util.Date; /** * CMC PendInfo: *
 *   PendInfo ::= SEQUENCE { 
 *       pendToken            OCTET STRING, 
 *       pendTime             GeneralizedTime 
 *   } 
 * 
*/ public class PendInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private OCTET_STRING pendToken; private GeneralizedTime pendTime; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// // no default constructor private PendInfo() { } /** * Constructs a PendInfo from its components. * * @param pendToken the identifier. * @param pendTime the suggested time for the client to query the status. */ public PendInfo(OCTET_STRING pendToken, GeneralizedTime pendTime) { sequence = new SEQUENCE(); this.pendToken = pendToken; sequence.addElement(pendToken); this.pendTime = pendTime; sequence.addElement(pendTime); } /** * Constructs a PendInfo from requestId and date. * * @param reqId the request Id * @param date the suggested time for the client to query the status. */ public PendInfo(String reqId, Date date) { sequence = new SEQUENCE(); this.pendToken = new OCTET_STRING(reqId.getBytes()); sequence.addElement(new OCTET_STRING(reqId.getBytes())); this.pendTime = new GeneralizedTime(date); sequence.addElement(new GeneralizedTime(date)); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public GeneralizedTime getPendTime() { return pendTime; } public OCTET_STRING getPendToken() { return pendToken; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an PendInfo from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OCTET_STRING.getTemplate() ); seqt.addElement( GeneralizedTime.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 2); return new PendInfo( (OCTET_STRING) seq.elementAt(0), (GeneralizedTime) seq.elementAt(1)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/PopLinkWitnessV2.java000066400000000000000000000127011326145000000236660ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; /** * CMC PopLinkWitnessV2: * per rfc 5272 *
 *     PopLinkWitnessV2 ::= SEQUENCE {
 *         keyGenAlgorithm     AlgorithmIdentifier,
 *         macAlgorithm       AlgorithmIdentifier,
 *         witness        OCTET STRING
 *     }
 * 
* * @author Christina Fu (cfu) */ public class PopLinkWitnessV2 implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private AlgorithmIdentifier keyGenAlgorithm; private AlgorithmIdentifier macAlgorithm; private OCTET_STRING witness; private SEQUENCE sequence; // for DER encoding public AlgorithmIdentifier getKeyGenAlgorithm() { return keyGenAlgorithm; } public AlgorithmIdentifier getMacAlgorithm() { return macAlgorithm; } public OCTET_STRING getWitness() { return witness; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private PopLinkWitnessV2() { } public PopLinkWitnessV2( AlgorithmIdentifier keyGenAlgorithm, AlgorithmIdentifier macAlgorithm, OCTET_STRING witness) { if( keyGenAlgorithm==null || macAlgorithm==null || witness==null ) { throw new IllegalArgumentException("PopLinkWitnessV2 constructor" +" parameter is null"); } this.keyGenAlgorithm = keyGenAlgorithm; this.macAlgorithm = macAlgorithm; this.witness = witness; sequence = new SEQUENCE(); sequence.addElement(keyGenAlgorithm); sequence.addElement(macAlgorithm); sequence.addElement(witness); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding BER-encoded PopLinkWitnessV2 items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new PopLinkWitnessV2( (AlgorithmIdentifier) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/ResponseBody.java000066400000000000000000000103701326145000000231410ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.Assert; /** * A ResponseBody for CMC full enrollment request. * ResponseBody ::= SEQUENCE { * controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute, * cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, * otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg * } */ public class ResponseBody implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private SEQUENCE controlSequence; private SEQUENCE cmsSequence; private SEQUENCE otherMsgSequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// // no default constructor private ResponseBody() { } /** * Constructs a ResponseBody from its components. * * @param controlSequence Sequence of TagggedAttribute. * @param cmsSequence Sequence of TagggedContentInfo. * @param otherMsgSequence Sequence of OtherMsg. */ public ResponseBody(SEQUENCE controlSequence, SEQUENCE cmsSequence, SEQUENCE otherMsgSequence) { sequence = new SEQUENCE(); this.controlSequence = controlSequence; sequence.addElement(controlSequence); this.cmsSequence = cmsSequence; sequence.addElement(cmsSequence); this.otherMsgSequence = otherMsgSequence; sequence.addElement(otherMsgSequence); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public SEQUENCE getControlSequence() { return controlSequence; } public SEQUENCE getCmsSequence() { return cmsSequence; } public SEQUENCE getOtherMsgSequence() { return otherMsgSequence; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// static Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an ResponseBody from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new SEQUENCE.OF_Template(TaggedAttribute.getTemplate()) ); seqt.addElement(new SEQUENCE.OF_Template(ANY.getTemplate()) ); seqt.addElement(new SEQUENCE.OF_Template(ANY.getTemplate()) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 3); return new ResponseBody( (SEQUENCE) seq.elementAt(0), (SEQUENCE) seq.elementAt(1), (SEQUENCE) seq.elementAt(2)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/RevokeRequest.java000066400000000000000000000262731326145000000233420ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMC RevokeRequest. *
 * RevokeRequest ::= SEQUENCE {
 *      issuerName      Name,
 *      serialNumber    INTEGER,
 *      reason          CRLReason,
 *      invalidityDate  GeneralizedTime OPTIONAL,
 *      passphrase    OCTET STRING OPTIONAL,
 *      comment         UTF8String OPTIONAL }
 * 
* * For maintenance and conformance reasons, this code is brought over * and mildly updated and renamed from cmmf/RevRequest during the process * of CMC update to rfc 5272 * @author Christina Fu (cfu) */ public class RevokeRequest implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Constants /////////////////////////////////////////////////////////////////////// /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED unspecified = new ENUMERATED(0); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED keyCompromise = new ENUMERATED(1); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cACompromise = new ENUMERATED(2); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED affiliationChanged = new ENUMERATED(3); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED superseded = new ENUMERATED(4); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cessationOfOperation = new ENUMERATED(5); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED certificateHold = new ENUMERATED(6); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED removeFromCRL = new ENUMERATED(8); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED privilegeWithdrawn = new ENUMERATED(9); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED aACompromise = new ENUMERATED(10); /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private ANY issuerName; private INTEGER serialNumber; private ENUMERATED reason; private GeneralizedTime invalidityDate; // may be null private OCTET_STRING passphrase; // may be null private UTF8String comment; // may be null private SEQUENCE sequence; /** * Returns the issuerName field as an ANY. */ public ANY getIssuerName() { return issuerName; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /** * Returns the reason field, which should indicate the * reason for the revocation. The currently supported reasons are: *
     * CRLReason ::= ENUMERATED {
     *      unspecified             (0),
     *      keyCompromise           (1),
     *      cACompromise            (2),
     *      affiliationChanged      (3),
     *      superseded              (4),
     *      cessationOfOperation    (5),
     *      certificateHold         (6),
     *      removeFromCRL           (8),
     *      privilegeWithdrawn      (9),
     *      aACompromise            (10) }
     * 
* These are all defined as constants in this class. */ public ENUMERATED getReason() { return reason; } /** * Returns the invalidityDate field. Returns null * if the field is not present. */ public GeneralizedTime getInvalidityDate() { return invalidityDate; } /** * Returns the passphrase field. Returns * null if the field is not present. */ public OCTET_STRING getSharedSecret() { return passphrase; } /** * Returns the comment field. Returns null * if the field is not present. */ public UTF8String getComment() { return comment; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private RevokeRequest() { } /** * Constructs a new RevokeRequest from its components, * omitting the invalidityDate field. * * @deprecated This constructor is obsolete now that * invalidityDate has been added to the class. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason field. The constants defined * in this class may be used. * @param passphrase The passphrase field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null may be used. */ public RevokeRequest(ANY issuerName, INTEGER serialNumber, ENUMERATED reason, OCTET_STRING passphrase, UTF8String comment) { this(issuerName, serialNumber, reason, null, passphrase, comment); } /** * Constructs a new RevokeRequest from its components. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason field. The constants defined * in this class may be used. * @param invalidityDate The suggested value for the Invalidity Date * CRL extension. This field is optional, so null may be * used. * @param passphrase The passphrase field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null may be used. */ public RevokeRequest(ANY issuerName, INTEGER serialNumber, ENUMERATED reason, GeneralizedTime invalidityDate, OCTET_STRING passphrase, UTF8String comment) { if( issuerName==null || serialNumber==null || reason==null ) { throw new IllegalArgumentException( "parameter to RevokeRequest constructor is null"); } sequence = new SEQUENCE(); this.issuerName = issuerName; sequence.addElement(issuerName); this.serialNumber = serialNumber; sequence.addElement(serialNumber); this.reason = reason; sequence.addElement(reason); this.invalidityDate = invalidityDate; sequence.addElement(invalidityDate); this.passphrase = passphrase; sequence.addElement(passphrase); this.comment = comment; sequence.addElement(comment); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * A Template class for decoding a RevokeRequest. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(ANY.getTemplate()); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(ENUMERATED.getTemplate()); seqt.addOptionalElement(GeneralizedTime.getTemplate()); seqt.addOptionalElement(OCTET_STRING.getTemplate()); seqt.addOptionalElement(UTF8String.getTemplate()); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new RevokeRequest( (ANY) seq.elementAt(0), (INTEGER) seq.elementAt(1), (ENUMERATED) seq.elementAt(2), (GeneralizedTime) seq.elementAt(3), (OCTET_STRING) seq.elementAt(4), (UTF8String) seq.elementAt(5) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/TaggedAttribute.java000066400000000000000000000106631326145000000236110ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; /** * A tagged attribute, which has the following ASN.1 * definition : *
 *   TaggedAttribute ::= SEQUENCE {
 *      bodyPartID         BodyPartId, 
 *      attrType           OBJECT IDENTIFIER, 
 *      attrValues         SET OF AttributeValue 
 *   bodyIdMax INTEGER ::= 4294967295
 *
 *   BodyPartID ::= INTEGER(0..bodyIdMax)
 * 
*/ public class TaggedAttribute implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private INTEGER bodyPartID; private OBJECT_IDENTIFIER type; private SET values; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// private TaggedAttribute() { } public TaggedAttribute(INTEGER bodyPartID, OBJECT_IDENTIFIER type, SET values) { sequence = new SEQUENCE(); Assert._assert(bodyPartID.compareTo(BODYIDMAX) <= 0); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.type = type; sequence.addElement(type); this.values = values; sequence.addElement(values); } public TaggedAttribute(INTEGER bodyPartID, OBJECT_IDENTIFIER type, ASN1Value value) { sequence = new SEQUENCE(); Assert._assert(bodyPartID.compareTo(BODYIDMAX) <= 0); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.type = type; sequence.addElement(type); this.values = new SET(); values.addElement(value); sequence.addElement(values); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public INTEGER getBodyPartID() { return bodyPartID; } public OBJECT_IDENTIFIER getType() { return type; } /** * If this AVA was constructed, returns the SET of ASN1Values passed to the * constructor. If this Attribute was decoded with an Attribute.Template, * returns a SET of ANYs. */ public SET getValues() { return values; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { sequence.encode(implicit, ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding an Attribute. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( new OBJECT_IDENTIFIER.Template() ); seqt.addElement( new SET.OF_Template(new ANY.Template())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this Assert._assert(seq.size() == 3); return new TaggedAttribute( (INTEGER) seq.elementAt(0), (OBJECT_IDENTIFIER) seq.elementAt(1), (SET) seq.elementAt(2)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/TaggedCertificationRequest.java000066400000000000000000000077331326145000000260060ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.util.Assert; import org.mozilla.jss.pkcs10.*; /** * CMC TaggedCertificationRequest: *
 *   TaggedCertificationRequest ::= SEQUENCE { 
 *       bodyPartID            BodyPartID, 
 *       certificationRequest  CertificationRequest 
 *   } 
 *   bodyIdMax INTEGER ::= 4294967295
 *
 *   BodyPartID ::= INTEGER(0..bodyIdMax)
 * 
*/ public class TaggedCertificationRequest implements ASN1Value { public static final INTEGER BODYIDMAX = new INTEGER("4294967295"); /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private SEQUENCE sequence; private INTEGER bodyPartID; private CertificationRequest certificationRequest; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// // no default constructor private TaggedCertificationRequest() { } /** * Constructs a TaggedCertificationRequest from its components. * * @param bodyPartID the identifier. * @param certificationRequest the pkcs10 request. */ public TaggedCertificationRequest(INTEGER bodyPartID, CertificationRequest certificationRequest) { sequence = new SEQUENCE(); Assert._assert(bodyPartID.compareTo(BODYIDMAX) <= 0); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.certificationRequest = certificationRequest; sequence.addElement(certificationRequest); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public CertificationRequest getCertificationRequest() { return certificationRequest; } public INTEGER getBodyPartID() { return bodyPartID; } /////////////////////////////////////////////////////////////////////// // DER encoding/decoding /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding an TaggedCertificationRequest from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( CertificationRequest.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 2); return new TaggedCertificationRequest( (INTEGER) seq.elementAt(0), (CertificationRequest) seq.elementAt(1)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/TaggedContentInfo.java000066400000000000000000000070561326145000000240760ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.pkix.cms.*; /** * CMC TaggedContentInfo. *
 * The definition of TaggedContentInfo comes from RFC 2797 Section 3.6.
 * TaggedContentInfo ::= SEQUENCE {
 *      bodyPartID      BodyPartID,
 *      contentInfo     ContentInfo}
 * 
*/ public class TaggedContentInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private INTEGER bodyPartID; private ContentInfo contentInfo; private SEQUENCE sequence; /** * Returns the bodyPartID field. */ public INTEGER getBodyPartID() { return bodyPartID; } /** * Returns the contentInfo field. */ public ContentInfo getContentInfo() { return contentInfo; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private TaggedContentInfo() { } /** * Constructs a new TaggedContentInfo from its components. */ public TaggedContentInfo(INTEGER bodyPartID, ContentInfo contentInfo) { if (bodyPartID == null || contentInfo == null) { throw new IllegalArgumentException( "parameter to TaggedContentInfo constructor is null"); } sequence = new SEQUENCE(); this.bodyPartID = bodyPartID; sequence.addElement(bodyPartID); this.contentInfo = contentInfo; sequence.addElement(contentInfo); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a TaggedContentInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(ContentInfo.getTemplate()); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new TaggedContentInfo((INTEGER)seq.elementAt(0), (ContentInfo)seq.elementAt(1)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/TaggedRequest.java000066400000000000000000000171641326145000000233010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmc; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.crmf.*; import java.io.*; import org.mozilla.jss.util.Assert; /** * CMC TaggedRequest: *
 *   TaggedRequest ::= CHOICE { 
 *       tcr               [0] TaggedCertificationRequest, 
 *       crm               [1] CertReqMsg 
 *       orm               [2] SEQUENCE {
 *            bodyPartID            BodyPartID,
 *            requestMessageType    OBJECT IDENTIFIER,
 *            requestMessageValue   ANY DEFINED BY requestMessageType
 *       } // added for rfc 5272; defined in OtherReqMsg
 *   } 
 * 
*/ public class TaggedRequest implements ASN1Value { /** * The type of TaggedRequest. */ public static class Type { private Type() { } static Type PKCS10 = new Type(); static Type CRMF = new Type(); static Type OTHER = new Type(); } public static Type PKCS10 = Type.PKCS10; public static Type CRMF = Type.CRMF; public static Type OTHER = Type.OTHER; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private Type type; private TaggedCertificationRequest tcr; // if type == PKCS10 private CertReqMsg crm; // if type == CRMF private OtherReqMsg orm; // if type == OTHER /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// // no default constructor public TaggedRequest() { } /** * Constructs a TaggedRequest from its components. * kept for backward compatibility for now * @param type The type of the request. * @param tcr Tagged pkcs10 request. * @param crm CRMF request. */ public TaggedRequest(Type type, TaggedCertificationRequest tcr, CertReqMsg crm) { this.type = type; this.tcr = tcr; this.crm = crm; } /** * Constructs a TaggedRequest from its components. * rfc 5272 * @param type The type of the request. * @param tcr Tagged pkcs10 request. * @param crm CRMF request. * @param orm OTHER request. */ public TaggedRequest(Type type, TaggedCertificationRequest tcr, CertReqMsg crm, OtherReqMsg orm) { this.type = type; this.tcr = tcr; this.crm = crm; this.orm = orm; } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// /** * Returns the type of TaggedRequest:
    *
  • PKCS10 *
  • CRMF *
  • OTHER *
*/ public Type getType() { return type; } /** * If type == PKCS10, returns the tcr field. Otherwise, * returns null. */ public TaggedCertificationRequest getTcr() { return tcr; } /** * If type == CRMF, returns the crm field. Otherwise, * returns null. */ public CertReqMsg getCrm() { return crm; } /** * If type == OTHER, returns the orm field. Otherwise, * returns null. */ public OtherReqMsg getOrm() { return orm; } /////////////////////////////////////////////////////////////////////// // DER decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if( type == PKCS10 ) { return Tag.get(0); } else if( type == CRMF ){ return Tag.get(1); } else { Assert._assert( type == OTHER ); return Tag.get(2); } } public void encode(OutputStream ostream) throws IOException { if( type == PKCS10 ) { tcr.encode(Tag.get(0), ostream); // a CHOICE must be explicitly tagged //EXPLICIT e = new EXPLICIT( Tag.get(0), tcr ); //e.encode(ostream); } else if( type == CRMF ) { crm.encode(Tag.get(1), ostream); // a CHOICE must be explicitly tagged //EXPLICIT e = new EXPLICIT( Tag.get(1), crm ); //e.encode(ostream); } else { Assert._assert( type == OTHER ); orm.encode(Tag.get(2), ostream); // a CHOICE must be explicitly tagged //EXPLICIT e = new EXPLICIT( Tag.get(2), orm ); //e.encode(ostream); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged " +implicitTag.getNum()); //tagAt() of SET.java actually returns the underlying type encode(ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a ProofOfPossession. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); //EXPLICIT.Template et = new EXPLICIT.Template( // Tag.get(0), TaggedCertificationRequest.getTemplate() ); //choicet.addElement( et ); choicet.addElement( Tag.get(0), TaggedCertificationRequest.getTemplate() ); //et = new EXPLICIT.Template( // Tag.get(1), CertReqMsg.getTemplate() ); //choicet.addElement( et ); choicet.addElement( Tag.get(1), CertReqMsg.getTemplate() ); //et = new EXPLICIT.Template( // Tag.get(2), CertReqMsg.getTemplate() ); //choicet.addElement( et ); choicet.addElement( Tag.get(2), OtherReqMsg.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE c = (CHOICE) choicet.decode(istream); if( c.getTag().equals(Tag.get(0)) ) { //EXPLICIT e = (EXPLICIT) c.getValue(); //return new TaggedRequest(PKCS10, // (TaggedCertificationRequest) // e.getContent(), null ); return new TaggedRequest(PKCS10, (TaggedCertificationRequest) c.getValue() , null); } if( c.getTag().equals(Tag.get(1)) ) { //EXPLICIT e = (EXPLICIT) c.getValue(); //return new TaggedRequest(CRMF, // (CertReqMsg) // e.getContent(), null ); return new TaggedRequest(CRMF, null, (CertReqMsg) c.getValue() , null); } else { Assert._assert( c.getTag().equals(Tag.get(2)) ); //EXPLICIT e = (EXPLICIT) c.getValue(); //return new TaggedRequest(OTHER, null, // (CertReqMsg) e.getContent() ); return new TaggedRequest(OTHER, null, null, (OtherReqMsg) c.getValue()); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged"); return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmc/package.html000066400000000000000000000004261326145000000221440ustar00rootroot00000000000000 Creating and interpeting CMC blobs. jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/000077500000000000000000000000001326145000000200415ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/CertOrEncCert.java000066400000000000000000000027031326145000000233500ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; import java.io.ByteArrayOutputStream; public class CertOrEncCert implements ASN1Value { private ANY certificate; byte[] encoding; /** * @exception InvalidBERException If the certificate is not a valid * BER-encoding. */ public CertOrEncCert(byte[] encodedCert) throws IOException, InvalidBERException { certificate = new ANY( new Tag(0), encodedCert ); ByteArrayOutputStream bos = new ByteArrayOutputStream(); certificate.encodeWithAlternateTag(new Tag(0), bos); encoding = bos.toByteArray(); } public static final Tag TAG = new Tag(0); public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { ostream.write(encoding); } /** * @param implicitTag This parameter is ignored, because a CHOICE * cannot have an implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { Assert._assert( implicitTag.equals(TAG) ); ostream.write(encoding); } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/CertRepContent.java000066400000000000000000000111231326145000000236010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.FileOutputStream; import java.io.ByteArrayInputStream; import java.io.FileInputStream; /** * A CMMF CertRepContent. *
 * CertRepContent ::= SEQUENCE {
 *      caPubs      [1] SEQUENCE SIZE (1..MAX) OF Certificate OPTIONAL,
 *      response    SEQUENCE of CertResponse }
 * 
* @see org.mozilla.jss.pkix.cmmf.CertResponse */ public class CertRepContent implements ASN1Value { private byte[][] caPubs; // may be null private SEQUENCE response; private CertRepContent() { } /** * Creates a new CertRepContent. * * @param caPubs An array of DER-encoded X.509 Certificates. It may be * null if the caPubs field is to be omitted. * @param response A SEQUENCE of CertResponse objects. * Must not be null. */ public CertRepContent(byte[][] caPubs, SEQUENCE response) { this.caPubs = caPubs; this.response = response; } /** * Creates a new CertRepContent. The responses can be * added later with addCertResponse. * * @param caPubs An array of DER-encoded X.509 Certificates, must not * be null and must have at least one element. */ public CertRepContent(byte[][] caPubs) { this.caPubs = caPubs; response = new SEQUENCE(); } /** * Creates a new CertRepContent * * @param response A SEQUENCE of CertResponse objects. * Must not be null. */ public CertRepContent(SEQUENCE response) { this.caPubs = null; this.response = response; } /** * Adds another CertResponse. */ public void addCertResponse(CertResponse resp) { response.addElement(resp); } /** * Returns the caPubs field, which is an array of * DER-encoded X.509 Certificates. May return null if the * field is not present. */ public byte[][] getCaPubs() { return caPubs; } /** * Returns the response field, which is a SEQUENCE * of CertResponse */ public SEQUENCE getResponse() { return response; } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE encoding = new SEQUENCE(); // create sequence of certificates if(caPubs != null) { SEQUENCE certs = new SEQUENCE(); for(int i = 0; i < caPubs.length; i++) { certs.addElement( new ANY( SEQUENCE.TAG, caPubs[i] ) ); } encoding.addElement( new Tag(1), certs ); } encoding.addElement( response ); encoding.encode(implicitTag, ostream); } public static void main(String argv[]) { try { if(argv.length != 2) { System.out.println("Usage: CertRepContent "); System.out.println("certfile should contain a DER-encoded X.509 "+ "certificate"); System.exit(-1); } FileInputStream certfile = new FileInputStream(argv[0]); FileOutputStream fos = new FileOutputStream(argv[1]); byte[][] certs = new byte[2][]; certs[0] = new byte[ certfile.available() ]; certfile.read(certs[0]); certs[1] = certs[0]; PKIStatusInfo status = new PKIStatusInfo(PKIStatusInfo.rejection, PKIStatusInfo.badRequest | PKIStatusInfo.badTime ); status.addFreeText("And your mother dresses you funny"); status.addFreeText("so there"); CertifiedKeyPair ckp = new CertifiedKeyPair( new CertOrEncCert( certs[0] ) ); CertResponse resp = new CertResponse( new INTEGER(54), status, ckp); CertRepContent content = new CertRepContent(certs); content.addCertResponse(resp); content.encode(fos); System.out.println("Success!"); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/CertResponse.java000066400000000000000000000040651326145000000233250ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; public class CertResponse implements ASN1Value { private INTEGER certReqId; private PKIStatusInfo status; private CertifiedKeyPair certifiedKeyPair; private CertResponse() { } public CertResponse(INTEGER certReqId, PKIStatusInfo status) { this.certReqId = certReqId; this.status = status; } public CertResponse(INTEGER certReqId, PKIStatusInfo status, CertifiedKeyPair certifiedKeyPair) { this(certReqId, status); this.certifiedKeyPair = certifiedKeyPair; } public INTEGER getCertReqId() { return certReqId; } public PKIStatusInfo getPKIStatusInfo() { return status; } /** * Returns true if the certifiedKeyPair field is present. */ public boolean hasCertifiedKeyPair() { return (certifiedKeyPair != null); } /** * Returns the optional certified key pair. Should only be called if * the certifiedKeyPair field is present. */ public CertifiedKeyPair getCertifiedKeyPair() { Assert._assert(certifiedKeyPair!=null); return certifiedKeyPair; } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement( certReqId ); seq.addElement( status ); if( certifiedKeyPair != null ) { seq.addElement( certifiedKeyPair ); } seq.encode(implicitTag, ostream); } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/CertifiedKeyPair.java000066400000000000000000000017521326145000000240740ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; public class CertifiedKeyPair implements ASN1Value { private CertOrEncCert certOrEncCert; public CertifiedKeyPair(CertOrEncCert certOrEncCert) { this.certOrEncCert = certOrEncCert; } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement( certOrEncCert ); seq.encode(implicitTag, ostream); } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/GetCRL.java000066400000000000000000000137271326145000000217760ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMMF GetCRL. *
 * GetCRL ::= SEQUENCE {
 *      issuerName      Name,
 *      cRLName         GeneralName OPTIONAL,
 *      time            GeneralizedTime OPTIONAL,
 *      reasons         ReasonFlags OPTIONAL }
 * 
*/ public class GetCRL implements ASN1Value { /////////////////////////////////////////////////////////////////////// // constants /////////////////////////////////////////////////////////////////////// /** * A bit position in a ReasonFlags bit string. */ public static final int unused = 0; /** * A bit position in a ReasonFlags bit string. */ public static final int keyCompromise = 1; /** * A bit position in a ReasonFlags bit string. */ public static final int cACompromise = 2; /** * A bit position in a ReasonFlags bit string. */ public static final int affiliationChanged = 3; /** * A bit position in a ReasonFlags bit string. */ public static final int superseded = 4; /** * A bit position in a ReasonFlags bit string. */ public static final int cessationOfOperation = 5; /** * A bit position in a ReasonFlags bit string. */ public static final int certificateHold = 6; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private ANY issuerName; private ANY cRLName; // may be null private GeneralizedTime time; // may be null private BIT_STRING reasons; // may be null private SEQUENCE sequence; /** * Returns the issuerName field. */ public ANY getIssuerName() { return issuerName; } /** * Returns the cRLName field, which may be null. */ public ANY getCRLName() { return cRLName; } /** * Returns the time field, which may be null. */ public GeneralizedTime getTime() { return time; } /** * Returns the reasons field, which may be null. */ public BIT_STRING getReasons() { return reasons; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private GetCRL() { } /** * Constructs a GetCRL from its components. * * @param issuerName The issuer name of the CRL. This should be an ASN.1 * Name. * @param cRLName The name of the CRL, which may be null. * This should be an ASN.1 GeneralName. * @param time The time of the CRL, which may be null. * @param reasons Can be used to specify from among CRLs partitioned * by revocation reason. The BIT_STRING can be created from a * Java BitSet. The positions in the BitSet should be set or cleared * using the constants provided in this class. */ public GetCRL( ANY issuerName, ANY cRLName, GeneralizedTime time, BIT_STRING reasons ) { if( issuerName == null ) { throw new IllegalArgumentException( "issuerName parameter to GetCRL constructor is null"); } sequence = new SEQUENCE(); this.issuerName = issuerName; sequence.addElement(issuerName); this.cRLName = cRLName; sequence.addElement(cRLName); this.time = time; sequence.addElement(time); // Remove trailing zeroes in this bit string because it contains // flags. this.reasons = reasons; reasons.setRemoveTrailingZeroes(true); sequence.addElement(reasons); } /////////////////////////////////////////////////////////////////////// // encoding / decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a GetCRL. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addOptionalElement( ANY.getTemplate() ); seqt.addOptionalElement( GeneralizedTime.getTemplate() ); seqt.addOptionalElement( BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new GetCRL( (ANY) seq.elementAt(0), (ANY) seq.elementAt(1), (GeneralizedTime) seq.elementAt(2), (BIT_STRING) seq.elementAt(3) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/IssuerAndSubject.java000066400000000000000000000072761326145000000241350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMMF IssuerAndSubject. *
 * IssuerAndSubject ::= SEQUENCE {
 *      issuer          Name,
 *      subject         Name,
 *      certReqId       INTEGER OPTIONAL }
 * 
*/ public class IssuerAndSubject implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private ANY issuer; private ANY subject; private INTEGER certReqId; // may be null private SEQUENCE sequence; /** * Returns the issuer field. */ public ANY getIssuer() { return issuer; } /** * Returns the subject field. */ public ANY getSubject() { return subject; } /** * Returns the certReqId field, which may be null. */ public INTEGER getCertReqId() { return certReqId; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private IssuerAndSubject() { } public IssuerAndSubject(ANY issuer, ANY subject, INTEGER certReqId) { if( issuer==null || subject==null ) { throw new IllegalArgumentException( "parameter to IssuerAndSubject constructor is null"); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.subject = subject; sequence.addElement(subject); this.certReqId = certReqId; sequence.addElement(certReqId); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding an IssuerAndSubject. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addElement( ANY.getTemplate() ); seqt.addOptionalElement( INTEGER.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new IssuerAndSubject( (ANY) seq.elementAt(0), (ANY) seq.elementAt(1), (INTEGER) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/PKIStatusInfo.java000066400000000000000000000127541326145000000233600ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.util.Assert; import org.mozilla.jss.asn1.*; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.BitSet; public class PKIStatusInfo implements ASN1Value { private INTEGER status; private SEQUENCE statusString; private int failInfo; // bitwise AND private boolean hasFailInfo; // PKIStatus constants public static final int granted = 0; public static final int grantedWithMods = 1; public static final int rejection = 2; public static final int waiting = 3; public static final int revocationWarning = 4; public static final int revocationNotification = 5; public static final int keyUpdateWarning = 6; // PKIFailureInfo constants // The bit string encoded in four bytes, big-endian, bit 0 is MSB. public static final int badAlg = 0x80000000; public static final int badMessageCheck = 0x40000000; public static final int badRequest = 0x20000000; public static final int badTime = 0x10000000; public static final int badCertId = 0x08000000; public static final int badDataFormat = 0x04000000; public static final int wrongAuthority = 0x02000000; public static final int incorrectData = 0x01000000; public static final int missingTimeStamp = 0x00800000; private PKIStatusInfo() { } /** * @param status A PKIStatus constant. * @param failInfo The bitwise AND of the PKIFailureInfo constants. */ public PKIStatusInfo(int status, int failInfo) { this.status = new INTEGER(status); statusString = new SEQUENCE(); this.failInfo = failInfo; hasFailInfo = true; } /** * Create a PKIStatusInfo with no failure info. * @param status A PKIStatus constant. */ public PKIStatusInfo(int status) { this.status = new INTEGER(status); statusString = new SEQUENCE(); hasFailInfo = false; } /** * Sets the statusString field. May be null, since this * field is optional. */ public void setStatusString(SEQUENCE statusString) { this.statusString = statusString; } /** * Adds a string to the statusString SEQUENCE. */ public void addFreeText(String s) { try { statusString.addElement( new UTF8String(s) ); } catch( java.io.CharConversionException e ) { Assert.notReached("Error encoding to UTF8"); } } /** * Adds a UTF8String to the statusString SEQUENCE. */ public void addFreeText(UTF8String s) { statusString.addElement( s ); } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(status); if( statusString.size() > 0 ) { seq.addElement( statusString ); } if(hasFailInfo) { // convert failInfo to BIT_STRING byte[] bytes = new byte[2]; bytes[0] = (byte) ((failInfo & 0xff000000) >>> 24); bytes[1] = (byte) ((failInfo & 0x00ff0000) >>> 16); int padCount = 7; // 7 unused bits BIT_STRING bs = new BIT_STRING(bytes, padCount); bs.setRemoveTrailingZeroes(true); seq.addElement( bs ); } seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addOptionalElement( new SEQUENCE.OF_Template(UTF8String.getTemplate())); seqt.addOptionalElement( BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { PKIStatusInfo psi; SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); BIT_STRING failInfo = (BIT_STRING) seq.elementAt(2); if( failInfo == null ) { psi = new PKIStatusInfo(((INTEGER)seq.elementAt(0)).intValue()); } else { BitSet bs = failInfo.toBitSet(); int failinfo = 0; for(int i = 0, bit = 0x80000000; bit > 0; i++, bit >>>= 1 ) { if( bs.get(i) ) { failinfo |= bit; } } psi = new PKIStatusInfo(((INTEGER)seq.elementAt(0)).intValue(), failinfo); } psi.setStatusString( (SEQUENCE) seq.elementAt(1) ); return psi; } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/RevRepContent.java000066400000000000000000000115011326145000000234400ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.pkix.crmf.CertId; /** * CMMF RevRepContent. *
 * RevRepContent ::= SEQUENCE {
 *    status          SEQUENCE SIZE (1..MAX) OF PKIStatusInfo,
 *      -- in same order as was sent in RevReqContent
 *    revCerts        [0] SEQUENCE SIZE (1..MAX) OF CertId OPTIONAL,
 *      -- IDs for which revocation was requested (same order as status)
 *    crls            [1] SEQUENCE SIZE (1..MAX) OF CertificateList OPTIONAL
 *      -- the resulting CRLs (there may be more than one) }
 * 
*/ public class RevRepContent implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private SEQUENCE status; private SEQUENCE revCerts; // may be null private SEQUENCE crls; // may be null private SEQUENCE sequence; // for encoding /** * The status field, which is a SEQUENCE * of PKIStatusInfo. * * @see org.mozilla.jss.pkix.cmmf.PKIStatusInfo */ public SEQUENCE getStatus() { return status; } /** * The revCerts field, which is a SEQUENCE * of CertId. Returns null if this * field is not present. * * @see org.mozilla.jss.pkix.crmf.CertId */ public SEQUENCE getRevCerts() { return revCerts; } /** * The crls field, which is a SEQUENCE of * ANY. Returns null if this field * is not present. */ public SEQUENCE getCrls() { return crls; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private RevRepContent() { } /** * Creates a new RevRepContent from its components. * * @param status A SEQUENCE of PKIStatusInfo. * @param revCerts A SEQUENCE of CertId. This * field is optional, so null may be used. * @param crls A SEQUENCE of ANY. This field * is optional, so null may be used. * @see org.mozilla.jss.pkix.cmmf.PKIStatusInfo */ public RevRepContent(SEQUENCE status, SEQUENCE revCerts, SEQUENCE crls) { sequence = new SEQUENCE(); this.status = status; sequence.addElement(status); this.revCerts = revCerts; sequence.addElement(Tag.get(0), revCerts); this.crls = crls; sequence.addElement(Tag.get(1), crls); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * A Template for decoding a RevRepContent. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( new SEQUENCE.OF_Template( PKIStatusInfo.getTemplate() ) ); seqt.addOptionalElement( new SEQUENCE.OF_Template( CertId.getTemplate() ) ); seqt.addOptionalElement( new SEQUENCE.OF_Template( ANY.getTemplate() ) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new RevRepContent( (SEQUENCE) seq.elementAt(0), (SEQUENCE) seq.elementAt(1), (SEQUENCE) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/RevRequest.java000066400000000000000000000240301326145000000230100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cmmf; import org.mozilla.jss.asn1.*; import java.io.*; /** * CMMF RevRequest. *
 * RevRequest ::= SEQUENCE {
 *      issuerName      Name,
 *      serialNumber    INTEGER,
 *      reason          CRLReason,
 *      invalidityDate  GeneralizedTime OPTIONAL,
 *      sharedSecret    OCTET STRING OPTIONAL,
 *      comment         UTF8String OPTIONAL }
 * 
* For maintenance and conformance reasons, this code has been brought * over and renamed to cmc/RevokeRequest during the CMC update to rfc 5272. * All new code should use cmc/RevokeRequest instead */ public class RevRequest implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Constants /////////////////////////////////////////////////////////////////////// /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED unspecified = new ENUMERATED(0); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED keyCompromise = new ENUMERATED(1); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cACompromise = new ENUMERATED(2); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED affiliationChanged = new ENUMERATED(3); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED superseded = new ENUMERATED(4); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED cessationOfOperation = new ENUMERATED(5); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED certificateHold = new ENUMERATED(6); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED removeFromCRL = new ENUMERATED(8); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED privilegeWithdrawn = new ENUMERATED(9); /** * A CRLReason, which can be used in the reason * field. */ public static final ENUMERATED aACompromise = new ENUMERATED(10); /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private ANY issuerName; private INTEGER serialNumber; private ENUMERATED reason; private GeneralizedTime invalidityDate; // may be null private OCTET_STRING sharedSecret; // may be null private UTF8String comment; // may be null private SEQUENCE sequence; /** * Returns the issuerName field as an ANY. */ public ANY getIssuerName() { return issuerName; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /** * Returns the reason field, which should indicate the * reason for the revocation. The currently supported reasons are: *
     * CRLReason ::= ENUMERATED {
     *      unspecified             (0),
     *      keyCompromise           (1),
     *      cACompromise            (2),
     *      affiliationChanged      (3),
     *      superseded              (4),
     *      cessationOfOperation    (5),
     *      certificateHold         (6),
     *      removeFromCRL           (8),
     *      privilegeWithdrawn      (9),
     *      aACompromise            (10) }
     * 
* These are all defined as constants in this class. */ public ENUMERATED getReason() { return reason; } /** * Returns the invalidityDate field. Returns null * if the field is not present. */ public GeneralizedTime getInvalidityDate() { return invalidityDate; } /** * Returns the passphrase field. Returns * null if the field is not present. * @deprecated The passphrase field has been renamed * sharedSecret. Call getSharedSecret instead. */ public OCTET_STRING getPassphrase() { return sharedSecret; } /** * Returns the sharedSecret field. Returns * null if the field is not present. */ public OCTET_STRING getSharedSecret() { return sharedSecret; } /** * Returns the comment field. Returns null * if the field is not present. */ public UTF8String getComment() { return comment; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private RevRequest() { } /** * Constructs a new RevRequest from its components, * omitting the invalidityDate field. * * @deprecated This constructor is obsolete now that * invalidityDate has been added to the class. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason field. The constants defined * in this class may be used. * @param sharedSecret The sharedSecret field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null may be used. */ public RevRequest(ANY issuerName, INTEGER serialNumber, ENUMERATED reason, OCTET_STRING sharedSecret, UTF8String comment) { this(issuerName, serialNumber, reason, null, sharedSecret, comment); } /** * Constructs a new RevRequest from its components. * * @param issuerName The issuerName field. * @param serialNumber The serialNumber field. * @param reason The reason field. The constants defined * in this class may be used. * @param invalidityDate The suggested value for the Invalidity Date * CRL extension. This field is optional, so null may be * used. * @param sharedSecret The sharedSecret field. This field is * optional, so null may be used. * @param comment The comment field. This field is optional, * so null may be used. */ public RevRequest(ANY issuerName, INTEGER serialNumber, ENUMERATED reason, GeneralizedTime invalidityDate, OCTET_STRING sharedSecret, UTF8String comment) { if( issuerName==null || serialNumber==null || reason==null ) { throw new IllegalArgumentException( "parameter to RevRequest constructor is null"); } sequence = new SEQUENCE(); this.issuerName = issuerName; sequence.addElement(issuerName); this.serialNumber = serialNumber; sequence.addElement(serialNumber); this.reason = reason; sequence.addElement(reason); this.invalidityDate = invalidityDate; sequence.addElement(invalidityDate); this.sharedSecret = sharedSecret; sequence.addElement(sharedSecret); this.comment = comment; sequence.addElement(comment); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * A Template class for decoding a RevRequest. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(ANY.getTemplate()); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(ENUMERATED.getTemplate()); seqt.addOptionalElement(GeneralizedTime.getTemplate()); seqt.addOptionalElement(OCTET_STRING.getTemplate()); seqt.addOptionalElement(UTF8String.getTemplate()); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new RevRequest( (ANY) seq.elementAt(0), (INTEGER) seq.elementAt(1), (ENUMERATED) seq.elementAt(2), (GeneralizedTime) seq.elementAt(3), (OCTET_STRING) seq.elementAt(4), (UTF8String) seq.elementAt(5) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cmmf/package.html000066400000000000000000000004121326145000000223170ustar00rootroot00000000000000 The PKIX CMMF protocol. jss-4.4.3/jss/org/mozilla/jss/pkix/cms/000077500000000000000000000000001326145000000177015ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkix/cms/ContentInfo.java000066400000000000000000000171671326145000000230060ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; /** * A PKCS #7 ContentInfo structure. */ public class ContentInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; // XXX is this right? public static OBJECT_IDENTIFIER DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 1 }); public static OBJECT_IDENTIFIER SIGNED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 2 }); public static OBJECT_IDENTIFIER ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 3 }); public static OBJECT_IDENTIFIER SIGNED_AND_ENVELOPED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 4 }); public static OBJECT_IDENTIFIER DIGESTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 5 }); public static OBJECT_IDENTIFIER ENCRYPTED_DATA = new OBJECT_IDENTIFIER(new long[] { 1, 2, 840, 113549, 1, 7, 6 }); private OBJECT_IDENTIFIER contentType; private ANY content; private SEQUENCE sequence = new SEQUENCE(); private ContentInfo() {} /** * Creates a ContentInfo with the given type and content. * * @param contentType The contentType of the ContentInfo. * @param content The content of the ContentInfo. May be null * to signify that the optional content field is not present. */ public ContentInfo(OBJECT_IDENTIFIER contentType, ASN1Value content) { this.contentType = contentType; sequence.addElement(contentType); if (content != null) { if( content instanceof ANY ) { this.content = (ANY) content; } else { // convert content to ANY try { this.content = (ANY) ASN1Util.decode(ANY.getTemplate(), ASN1Util.encode(content) ); } catch(InvalidBERException e) { Assert.notReached("InvalidBERException while converting"+ "ASN1Value to ANY"); } } sequence.addElement(new EXPLICIT(new Tag(0),content) ); } } /** * Creates a ContentInfo of type data. */ public ContentInfo(byte[] data) { this( DATA, new OCTET_STRING(data) ); } /** * Creates a ContentInfo of type signedData. */ public ContentInfo(SignedData sd) { this( SIGNED_DATA, sd); } /** * Creates a ContentInfo of type envelopedData. */ public ContentInfo(EnvelopedData ed) { this( ENVELOPED_DATA, ed ); } /** * Creates a ContentInfo of type signedAndEnvelopedData. */ public ContentInfo(SignedAndEnvelopedData sed) { this( SIGNED_AND_ENVELOPED_DATA, sed ); } /** * Creates a ContentInfo of type digestedData. */ public ContentInfo(DigestedData dd) { this( DIGESTED_DATA, dd ); } /** * Creates a ContentInfo of type encryptedData. */ public ContentInfo(EncryptedData ed) { this( ENCRYPTED_DATA, ed ); } /** * Returns the contentType field, which determines what kind of content * is contained in this ContentInfo. It will usually be one of the six * predefined types, but may also be a user-defined type. */ public OBJECT_IDENTIFIER getContentType() { return contentType; } /** * Returns true if the content field is present. */ public boolean hasContent() { return (content != null); } /** * Returns the content, interpreted based on its type. If there is no * content, null is returned. *

If the contentType is * one of the six standard types, the returned object will be of that * type. For example, if the ContentInfo has contentType signedData, * a SignedData object will be returned. If the contentType is data, * an OCTET_STRING will be returned. *

If the contentType is not one of the six standard types, * the returned object will be an ANY. */ public ASN1Value getInterpretedContent() throws InvalidBERException { if(contentType.equals(DATA)) { return content.decodeWith( new OCTET_STRING.Template() ); } else if( contentType.equals(SIGNED_DATA) ) { return content.decodeWith( new SignedData.Template() ); } else if( contentType.equals(ENVELOPED_DATA) ) { return content.decodeWith( new EnvelopedData.Template()); } else if( contentType.equals(SIGNED_AND_ENVELOPED_DATA) ) { return content.decodeWith( new SignedAndEnvelopedData.Template() ); } else if( contentType.equals(DIGESTED_DATA) ) { return content.decodeWith( new DigestedData.Template() ); } else if( contentType.equals(ENCRYPTED_DATA) ) { return content.decodeWith( new EncryptedData.Template()); } else { // unknown type return content; } } /** * Returns the content encoded as an ANY. If there is no content, * null is returned. */ public ANY getContent() { return content; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag,ostream); } public Tag getTag() { return ContentInfo.TAG; } /** * Returns a singleton instance of a decoding template for ContentInfo. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a ContentInfo blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(ContentInfo.TAG)); } private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(0), new ANY.Template() )); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(ContentInfo.TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream ) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() == 2); ASN1Value content; if( seq.elementAt(1) == null ) { content = null; } else { content = ((EXPLICIT)seq.elementAt(1)).getContent(); } return new ContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), content ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/DigestInfo.java000066400000000000000000000065541326145000000226110ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; import org.mozilla.jss.util.Assert; public class DigestInfo implements ASN1Value { private AlgorithmIdentifier digestAlgorithm; private OCTET_STRING digest; private SEQUENCE sequence; private DigestInfo() { } public DigestInfo(AlgorithmIdentifier digestAlgorithm, OCTET_STRING digest){ if( digestAlgorithm==null || digest==null ) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.digestAlgorithm = digestAlgorithm; sequence.addElement(digestAlgorithm); this.digest = digest; sequence.addElement(digest); } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public OCTET_STRING getDigest() { return digest; } private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public boolean equals(Object obj) { if( obj==null || !(obj instanceof DigestInfo)) { return false; } DigestInfo di = (DigestInfo)obj; return byteArraysAreSame(di.digest.toByteArray(), digest.toByteArray()); } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { Assert._assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding the BER encoding of a DigestInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate()); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream ostream) throws InvalidBERException, IOException { return decode(TAG, ostream); } public ASN1Value decode(Tag implicitTag, InputStream ostream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, ostream); return new DigestInfo( (AlgorithmIdentifier) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/DigestedData.java000066400000000000000000000073271326145000000230770ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; public class DigestedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private AlgorithmIdentifier digestAlgorithm; private ContentInfo contentInfo; private OCTET_STRING digest; private SEQUENCE sequence; // for DER encoding public INTEGER getVersion() { return version; } public AlgorithmIdentifier getDigestAlgorithm() { return digestAlgorithm; } public ContentInfo getContentInfo() { return contentInfo; } public OCTET_STRING getDigest() { return digest; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private DigestedData() { } public DigestedData(INTEGER version, AlgorithmIdentifier digestAlgorithm, ContentInfo contentInfo, OCTET_STRING digest) { if( version==null || digestAlgorithm==null || contentInfo==null || digest==null ) { throw new IllegalArgumentException("DigestedData constructor" +" parameter is null"); } this.version = version; this.digestAlgorithm = digestAlgorithm; this.contentInfo = contentInfo; this.digest = digest; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithm); sequence.addElement(contentInfo); sequence.addElement(digest); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * A Template for decoding BER-encoded DigestData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( ContentInfo.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new DigestedData( (INTEGER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (ContentInfo) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/EncapsulatedContentInfo.java000066400000000000000000000104731326145000000253300ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; /** * A CMS EncapsulatedContentInfo structure. */ public class EncapsulatedContentInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; // XXX is this right? private OBJECT_IDENTIFIER contentType; private OCTET_STRING content; private SEQUENCE sequence = new SEQUENCE(); private EncapsulatedContentInfo() {} /** * Creates a EncapsulatedContentInfo with the given type and content. * * @param contentType The contentType of the EncapsulatedContentInfo. * @param content The content of the EncapsulatedContentInfo. May be null * to signify that the optional content field is not present. */ public EncapsulatedContentInfo(OBJECT_IDENTIFIER contentType, ASN1Value content) { this.contentType = contentType; sequence.addElement(contentType); if (content != null) { if( content instanceof OCTET_STRING) { this.content = (OCTET_STRING) content; } else { // convert content to OCTET_STRING this.content = (OCTET_STRING) new OCTET_STRING( ASN1Util.encode(content) ); } sequence.addElement(new EXPLICIT(new Tag(0), this.content) ); } } /** * Returns the contentType field, which determines what kind of content * is contained in this EncapsulatedContentInfo. */ public OBJECT_IDENTIFIER getContentType() { return contentType; } /** * Returns true if the content field is present. */ public boolean hasContent() { return (content != null); } /** * Returns the content encoded as an OCTET_STRING. If there is no content, * null is returned. */ public OCTET_STRING getContent() { return content; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag,ostream); } public Tag getTag() { return EncapsulatedContentInfo.TAG; } /** * Returns a singleton instance of a decoding template for EncapsulatedContentInfo. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a EncapsulatedContentInfo blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(EncapsulatedContentInfo.TAG)); } private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addOptionalElement( new EXPLICIT.Template( new Tag(0), new OCTET_STRING.Template() )); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(EncapsulatedContentInfo.TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream ) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() == 2); ASN1Value content; if( seq.elementAt(1) == null ) { content = null; } else { content = ((EXPLICIT)seq.elementAt(1)).getContent(); } return new EncapsulatedContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), content ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/EncryptedContentInfo.java000066400000000000000000000266161326145000000246630ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import org.mozilla.jss.pkix.primitive.*; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; import org.mozilla.jss.crypto.*; import java.security.*; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.util.Password; import org.mozilla.jss.CryptoManager; /** * The PKCS #7 type EncryptedContentInfo, which encapsulates * encrypted data. */ public class EncryptedContentInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private OBJECT_IDENTIFIER contentType; private AlgorithmIdentifier contentEncryptionAlgorithm; private OCTET_STRING encryptedContent; // may be null private SEQUENCE sequence = new SEQUENCE(); public OBJECT_IDENTIFIER getContentType() { return contentType; } public AlgorithmIdentifier getContentEncryptionAlgorithm() { return contentEncryptionAlgorithm; } public OCTET_STRING getEncryptedContent() { return encryptedContent; } public boolean hasEncryptedContent() { return (encryptedContent!=null); } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private EncryptedContentInfo() { } /** * Create a EnvelopedData ASN1 object. */ public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { this(contentType, contentEncryptionAlgorithm, encryptedContent, false); } public EncryptedContentInfo( OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent, boolean createHackedCRSCompatibleECI) { this.contentType = contentType; this.contentEncryptionAlgorithm = contentEncryptionAlgorithm; this.encryptedContent = encryptedContent; sequence.addElement(contentType); sequence.addElement(contentEncryptionAlgorithm); if(encryptedContent != null) { if (createHackedCRSCompatibleECI) { sequence.addElement(new EXPLICIT(new Tag(0), encryptedContent)); } else { sequence.addElement(new Tag(0), encryptedContent); } } } public static EncryptedContentInfo createCRSCompatibleEncryptedContentInfo(OBJECT_IDENTIFIER contentType, AlgorithmIdentifier contentEncryptionAlgorithm, OCTET_STRING encryptedContent) { return new EncryptedContentInfo(contentType, contentEncryptionAlgorithm, encryptedContent, true); } /////////////////////////////////////////////////////////////////////// // Crypto shortcuts /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedContentInfo, where the data is encrypted * with a password-based key. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param toBeEncrypted The bytes to be encrypted and stored in the * EncryptedContentInfo. Before they are encrypted, they will be * padded using PKCS padding. */ public static EncryptedContentInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, byte[] toBeEncrypted) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = (PBEAlgorithm) keyGenAlg; CryptoManager cman = CryptoManager.getInstance(); // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( toBeEncrypted, encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedContentInfo EncryptedContentInfo encCI = new EncryptedContentInfo( ContentInfo.DATA, encAlgID, new OCTET_STRING(encrypted) ); return encCI; } catch( IllegalBlockSizeException e ) { Assert.notReached("IllegalBlockSizeException in EncryptedContentInfo" +".createPBE"); } catch( BadPaddingException e ) { Assert.notReached("BadPaddingException in EncryptedContentInfo" +".createPBE"); } return null; } /** * Decrypts the content of an EncryptedContentInfo encrypted with a * PBE key. * * @param pass The password to use in generating the PBE decryption key. * @param charToByteConverter The converter for converting the password * characters into bytes. May be null to use the default. * @return The decrypted contents of the EncryptedContentInfo. The contents * are first unpadded using the PKCS padding mechanism. */ public byte[] decrypt(Password pass, KeyGenerator.CharToByteConverter charToByteConverter) throws IllegalStateException,CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidBERException, IOException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException { if( encryptedContent == null ) { return null; } // get the key gen parameters AlgorithmIdentifier algid = contentEncryptionAlgorithm; KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID( algid.getOID() ); if( !(kgAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("KeyGenAlgorithm is not a"+ " PBE algorithm"); } ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } PBEParameter pbeParams; if( params instanceof PBEParameter) { pbeParams = (PBEParameter) params; } else { byte[] encodedParams = ASN1Util.encode(params); pbeParams = (PBEParameter) ASN1Util.decode( PBEParameter.getTemplate(), encodedParams ); } PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize( kgp ); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = ((PBEAlgorithm)kgAlg).getEncryptionAlg(); AlgorithmParameterSpec algParams; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); } else { algParams = null; } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams); return Cipher.unPad(cipher.doFinal( encryptedContent.toByteArray() )); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return (tag.equals(EncryptedContentInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new OBJECT_IDENTIFIER.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addOptionalElement(new Tag(0), new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() ==3); return new EncryptedContentInfo( (OBJECT_IDENTIFIER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/EncryptedData.java000066400000000000000000000076361326145000000233070ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import org.mozilla.jss.asn1.*; import java.io.*; /** * The PKCS #7 structure EncryptedData. */ public class EncryptedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private INTEGER version; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence; /** * The default version number. This should always be used unless * you really know what you are doing. */ public static final INTEGER DEFAULT_VERSION = new INTEGER(0); /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private EncryptedData() { } /** * Creates a new EncryptedData. * * @param version Should usually be DEFAULT_VERSION unless you are being * very clever. */ public EncryptedData( INTEGER version, EncryptedContentInfo encryptedContentInfo ) { if( version == null || encryptedContentInfo == null ) { throw new IllegalArgumentException("null parameter"); } sequence = new SEQUENCE(); this.version = version; sequence.addElement(version); this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(encryptedContentInfo); } /** * Creates an EncryptedData with the default version. */ public EncryptedData( EncryptedContentInfo encryptedContentInfo ) { this( DEFAULT_VERSION, encryptedContentInfo ); } /////////////////////////////////////////////////////////////////////// // Accessor Methods /////////////////////////////////////////////////////////////////////// public INTEGER getVersion() { return version; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A Template for decoding EncryptedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( EncryptedContentInfo.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new EncryptedData( (INTEGER) seq.elementAt(0), (EncryptedContentInfo) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/EnvelopedData.java000066400000000000000000000060411326145000000232600ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; public class EnvelopedData implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private SET recipientInfos; private EncryptedContentInfo encryptedContentInfo; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public SET getRecipientInfos() { return recipientInfos; } public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } private EnvelopedData() { } /** * Create a EnvelopedData ASN1 object. */ public EnvelopedData( INTEGER version, SET recipientInfos, EncryptedContentInfo encryptedContentInfo) { this.version = version; this.recipientInfos = recipientInfos; this.encryptedContentInfo = encryptedContentInfo; sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(encryptedContentInfo); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a EnvelopedData blob * */ public static class Template implements ASN1Template { public Tag getTag() { return EnvelopedData.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(EnvelopedData.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new SET.OF_Template(new RecipientInfo.Template())); seqt.addElement(new EncryptedContentInfo.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() ==3); return new EnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (EncryptedContentInfo) seq.elementAt(2) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/IssuerAndSerialNumber.java000066400000000000000000000072151326145000000247570ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.Assert; /** * An issuer name and serial number, used to uniquely identify a certificate. */ public class IssuerAndSerialNumber implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// private Name issuer; private INTEGER serialNumber; private SEQUENCE sequence; /////////////////////////////////////////////////////////////////////// // Construction /////////////////////////////////////////////////////////////////////// // no default constructor private IssuerAndSerialNumber() { } /** * Constructs an IssuerAndSerialNumber from its components. * * @param issuer Must not be null. * @param serialNumber must not be null. */ public IssuerAndSerialNumber(Name issuer, INTEGER serialNumber) { if(issuer==null || serialNumber==null) { throw new IllegalArgumentException(); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // accessors /////////////////////////////////////////////////////////////////////// public Name getIssuer() { return issuer; } public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// static Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * Returns a singleton template instance. */ public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding an IssuerAndSerialNumber from its BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( Name.getTemplate() ); seqt.addElement( INTEGER.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 2); return new IssuerAndSerialNumber( (Name) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/RecipientInfo.java000066400000000000000000000075071326145000000233130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import org.mozilla.jss.pkix.primitive.*; import java.io.*; import org.mozilla.jss.asn1.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; public class RecipientInfo implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private INTEGER version; private IssuerAndSerialNumber issuerAndSerialNumber; private AlgorithmIdentifier keyEncryptionAlgorithmID; private OCTET_STRING encryptedKey; private SEQUENCE sequence = new SEQUENCE(); public INTEGER getVersion() { return version; } public IssuerAndSerialNumber getissuerAndSerialNumber() { return issuerAndSerialNumber; } public AlgorithmIdentifier getKeyEncryptionAlgorithmID() { return keyEncryptionAlgorithmID; } public OCTET_STRING getEncryptedKey() { return encryptedKey; } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } private RecipientInfo() { } /** * Create a RecipientInfo ASN1 object. */ public RecipientInfo( INTEGER version, IssuerAndSerialNumber issuerAndSerialNumber, AlgorithmIdentifier keyEncryptionAlgorithmID, OCTET_STRING encryptedKey) { Assert._assert(issuerAndSerialNumber != null); Assert._assert(keyEncryptionAlgorithmID != null); Assert._assert(encryptedKey != null); this.version = version; this.issuerAndSerialNumber = issuerAndSerialNumber; this.keyEncryptionAlgorithmID = keyEncryptionAlgorithmID; this.encryptedKey = encryptedKey; sequence.addElement(version); sequence.addElement(issuerAndSerialNumber); sequence.addElement(keyEncryptionAlgorithmID); sequence.addElement(encryptedKey); } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { sequence.encode(tag,ostream); } /** * A template file for decoding a RecipientInfo blob * */ public static class Template implements ASN1Template { public Tag getTag() { return RecipientInfo.TAG; } public boolean tagMatch(Tag tag) { return (tag.equals(RecipientInfo.TAG)); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(getTag(),istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement(new INTEGER.Template()); seqt.addElement(new IssuerAndSerialNumber.Template()); seqt.addElement(new AlgorithmIdentifier.Template()); seqt.addElement(new OCTET_STRING.Template()); SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() ==4); return new RecipientInfo( (INTEGER) seq.elementAt(0), (IssuerAndSerialNumber) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (OCTET_STRING) seq.elementAt(3) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/SignedAndEnvelopedData.java000066400000000000000000000133271326145000000250420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; public class SignedAndEnvelopedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET recipientInfos; private SET digestAlgorithms; private EncryptedContentInfo encryptedContentInfo; private SET certificates; // may be null private SET crls; // may be null private SET signerInfos; private SEQUENCE sequence; // for encoding /** * Returns the version number. The current version is 1. */ public INTEGER getVersion() { return version; } /** * Returns a SET of RecipientInfo. */ public SET getRecipientInfos() { return recipientInfos; } /** * Returns a SET of AlgorithmIdentifier. */ public SET getDigestAlgorithms() { return digestAlgorithms; } /** * Returns the encrypted content. */ public EncryptedContentInfo getEncryptedContentInfo() { return encryptedContentInfo; } /** * Returns a SET of ANYs. May return null if the * certificates field is not present. */ public SET getCertificates() { return certificates; } /** * Returns a SET of ANYs. May return null if the crls * field is not present. */ public SET getCrls() { return crls; } /** * Returns a SET of SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private SignedAndEnvelopedData() { } public SignedAndEnvelopedData( INTEGER version, SET recipientInfos, SET digestAlgorithms, EncryptedContentInfo encryptedContentInfo, SET certificates, SET crls, SET signerInfos) { if( version==null || recipientInfos==null || digestAlgorithms==null || encryptedContentInfo==null || signerInfos==null ) { throw new IllegalArgumentException( "SignedAndEnvelopedData constructor parameter is null"); } this.version = version; this.recipientInfos = recipientInfos; this.digestAlgorithms = digestAlgorithms; this.encryptedContentInfo = encryptedContentInfo; this.certificates = certificates; this.crls = crls; this.signerInfos = signerInfos; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(recipientInfos); sequence.addElement(digestAlgorithms); sequence.addElement(encryptedContentInfo); if( certificates!=null ) { sequence.addElement(certificates); } if( crls!=null ) { sequence.addElement(crls); } sequence.addElement( signerInfos ); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } /** * A Template class for decoding BER-encoded SignedAndEnvelopedData items. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement(INTEGER.getTemplate()); seqt.addElement(new SET.OF_Template(RecipientInfo.getTemplate())); seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate()) ); seqt.addElement(EncryptedContentInfo.getTemplate()); seqt.addOptionalElement(new Tag(0), new SET.OF_Template(ANY.getTemplate())); seqt.addOptionalElement(new Tag(1), new SET.OF_Template(ANY.getTemplate())); seqt.addElement(new SET.OF_Template(SignerInfo.getTemplate())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new SignedAndEnvelopedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (SET) seq.elementAt(2), (EncryptedContentInfo) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5), (SET) seq.elementAt(6) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/SignedData.java000066400000000000000000000327511326145000000225570ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import java.io.*; import java.util.Vector; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.io.ByteArrayInputStream; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.Certificate; /* CUT THIS??? *

Although all the normal functionality of a SignedData is supported * with high-level methods, there is a low-level API for setting the * individual fields of the structure. Using these calls is an unsupported * way of accomplishing unforeseen tasks. If you have reason to use these * methods, please notify the authors in case it is something that should * be added to the high-level interface. * */ /** * A CMS SignedData structure. *

The certificates field should only contain X.509 certificates. * PKCS #6 extended certificates will fail to decode properly. * @author stevep * @author nicolson * @author mzhao */ public class SignedData implements ASN1Value { /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private SET digestAlgorithms; private EncapsulatedContentInfo contentInfo; private SET certificates; // [0] optional, may be null private SET crls; // [1] optional, may be null private SET signerInfos; // This class implements version 3 of the spec. private static final INTEGER VERSION = new INTEGER(3); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static void verifyNotNull(Object obj) { if( obj == null ) { throw new IllegalArgumentException(); } } /** * Returns the version of this SignedData. The current version of the * spec is version 3. */ public INTEGER getVersion() { return version; } /** * Low-level function to set the version. * @param version Must not be null. public void setVersion(INTEGER version) { verifyNotNull(version); this.version = version; } */ /** * Returns the digest algorithms used by the signers to digest the * signed content. There may be more than one, if different signers * use different digesting algorithms. */ public SET getDigestAlgorithmIdentifiers() { return digestAlgorithms; } /** * Low-level function to set the digest algorithm identifiers. * @param digestAlgIds Must not be null. public void setDigestAlgorithmIdentifiers(SET digestAlgIds) { verifyNotNull(digestAlgIds); this.digestAlgorithms = digestAlgIds; } */ /** * Returns the EncapsulatedContentInfo containing the signed content. The simple * case is for the content to be of type data, although any * content type can be signed. */ public EncapsulatedContentInfo getContentInfo() { return contentInfo; } /** * Low-level function to set the EncapsulatedcontentInfo. * @param ci Must not be null. public void setContentInfo(EncapsulatedContentInfo ci) { verifyNotNull(ci); this.contentInfo = ci; } */ /** * Returns the certificates field, which is a SET of * X.509 certificates (org.mozilla.jss.pkix.cert.Certificate). * PKCS #6 Extended Certificates are not supported by this implementation. * Returns null if this optional field is not present. * */ public SET getCertificates() { return certificates; } /** * Low-level function to set the certificates. * @param certs May be null to signify that the certificates * field is not present. public void setCertificates(SET certs) { this.certificates = certs; } */ /** * Returns true if the certificates field is present. */ public boolean hasCertificates() { return (certificates!=null); } /** * Returns the crls field, which contains a SET of certificate * revocation lists represented by ANYs (org.mozilla.jss.asn1.ANY). * */ public SET getCrls() { return crls; } /** * Low-level function to set the crls. * @param certs May be null to signify that the crls * field is not present. public void setCrls(SET crls) { this.crls = crls; } */ /** * Returns true if the crls field is present. */ public boolean hasCrls() { return (crls != null); } /** * Returns the signerInfos field, which is a SET of * org.mozilla.jss.pkcs7.SignerInfo. */ public SET getSignerInfos() { return signerInfos; } /** * Low-level function to set the SignerInfos. * @param signerInfos Must not be null. public void setSignerInfos(SET signerInfos) { verifyNotNull(sis); this.signerInfos = signerInfos; } */ /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Low-level constructor that merely initializes all fields to null. private SignedData() {} */ /** * Create a SignedData ASN1 object. Both certificates and CRLs * are optional. If you pass in a null for either value, that * parameter will not get written in the sequence. * * @param digestAlgorithms A SET of zero or more * algorithm identifiers. The purpose of this item is to list * the digest algorithms used by the various signers to digest * the signed content. This field will also be updated by * the addSigner method. If all the signers are added * with addSigner, it is not necessary to list * the digest algorithms here. *

If null is passed in, the * digestAlgorithms field will be initialized * with an empty SET. * @param contentInfo The content that is being signed. This parameter * may not be null. However, the content * field of the contentInfo may be omitted, in which case the * signatures contained in the SignerInfo structures * are presumed to be on externally-supplied data. * @param certificates A SET of org.mozilla.jss.pkix.cert.Certificate, * the certificates * containing the public keys used to sign the content. It may * also contain elements of the CA chain extending from the leaf * certificates. It is not necessary to include the CA chain, or * indeed to include any certificates, if the certificates are * expected to already be possessed by the recipient. The recipient * can use the issuer and serial number in the SignerInfo structure * to search for the necessary certificates. If this parameter is * null, the certificates field will be * omitted. * @param crls A SET of ASN1Values, which should encode to the ASN1 type * CertificateRevocationList. This implementation does * not interpret CRLs. If this parameter is null, * the crls field will be omitted. * @param signerInfos SignerInfo structures containing signatures * of the content. Additional signerInfos can be added with * the addSigner method. If this parameter is * null, the field will be initialized with an * empty SET. */ public SignedData( SET digestAlgorithms, EncapsulatedContentInfo contentInfo, SET certificates, SET crls, SET signerInfos) { version = VERSION; if(digestAlgorithms == null ) { this.digestAlgorithms = new SET(); } else { this.digestAlgorithms = digestAlgorithms; } verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; if(signerInfos == null) { this.signerInfos = new SET(); } else { this.signerInfos = signerInfos; } } /** * Constructor for creating a SignedData from its encoding. */ SignedData( INTEGER version, SET digestAlgorithms, EncapsulatedContentInfo contentInfo, SET certificates, SET crls, SET signerInfos ) { verifyNotNull(version); this.version = version; verifyNotNull(digestAlgorithms); this.digestAlgorithms = digestAlgorithms; verifyNotNull(contentInfo); this.contentInfo = contentInfo; // certificates may be null this.certificates = certificates; // crls may be null this.crls = crls; verifyNotNull(signerInfos); this.signerInfos = signerInfos; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Cryptographic functions /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(digestAlgorithms); sequence.addElement(contentInfo); if( certificates != null ) { sequence.addElement( new Tag(0), certificates ); } if( crls != null ) { sequence.addElement( new Tag(1), crls ); } sequence.addElement(signerInfos); sequence.encode(tag,ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template file for decoding a SignedData blob * */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // version seqt.addElement(INTEGER.getTemplate()); // digestAlgorithms seqt.addElement(new SET.OF_Template( AlgorithmIdentifier.getTemplate())); // content info seqt.addElement(EncapsulatedContentInfo.getTemplate()); // [0] IMPLICIT certificates OPTIONAL seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Certificate.getTemplate())); // [1] IMPLICIT CertificateRevocationLists OPTIONAL seqt.addOptionalElement( new Tag(1), new SET.OF_Template(ANY.getTemplate())); // signerInfos seqt.addElement(new SET.OF_Template(SignerInfo.getTemplate())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); Assert._assert(seq.size() == 6); return new SignedData( (INTEGER) seq.elementAt(0), (SET) seq.elementAt(1), (EncapsulatedContentInfo) seq.elementAt(2), (SET) seq.elementAt(3), (SET) seq.elementAt(4), (SET) seq.elementAt(5) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/SignerIdentifier.java000066400000000000000000000135001326145000000237750ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.cert.*; import java.io.*; import org.mozilla.jss.util.Assert; /** * CMS SignerIdentifier: *

 * SignerIdentifier ::= CHOICE {
 *      issuerAndSerialNumber IssuerAndSerialNumber,
 *      subjectKeyIdentifier [0] SubjectKeyIdentifier }
 * 
*/ public class SignerIdentifier implements ASN1Value { /** * The type of SignerIdentifier. */ public static class Type { private Type() { } static Type ISSUER_AND_SERIALNUMBER = new Type(); static Type SUBJECT_KEY_IDENTIFIER = new Type(); } public static Type ISSUER_AND_SERIALNUMBER = Type.ISSUER_AND_SERIALNUMBER; public static Type SUBJECT_KEY_IDENTIFIER = Type.SUBJECT_KEY_IDENTIFIER; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private Type type; private IssuerAndSerialNumber issuerAndSerialNumber = null; // if type == ISSUER_AND_SERIALNUMBER private OCTET_STRING subjectKeyIdentifier = null; // if type == SUBJECT_KEY_IDENTIFIER /** * Returns the type of SignerIdentifier:
    *
  • ISSUER_AND_SERIALNUMBER *
  • SUBJECT_KEY_IDENTIFIER *
*/ public Type getType() { return type; } /** * If type == ISSUER_AND_SERIALNUMBER, returns the IssuerAndSerialNumber * field. Otherwise, returns null. */ public IssuerAndSerialNumber getIssuerAndSerialNumber() { return issuerAndSerialNumber; } /** * If type == SUBJECT_KEY_IDENTIFIER, returns the SubjectKeyIdentifier * field. Otherwise, returns null. */ public OCTET_STRING getSubjectKeyIdentifier() { return subjectKeyIdentifier; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private SignerIdentifier() { } public SignerIdentifier(Type type, IssuerAndSerialNumber issuerAndSerialNumber, OCTET_STRING subjectKeyIdentifier) { this.type = type; this.issuerAndSerialNumber = issuerAndSerialNumber; this.subjectKeyIdentifier = subjectKeyIdentifier; } /** * Creates a new SignerIdentifier with the given IssuerAndSerialNumber field. */ public static SignerIdentifier createIssuerAndSerialNumber(IssuerAndSerialNumber ias) { return new SignerIdentifier( ISSUER_AND_SERIALNUMBER, ias, null ); } /** * Creates a new SignerIdentifier with the given SubjectKeyIdentifier field. */ public static SignerIdentifier createSubjectKeyIdentifier(OCTET_STRING ski) { return new SignerIdentifier(SUBJECT_KEY_IDENTIFIER , null, ski ); } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if( type == SUBJECT_KEY_IDENTIFIER ) { return Tag.get(0); } else { Assert._assert( type == ISSUER_AND_SERIALNUMBER ); return IssuerAndSerialNumber.TAG; } } public void encode(OutputStream ostream) throws IOException { if( type == SUBJECT_KEY_IDENTIFIER ) { // a CHOICE must be explicitly tagged //EXPLICIT e = new EXPLICIT( Tag.get(0), subjectKeyIdentifier ); //e.encode(ostream); subjectKeyIdentifier.encode(Tag.get(0), ostream); } else { Assert._assert( type == ISSUER_AND_SERIALNUMBER ); issuerAndSerialNumber.encode(ostream); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged"); encode(ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding a SignerIdentifier. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); //EXPLICIT.Template et = new EXPLICIT.Template( // Tag.get(0), OCTET_STRING.getTemplate() ); //choicet.addElement( et ); choicet.addElement( Tag.get(0), OCTET_STRING.getTemplate() ); choicet.addElement(IssuerAndSerialNumber.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE c = (CHOICE) choicet.decode(istream); if( c.getTag() == SEQUENCE.TAG ) { return createIssuerAndSerialNumber( (IssuerAndSerialNumber) c.getValue() ); } else { Assert._assert( c.getTag().equals(Tag.get(0)) ); //EXPLICIT e = (EXPLICIT) c.getValue(); //ASN1Value dski = e.getContent(); //OCTET_STRING ski = (OCTET_STRING) e.getContent(); OCTET_STRING ski = (OCTET_STRING) c.getValue(); return createSubjectKeyIdentifier(ski); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { //Assert.notReached("A CHOICE cannot be implicitly tagged"); return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/SignerInfo.java000066400000000000000000000720571326145000000226220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.cms; import java.io.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.crypto.*; import java.security.InvalidKeyException; import java.security.SignatureException; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.pkix.cert.*; import org.mozilla.jss.*; import java.security.PublicKey; /* * The high-level interface takes care of all * the logic and cryptography. If you need to use the low-level interface, * please let us know what you are using it for. Perhaps it should be part * of the high-level interface. */ /** * A CMS SignerInfo. */ public class SignerInfo implements ASN1Value { //////////////////////////////////////////////// // PKCS #9 attributes //////////////////////////////////////////////// private static final OBJECT_IDENTIFIER CONTENT_TYPE = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(3); private static final OBJECT_IDENTIFIER MESSAGE_DIGEST = OBJECT_IDENTIFIER.PKCS.subBranch(9).subBranch(4); /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Members /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private INTEGER version; private SignerIdentifier signerIdentifier; private AlgorithmIdentifier digestAlgorithm; private SET signedAttributes; // [0] OPTIONAL private AlgorithmIdentifier digestEncryptionAlgorithm; private OCTET_STRING encryptedDigest; private SET unsignedAttributes; // [1] OPTIONAL /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Accessor methods /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Retrieves the version number of this SignerInfo. */ public INTEGER getVersion() { return version; } /** * Retrieves the SignerIdentifier. */ public SignerIdentifier getSignerIdentifier() { return signerIdentifier; } /** * Retrieves the DigestAlgorithm used in this SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not * recognized by JSS. */ public DigestAlgorithm getDigestAlgorithm() throws NoSuchAlgorithmException { return DigestAlgorithm.fromOID( digestAlgorithm.getOID() ); } /** * Retrieves the DigestAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestAlgorithmIdentifer() { return digestAlgorithm; } /** * Retrieves the signed attributes, if they exist. * */ public SET getSignedAttributes() { return signedAttributes; } /** * Returns true if the signedAttributes field is present. */ public boolean hasSignedAttributes() { return (signedAttributes != null); } /** * Returns the raw signature (digest encryption) algorithm used in this * SignerInfo. * * @exception NoSuchAlgorithmException If the algorithm is not recognized * by JSS. */ public SignatureAlgorithm getDigestEncryptionAlgorithm() throws NoSuchAlgorithmException { return SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); } /** * Returns the DigestEncryptionAlgorithmIdentifier used in this SignerInfo. */ public AlgorithmIdentifier getDigestEncryptionAlgorithmIdentifier() { return digestEncryptionAlgorithm; } /** * Retrieves the encrypted digest. */ public byte[] getEncryptedDigest() { return encryptedDigest.toByteArray(); } /** * Retrieves the unsigned attributes, if they exist. * */ public SET getUnsignedAttributes() { return unsignedAttributes; } /** * Returns true if the unsignedAttributes field is present. */ public boolean hasUnsignedAttributes() { return (unsignedAttributes!=null); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * A constructor for creating a new SignerInfo from scratch. * * @param signerIdentifier The signerIdentifier of the * certificate from which the public key was extracted to create * this SignerInfo. * @param signingAlg The algorithm to be used to sign the content. * This should be a composite algorithm, such as * RSASignatureWithMD5Digest, instead of a raw algorithm, such as * RSASignature. * Note that the digest portion of this algorithm must be the same * algorithm as was used to digest the message content. * @param signedAttributes An optional set of Attributes, which * will be signed along with the message content. This parameter may * be null, or the SET may be empty. DO NOT insert * the PKCS #9 content-type or message-digest attributes. They will * be added automatically if they are necessary. * @param unsignedAttributes An optional set of Attributes, which * will be included in the SignerInfo but not signed. This parameter * may be null, or the SET may be empty. * @param messageDigest The digest of the message contents. The digest * must have been created with the digest algorithm specified by * the signingAlg parameter. * @param contentType The type of the ContentInfo that is being signed. * If it is not data, then the PKCS #9 attributes * content-type and message-digest will be automatically computed and * added to the signed attributes. */ public SignerInfo( SignerIdentifier signerIdentifier, SET signedAttributes, SET unsignedAttributes, OBJECT_IDENTIFIER contentType, byte[] messageDigest, SignatureAlgorithm signingAlg, PrivateKey signingKey ) throws InvalidKeyException, NoSuchAlgorithmException, CryptoManager.NotInitializedException, SignatureException, TokenException { if (signerIdentifier == null) { throw new IllegalArgumentException("SignerIdentifier may not be null"); } this.signerIdentifier = signerIdentifier; if (SignerIdentifier.ISSUER_AND_SERIALNUMBER.equals(this.signerIdentifier.getType())) { this.version = new INTEGER(1); } else if (SignerIdentifier.SUBJECT_KEY_IDENTIFIER.equals(this.signerIdentifier.getType())) { this.version = new INTEGER(3); } else { throw new IllegalArgumentException("Unexpected SignerIdentifier type"); } this.digestAlgorithm = new AlgorithmIdentifier(signingAlg.getDigestAlg().toOID(),null); // if content-type is not data, add message-digest and content-type // to signed attributes. if( ! contentType.equals(ContentInfo.DATA) ) { if( signedAttributes == null ) { signedAttributes = new SET(); } Attribute attrib = new Attribute(CONTENT_TYPE, contentType); signedAttributes.addElement(attrib); attrib = new Attribute(MESSAGE_DIGEST, new OCTET_STRING(messageDigest) ); signedAttributes.addElement(attrib); } digestEncryptionAlgorithm = new AlgorithmIdentifier( signingAlg.toOID(),null ); if( signedAttributes != null ) { Assert._assert( signedAttributes.size() >= 2 ); this.signedAttributes = signedAttributes; } ////////////////////////////////////////////////// // create encrypted digest (signature) ////////////////////////////////////////////////// // compute the digest CryptoToken token = signingKey.getOwningToken(); Signature sig; byte[] toBeSigned = null; if (signedAttributes == null) { // just use the message digest of the content if (signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { SEQUENCE digestInfo = createDigestInfo(messageDigest, false); toBeSigned = ASN1Util.encode(digestInfo); } else { toBeSigned = messageDigest; } sig = token.getSignatureContext(signingAlg.getRawAlg()); //data is already digested } else { byte[] encoding = ASN1Util.encode(signedAttributes); if (signingAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { // put the digest in a DigestInfo SEQUENCE digestInfo = createDigestInfo(encoding, true); toBeSigned = ASN1Util.encode(digestInfo); sig = token.getSignatureContext(SignatureAlgorithm.RSASignature); } else { toBeSigned = encoding; sig = token.getSignatureContext(signingAlg); } } // encrypt the DER-encoded DigestInfo with the private key sig.initSign(signingKey); sig.update(toBeSigned); encryptedDigest = new OCTET_STRING(sig.sign()); if( unsignedAttributes != null ) { this.unsignedAttributes = unsignedAttributes; } } /** * A constructor for creating a new SignerInfo from its decoding. */ SignerInfo( INTEGER version, SignerIdentifier signerIdentifier, AlgorithmIdentifier digestAlgorithm, SET signedAttributes, AlgorithmIdentifier digestEncryptionAlgorithm, byte[] encryptedDigest, SET unsignedAttributes) { this.version = version; this.signerIdentifier = signerIdentifier; this.digestAlgorithm = digestAlgorithm; this.signedAttributes = signedAttributes; this.digestEncryptionAlgorithm = digestEncryptionAlgorithm; this.encryptedDigest = new OCTET_STRING(encryptedDigest); this.unsignedAttributes = unsignedAttributes; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Verification /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any signed attributes are present, * they are also validated. The verification algorithm is as follows: * Note that this does not verify the validity of the * the certificate itself, only the signature.
    * *
  • If no signed attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If signed attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * signedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @exception ObjectNotFoundException If no certificate * matching the issuer name and serial number can be found. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException, ObjectNotFoundException { CryptoManager cm = CryptoManager.getInstance(); if (signerIdentifier.getType().equals(SignerIdentifier.ISSUER_AND_SERIALNUMBER)) { IssuerAndSerialNumber issuerAndSerialNumber = signerIdentifier.getIssuerAndSerialNumber(); X509Certificate cert = cm.findCertByIssuerAndSerialNumber( ASN1Util.encode(issuerAndSerialNumber.getIssuer()), issuerAndSerialNumber.getSerialNumber() ); verify(messageDigest, contentType, cert.getPublicKey()); } else { Assert._assert( signerIdentifier.getType().equals(SignerIdentifier.SUBJECT_KEY_IDENTIFIER) ); // XXX Do we have method to get key using keyIdentifier } } /** * Verifies that this SignerInfo contains a valid signature of the * given message digest. If any signed attributes are present, * they are also validated. The verification algorithm is as follows:
    * *
  • If no signed attributes are present, the content type is * verified to be data. Then it is verified that the message * digest passed * in, when encrypted with the given public key, matches the encrypted * digest in the SignerInfo. * *
  • If signed attributes are present, * two particular attributes must be present:
      *
    • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
    • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
    * After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * signedAttributes field. * *
* * @param messageDigest The hash of the content that is signed by this * SignerInfo. * @param contentType The type of the content that is signed by this * SignerInfo. * @param pubkey The public key to use to verify the signature. */ public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( signedAttributes == null ) { verifyWithoutSignedAttributes(messageDigest, contentType, pubkey); } else { verifyWithSignedAttributes(messageDigest, contentType, pubkey); } } /** * Verifies that the message digest passed in, when encrypted with the * given public key, matches the encrypted digest in the SignerInfo. */ private void verifyWithoutSignedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { if( ! contentType.equals(ContentInfo.DATA) ) { // only data can be signed this way. Everything else has // to go into signedAttributes. throw new SignatureException( "Content-Type is not DATA, but there are"+ " no signed attributes"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); CryptoToken token = CryptoManager.getInstance() .getInternalCryptoToken(); Signature sig; byte[] toBeVerified; if (sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { // create DigestInfo structure SEQUENCE digestInfo = createDigestInfo(messageDigest, false); toBeVerified = ASN1Util.encode(digestInfo); sig = token.getSignatureContext(sigAlg.getRawAlg()); } else { toBeVerified = messageDigest; sig = token.getSignatureContext(sigAlg); } sig.initVerify(pubkey); sig.update(toBeVerified); if( sig.verify(encryptedDigest.toByteArray()) ) { return; // success } else { throw new SignatureException( "Encrypted message digest parameter does not "+ "match encrypted digest in SignerInfo"); } } /** * Verifies a SignerInfo with signed attributes. If signed * attributes are present, then two particular attributes must * be present:
    *
  • PKCS #9 Content-Type, the type of content that is being signed. * This must match the contentType parameter. *
  • PKCS #9 Message-Digest, the digest of the content that is being * signed. This must match the messageDigest parameter. *
* After these two attributes are verified to be both present and correct, * the encryptedDigest field of the SignerInfo is verified to be the * signature of the contents octets of the DER encoding of the * signedAttributes field. */ private void verifyWithSignedAttributes (byte[] messageDigest, OBJECT_IDENTIFIER contentType, PublicKey pubkey) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, TokenException, SignatureException { int numAttrib = signedAttributes.size(); if(numAttrib < 2) { throw new SignatureException( "At least two signed attributes must be present:"+ " content-type and message-digest"); } // go through the signed attributes, verifying the // interesting ones boolean foundContentType = false; boolean foundMessageDigest = false; for( int i = 0; i < numAttrib; i++ ) { if( ! (signedAttributes.elementAt(i) instanceof Attribute)) { throw new SignatureException( "Element of signedAttributes is not an Attribute"); } Attribute attrib = (Attribute) signedAttributes.elementAt(i); if( attrib.getType().equals(CONTENT_TYPE) ) { // content-type. Compare with what was passed in. SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Content-Type attribute "+ " does not have exactly one value"); } ASN1Value val = vals.elementAt(0); OBJECT_IDENTIFIER ctype; try { if( val instanceof OBJECT_IDENTIFIER ) { ctype = (OBJECT_IDENTIFIER) val; } else if( val instanceof ANY ) { ctype = (OBJECT_IDENTIFIER) ((ANY)val).decodeWith( OBJECT_IDENTIFIER.getTemplate() ); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type signed attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Content-Type signed attribute does not have "+ "OBJECT IDENTIFIER value"); } // compare the content type in the attribute to the // contentType parameter if( ! ctype.equals( contentType ) ) { throw new SignatureException( "Content-type in signed attributes does not "+ "match content-type being verified"); } // content type is A-OK foundContentType = true; } else if( attrib.getType().equals(MESSAGE_DIGEST) ) { SET vals = attrib.getValues(); if( vals.size() != 1 ) { throw new SignatureException( "Message-digest attribute does not have"+ " exactly one value"); } ASN1Value val = vals.elementAt(0); byte[] mdigest; try { if( val instanceof OCTET_STRING ) { mdigest = ((OCTET_STRING)val).toByteArray(); } else if( val instanceof ANY ) { OCTET_STRING os; os = (OCTET_STRING) ((ANY)val).decodeWith( OCTET_STRING.getTemplate() ); mdigest = os.toByteArray(); } else { // what the heck is it? not what it's supposed to be throw new InvalidBERException( "Content-Type signed attribute has unexpected"+ " content type"); } } catch( InvalidBERException e ) { throw new SignatureException( "Message-digest attribute does not"+ " have OCTET STRING value"); } // compare the message digest in the attribute to the // message digest being verified if( ! byteArraysAreSame(mdigest, messageDigest) ) { throw new SignatureException( "Message-digest attribute does not"+ " match message digest being verified"); } // message digest is A-OK foundMessageDigest = true; } // we don't care about other attributes } if( !foundContentType ) { throw new SignatureException( "Signed attributes does not contain"+ " PKCS #9 content-type attribute"); } if( !foundMessageDigest ) { throw new SignatureException( "Signed attributes does not contain"+ " PKCS #9 message-digest attribute"); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID( digestEncryptionAlgorithm.getOID() ); // All the signed attributes are present and correct. // Now verify the signature. CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); Signature sig; // verify the contents octets of the DER encoded signed attribs byte[] encoding = ASN1Util.encode(signedAttributes); byte[] toBeVerified; if (sigAlg.getRawAlg() == SignatureAlgorithm.RSASignature) { // create DigestInfo structure SEQUENCE digestInfo = createDigestInfo(encoding, true); toBeVerified = ASN1Util.encode(digestInfo); sig = token.getSignatureContext(SignatureAlgorithm.RSASignature); } else { toBeVerified = encoding; sig = token.getSignatureContext(sigAlg); } sig.initVerify(pubkey); sig.update( toBeVerified ); if( ! sig.verify(encryptedDigest.toByteArray()) ) { // signature is invalid throw new SignatureException("encryptedDigest was not the correct"+ " signature of the contents octets of the DER-encoded"+ " signed attributes"); } // SUCCESSFULLY VERIFIED } private SEQUENCE createDigestInfo(byte[] data, boolean doDigest) throws NoSuchAlgorithmException { if(data == null || data.length == 0){ throw new IllegalArgumentException("Data to digest must be supplied"); } SEQUENCE digestInfo = new SEQUENCE(); digestInfo.addElement(this.digestAlgorithm); byte[] digest; if (doDigest) { MessageDigest md = MessageDigest.getInstance( DigestAlgorithm.fromOID(this.digestAlgorithm.getOID()).toString()); digest = md.digest(data); } else { digest = data; } digestInfo.addElement(new OCTET_STRING(digest)); return digestInfo; } /** * Compares two non-null byte arrays. Returns true if they are identical, * false otherwise. */ private static boolean byteArraysAreSame(byte[] left, byte[] right) { Assert._assert(left!=null && right!=null); if( left.length != right.length ) { return false; } for(int i = 0 ; i < left.length ; i++ ) { if( left[i] != right[i] ) { return false; } } return true; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER-encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(getTag(),ostream); } public void encode(Tag tag, OutputStream ostream) throws IOException { SEQUENCE sequence = new SEQUENCE(); sequence.addElement( version ); sequence.addElement( signerIdentifier ); sequence.addElement( digestAlgorithm ); if( signedAttributes != null ) { sequence.addElement( new Tag(0), signedAttributes ); } sequence.addElement( digestEncryptionAlgorithm ); sequence.addElement( encryptedDigest ); if( unsignedAttributes != null ) { sequence.addElement( new Tag(1), unsignedAttributes ); } sequence.encode(tag,ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A template for decoding a SignerInfo blob * */ public static class Template implements ASN1Template { SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); // serial number seqt.addElement(INTEGER.getTemplate()); // vn // issuerAndSerialNumber seqt.addElement(SignerIdentifier.getTemplate()); // signerId // digestAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // digest alg // signedAttributes seqt.addOptionalElement( new Tag(0), new SET.OF_Template(Attribute.getTemplate())); // digestEncryptionAlgorithm seqt.addElement(AlgorithmIdentifier.getTemplate()); // dig encr alg // encryptedDigest seqt.addElement(OCTET_STRING.getTemplate()); // encr digest // unsigned attributes seqt.addOptionalElement( new Tag(1), new SET.OF_Template(Attribute.getTemplate())); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG,istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag,istream); Assert._assert(seq.size() == 7); return new SignerInfo( (INTEGER) seq.elementAt(0), (SignerIdentifier) seq.elementAt(1), (AlgorithmIdentifier) seq.elementAt(2), (SET) seq.elementAt(3), (AlgorithmIdentifier) seq.elementAt(4), ((OCTET_STRING) seq.elementAt(5)).toByteArray(), (SET) seq.elementAt(6) ); } } // end of template } jss-4.4.3/jss/org/mozilla/jss/pkix/cms/package.html000066400000000000000000000004261326145000000221640ustar00rootroot00000000000000 Creating and interpeting CMS blobs. jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/000077500000000000000000000000001326145000000200465ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/CertId.java000066400000000000000000000066571326145000000221010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.*; /** * CRMF CertId. *
 * CertId ::= SEQUENCE {
 *      issuer          GeneralName,
 *      serialNumber    INTEGER }
 * 
*/ public class CertId implements ASN1Value { /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private ANY issuer; private INTEGER serialNumber; private SEQUENCE sequence; /** * Returns the issuer field as an ANY. * The actual type of the field is GeneralName. */ public ANY getIssuer() { return issuer; } /** * Returns the serialNumber field. */ public INTEGER getSerialNumber() { return serialNumber; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private CertId() { } /** * Constructs a new CertId from its components. Neither * component may be null. */ public CertId(ANY issuer, INTEGER serialNumber) { if( issuer == null || serialNumber == null ) { throw new IllegalArgumentException( "parameter to CertId constructor is null"); } sequence = new SEQUENCE(); this.issuer = issuer; sequence.addElement(issuer); this.serialNumber = serialNumber; sequence.addElement(serialNumber); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a CertId. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( ANY.getTemplate() ); seqt.addElement( INTEGER.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new CertId( (ANY) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/CertReqMsg.java000066400000000000000000000251601326145000000227310ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.Assert; import java.math.BigInteger; import java.text.DateFormat; import java.security.SignatureException; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.crypto.*; import java.security.PublicKey; import java.io.FileOutputStream; /** * This class models a CRMF CertReqMsg structure. */ public class CertReqMsg implements ASN1Value { public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } /** * Retrieves the CertRequest contained in this structure. */ public CertRequest getCertReq() { return certReq; } private CertRequest certReq; /** * Returns true if this CertReqMsg has a * regInfo field. */ public boolean hasRegInfo() { return regInfo != null; } /** * Returns the regInfo field. Should only be called if the * field is present. */ public SEQUENCE getRegInfo() { Assert._assert(regInfo != null); return regInfo; } private SEQUENCE regInfo; /** * Returns true if this CertReqMsg has a * pop field. */ public boolean hasPop() { return pop != null; } /** * Returns the pop field. Should only be called if the * field is present. */ public ProofOfPossession getPop() { Assert._assert(pop != null); return pop; } private ProofOfPossession pop = null; // no default constructor private CertReqMsg() { } /** * Constructs a CertReqmsg from a CertRequest and, optionally, * a pop and a regInfo. * @param pop May be NULL. * @param regInfo May be NULL. */ public CertReqMsg( CertRequest certReq, ProofOfPossession pop, SEQUENCE regInfo ) { this.certReq = certReq; this.pop = pop; this.regInfo = regInfo; } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // Verification /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// public void verify() throws SignatureException, InvalidKeyFormatException, NoSuchAlgorithmException, org.mozilla.jss.CryptoManager.NotInitializedException, TokenException, java.security.InvalidKeyException, IOException{ CryptoToken token = CryptoManager.getInstance() .getInternalCryptoToken(); verify(token); } public void verify(CryptoToken token) throws SignatureException, InvalidKeyFormatException, NoSuchAlgorithmException, org.mozilla.jss.CryptoManager.NotInitializedException, TokenException, java.security.InvalidKeyException, IOException{ ProofOfPossession.Type type = pop.getType(); if (type == ProofOfPossession.SIGNATURE) { POPOSigningKey sigkey = pop.getSignature(); AlgorithmIdentifier alg = sigkey.getAlgorithmIdentifier(); BIT_STRING sig_from = sigkey.getSignature(); ByteArrayOutputStream bo = new ByteArrayOutputStream(); certReq.encode(bo); byte[] toBeVerified = bo.toByteArray(); PublicKey pubkey = null; CertTemplate ct = certReq.getCertTemplate(); if (ct.hasPublicKey()) { SubjectPublicKeyInfo spi = ct.getPublicKey(); pubkey = (PublicKey) spi.toPublicKey(); } SignatureAlgorithm sigAlg = SignatureAlgorithm.fromOID(alg.getOID()); Signature sig = token.getSignatureContext(sigAlg); sig.initVerify(pubkey); sig.update(toBeVerified); if( sig.verify(sig_from.getBits()) ) { //System.out.println("worked!!"); return; // success } else { throw new SignatureException( "Signed request information does not "+ "match signature in POP"); } } else if (type == ProofOfPossession.KEY_ENCIPHERMENT) { POPOPrivKey keyEnc = pop.getKeyEncipherment(); POPOPrivKey.Type ptype = keyEnc.getType(); if (ptype == POPOPrivKey.THIS_MESSAGE) { //BIT_STRING thisMessage = keyEnc.getThisMessage(); //This should be the same as from the archive control //It's verified by DRM. } else if (ptype == POPOPrivKey.SUBSEQUENT_MESSAGE) { new ChallengeResponseException("requested"); } } } /** * Encodes this CertReqMsg to the given OutputStream using * DER encoding. */ public void encode(OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertReqMsg encoding"); encode(getTag(),ostream); } /** * Encodes this CertReqMsg to the given OutputStream using * DER encoding, with the given implicit tag. */ public void encode(Tag implicit, OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertReqMsg encoding"); SEQUENCE sequence = new SEQUENCE(); sequence.addElement( certReq ); if (pop != null) sequence.addElement( pop ); if (regInfo != null) sequence.addElement( regInfo ); sequence.encode(implicit,ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding CertReqMsg structures from a BER encoding. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag t) { return TAG.equals(t); } /** * Decodes a CertReqMsg from the given input stream. * * @return A new CertReqMsg. The return value may be cast * to a CertReqMsg. * @throws InvalidBERException If the data on the input stream is not * a valid BER encoding of a CertReqMsg. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } /** * Decodes a CertReqMsg from the given input stream, using * the given implicit tag. * * @param implicit The implicit tag for this item. This must be * supplied if the CertReqMsg appears in a context * where it is implicitly tagged. * @return A new CertReqMsg. The return value may be cast * to a CertReqMsg. * @throws InvalidBERException If the data on the input stream is not * a valid BER encoding of a CertReqMsg. */ public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement( new CertRequest.Template() ); seqt.addOptionalElement( new ProofOfPossession.Template()); seqt.addOptionalElement( new SEQUENCE.OF_Template( new AVA.Template() ) ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); return new CertReqMsg( (CertRequest) seq.elementAt(0), (ProofOfPossession) seq.elementAt(1), (SEQUENCE) seq.elementAt(2) ); } } public static void main(String args[]) { try { if( args.length < 1 ) { System.err.println("Give an arg"); System.exit(0); } FileInputStream fis = new FileInputStream(args[0]); SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( new CertReqMsg.Template() ); SEQUENCE seq=null; byte[] bytes = new byte[ fis.available() ]; fis.read(bytes); for(int i=0; i < 1; i++) { seq = (SEQUENCE) seqt.decode(new ByteArrayInputStream(bytes)); } System.out.println("Decoded "+seq.size()+" messages"); CertReqMsg reqmsg = (CertReqMsg) seq.elementAt(0); CertRequest certreq = reqmsg.getCertReq(); System.out.println("Request ID: "+certreq.getCertReqId() ); CertTemplate temp = certreq.getCertTemplate(); if( temp.hasVersion() ) { System.out.println("Version: "+temp.getVersion()); } else { System.out.println("No version"); } if( temp.hasSerialNumber() ) { System.out.println("Serial Number: "+temp.getSerialNumber()); } else { System.out.println("No serial number"); } if( temp.hasSigningAlg() ) { System.out.println("SigningAlg: "+temp.getSigningAlg().getOID()); } else { System.out.println("No signing alg"); } if( temp.hasIssuer() ) { System.out.println("Issuer: "+temp.getIssuer().getRFC1485()); } else { System.out.println("No issuer"); } if( temp.hasSubject() ) { System.out.println("Subject: "+temp.getSubject().getRFC1485()); } else { System.out.println("No subject: "); } if( temp.hasPublicKey() ) { System.out.println("Public Key: "+ temp.getPublicKey().getAlgorithmIdentifier().getOID() ); } else { System.out.println("No public key"); } if( temp.hasIssuerUID() ) { System.out.println("Issuer UID: "+new BigInteger(temp.getIssuerUID().getBits() ) ); } else { System.out.println("no issuer uid"); } if( temp.hasSubjectUID() ) { System.out.println("Subject UID: "+new BigInteger(temp.getIssuerUID().getBits() ) ); } else { System.out.println("no subject uid"); } if( temp.hasNotBefore() ) { System.out.println("Not Before: "+ DateFormat.getInstance().format( temp.getNotBefore() )); } if( temp.hasNotAfter() ) { System.out.println("Not After: "+ DateFormat.getInstance().format( temp.getNotAfter() )); } } catch( Exception e ) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/CertRequest.java000066400000000000000000000111101326145000000231510ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import java.util.Date; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.pkix.primitive.*; /** * A PKIX CertRequest. Currently can only be decoded from its BER * encoding. There are no methods for constructing one. */ public class CertRequest implements ASN1Value { private INTEGER certReqId; private CertTemplate certTemplate; private SEQUENCE controls; // may be null private CertRequest() { } /** * @param certReqId May NOT be null. * @param certTemplate May NOT be null. * @param controls May be null. */ public CertRequest(INTEGER certReqId, CertTemplate certTemplate, SEQUENCE controls) { if( certReqId == null ) { throw new NullPointerException("certReqId is null"); } this.certReqId = certReqId; if( certTemplate == null ) { throw new NullPointerException("certTemplate is null"); } this.certTemplate = certTemplate; this.controls = controls; } /** * Returns the certReqId (certificate request ID) field. */ public INTEGER getCertReqId() { return certReqId; } /** * Returns the CertTemplate field. */ public CertTemplate getCertTemplate() { return certTemplate; } /** * Returns the controls field. */ public SEQUENCE getControls() { return controls; } /** * Returns the number of optional Controls in the cert request. * The number may be zero. */ public int numControls() { if(controls == null) { return 0; } else { return controls.size(); } } /** * Returns the ith Control. i must be in the * range [0..numControls-1]. */ public AVA controlAt(int i) { if( controls == null ) { throw new ArrayIndexOutOfBoundsException(); } return (AVA) controls.elementAt(i); } /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// // DER-encoding /////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////// public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } /** * This method is not yet supported. */ public void encode(OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertRequest encoding"); encode(getTag(),ostream); } /** * This method is not yet supported. */ public void encode(Tag implicit, OutputStream ostream) throws IOException { //Assert.notYetImplemented("CertRequest encoding"); SEQUENCE sequence = new SEQUENCE(); sequence.addElement( certReqId ); sequence.addElement( certTemplate ); if (controls != null) sequence.addElement( controls ); sequence.encode(implicit,ostream); } /** * A Template class for constructing CertRequests from their * BER encoding. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqTemplate; public Template() { seqTemplate = new SEQUENCE.Template(); seqTemplate.addElement( new INTEGER.Template() ); seqTemplate.addElement( new CertTemplate.Template() ); seqTemplate.addOptionalElement( new SEQUENCE.OF_Template( new AVA.Template() )); } public boolean tagMatch( Tag tag ) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqTemplate.decode(implicit, istream); return new CertRequest( (INTEGER) seq.elementAt(0), (CertTemplate) seq.elementAt(1), (SEQUENCE) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/CertTemplate.java000066400000000000000000000374001326145000000233060ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.IOException; import org.mozilla.jss.util.Assert; import java.util.Date; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.Extension; import java.util.Calendar; import java.util.TimeZone; /** * This class models a CRMF CertTemplate structure. */ public class CertTemplate implements ASN1Value { // All of these may be null private INTEGER version; private INTEGER serialNumber; private AlgorithmIdentifier signingAlg; private Name issuer; private Date notBefore; private Date notAfter; private Name subject; private SubjectPublicKeyInfo publicKey; private BIT_STRING issuerUID; private BIT_STRING subjectUID; private SEQUENCE extensions; /** * Creates an empty CertTemplate. Use the accessor methods to fill it * up with stuff. */ public CertTemplate() { } /** * Returns true if the version field is present. */ public boolean hasVersion() { return (version!=null); } /** * Returns the version field of this CertTemplate. */ public INTEGER getVersion() { return version; } /** * Sets the version field of this CertTemplate. */ public void setVersion(INTEGER version) { this.version = version; } /** * Returns true if the serialNumber field is present. */ public boolean hasSerialNumber() { return (serialNumber!=null); } /** * Returns the serialNumber field of this CertTemplate. */ public INTEGER getSerialNumber() { return serialNumber; } /** * Sets the serialNumber field of this CertTemplate. */ public void setSerialNumber(INTEGER serialNumber) { this.serialNumber = serialNumber; } /** * Returns true if the signingAlg field is present. */ public boolean hasSigningAlg() { return (signingAlg!=null); } /** * Returns the signingAlg field of this CertTemplate. */ public AlgorithmIdentifier getSigningAlg() { return signingAlg; } /** * Sets the signingAlg field of this CertTemplate. */ public void setSigningAlg(AlgorithmIdentifier signingAlg) { this.signingAlg = signingAlg; } /** * Returns true if the issuer field is present. */ public boolean hasIssuer() { return (issuer!=null); } /** * Returns the issuer field of this CertTemplate. */ public Name getIssuer() { return issuer; } /** * Sets the issuer field of this CertTemplate. */ public void setIssuer(Name issuer) { this.issuer = issuer; } /** * Returns true if the notBefore field is present. */ public boolean hasNotBefore() { return (notBefore!=null); } /** * Returns the notBefore field of this CertTemplate. */ public Date getNotBefore() { return notBefore; } /** * Sets the version field of this CertTemplate. */ public void setNotBefore(Date date) { this.notBefore = date; } /** * Returns true if the notAfter field is present. */ public boolean hasNotAfter() { return (notAfter!=null); } /** * Returns the notAfter field of this CertTemplate. */ public Date getNotAfter() { return notAfter; } /** * Sets the notAfter field of this CertTemplate. */ public void setNotAfter(Date date) { this.notAfter = date; } /** * Returns true if the subject field is present. */ public boolean hasSubject() { return (subject!=null); } /** * Sets the subject field of this CertTemplate. */ public Name getSubject() { return subject; } /** * Sets the subject field of this CertTemplate. */ public void setSubject(Name subject) { this.subject = subject; } /** * Returns true if the publicKey field is present. */ public boolean hasPublicKey() { return (publicKey!=null); } /** * Returns the publicKey field of this CertTemplate. */ public SubjectPublicKeyInfo getPublicKey() { return publicKey; } /** * Sets the publicKey field of this CertTemplate. */ public void setPublicKey(SubjectPublicKeyInfo publicKey) { this.publicKey = publicKey; } /** * Returns true if the issuerUID field is present. */ public boolean hasIssuerUID() { return (issuerUID!=null); } /** * Returns the issuerUID field of this CertTemplate. */ public BIT_STRING getIssuerUID() { return issuerUID; } /** * Sets the issuerUID field of this CertTemplate. */ public void setIssuerUID(BIT_STRING issuerUID) { this.issuerUID = issuerUID; } /** * Returns true if the subjectUID field is present. */ public boolean hasSubjectUID() { return (subjectUID!=null); } /** * Returns the subjectUID field of this CertTemplate. */ public BIT_STRING getSubjectUID() { return subjectUID; } /** * Sets the subjectUID field of this CertTemplate. */ public void setSubjectUID(BIT_STRING subjectUID) { this.subjectUID = subjectUID; } /** * Returns true if the extensions field is present. */ public boolean hasExtensions() { return (extensions!=null); } /** * Sets the extensions field of this CertTemplate. */ public void setExtensions(SEQUENCE extensions) { this.extensions = extensions; } /** * Returns the number of extensions present in the template. May be zero. */ public int numExtensions() { if(extensions == null) { return 0; } else { return extensions.size(); } } /** * Returns the ith extension. * @param idx The index of the extension to retrieve. Must be in the * range [ 0, numExtensions()-1 ]. */ public Extension extensionAt(int idx) { if(extensions == null) { throw new ArrayIndexOutOfBoundsException(); } return (Extension) extensions.elementAt(idx); } public void print(PrintStream ps, int indentSpaces) throws InvalidBERException, IOException { StringBuffer indentBuf = new StringBuffer(); for(int i=0; i < indentSpaces; i++) { indentBuf.append(" "); } String indent = indentBuf.toString(); if(version!=null) { ps.println("Version: "+version.toString()); } if(serialNumber!=null) { ps.println("Serial Number: "+serialNumber.toString()); } if(signingAlg!=null) { ps.println("Signing Algorithm: "+signingAlg.getOID().toString()); } if(issuer!=null) { ps.println("Issuer: "+issuer.getRFC1485()); } if(notBefore!=null) { ps.println("Not Before: " + notBefore); } if(notAfter!=null) { ps.println("Not After: " + notAfter); } if(subject!=null) { ps.println("Subject: " + subject.getRFC1485()); } if(publicKey!=null) { ps.println("publicKey is present"); } if(issuerUID != null ) { ps.println("issuerUID is present"); } if(subjectUID != null ) { ps.println("subjectUID is present"); } if(extensions != null ) { ps.println("Extensions is present, with "+extensions.size()+ " elements"); } } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } // the last year for using UTCTime static final int UTCTIME_CUTOFF_YEAR = 2049; /** * Converts a Date into a UTCTime or GeneralizedTime, depending on * whether it falls before or after the cutoff date. */ private static TimeBase dateToASN1(Date d) { if(d==null) { return null; } Calendar cal = Calendar.getInstance( TimeZone.getTimeZone("GMT") ); cal.setTime(d); if( cal.get(Calendar.YEAR) <= UTCTIME_CUTOFF_YEAR) { return new UTCTime(d); } else { return new GeneralizedTime(d); } } public void encode(Tag t, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(Tag.get(0), version); seq.addElement(Tag.get(1), serialNumber); seq.addElement(Tag.get(2), signingAlg); if( issuer!=null ) { // issuer is a CHOICE, so it must be EXPLICITly tagged seq.addElement(new EXPLICIT(Tag.get(3), issuer )); } if( notBefore!=null || notAfter!=null ) { SEQUENCE optionalVal = new SEQUENCE(); // notBefore & notAfter are CHOICES, so must be EXPLICITly tagged if( notBefore!=null ) { optionalVal.addElement( new EXPLICIT( Tag.get(0), dateToASN1(notBefore) ) ); } if( notAfter!=null ) { optionalVal.addElement( new EXPLICIT( Tag.get(1), dateToASN1(notAfter) ) ); } seq.addElement(Tag.get(4), optionalVal); } if( subject!=null ) { // subject is a CHOICE, so it must be EXPLICITly tagged seq.addElement(new EXPLICIT(Tag.get(5), subject)); } seq.addElement(Tag.get(6), publicKey); seq.addElement(Tag.get(7), issuerUID); seq.addElement(Tag.get(8), subjectUID); seq.addElement(Tag.get(9), extensions); seq.encode(t, ostream); } private static Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A class for decoding CertTemplates. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } /** * Decodes a CertTemplate from its BER encoding. The return * value of this method */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { CHOICE.Template timeChoice = new CHOICE.Template(); timeChoice.addElement( new GeneralizedTime.Template() ); timeChoice.addElement( new UTCTime.Template() ); // optional validity. The times are CHOICEs, so they are // EXPLICITly tagged SEQUENCE.Template validity = new SEQUENCE.Template(); validity.addOptionalElement( new EXPLICIT.Template( Tag.get(0), timeChoice)); validity.addOptionalElement( new EXPLICIT.Template( Tag.get(1), timeChoice)); SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addOptionalElement( Tag.get(0), new INTEGER.Template() ); seqt.addOptionalElement( Tag.get(1), new INTEGER.Template() ); seqt.addOptionalElement( Tag.get(2), new AlgorithmIdentifier.Template() ); seqt.addOptionalElement( new EXPLICIT.Template(Tag.get(3), new Name.Template() )); seqt.addOptionalElement( Tag.get(4), validity ); seqt.addOptionalElement( new EXPLICIT.Template(Tag.get(5), new Name.Template() )); seqt.addOptionalElement( Tag.get(6), new SubjectPublicKeyInfo.Template() ); seqt.addOptionalElement( Tag.get(7), new BIT_STRING.Template() ); seqt.addOptionalElement( Tag.get(8), new BIT_STRING.Template() ); seqt.addOptionalElement( Tag.get(9), new SEQUENCE.OF_Template( new Extension.Template() ) ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); CertTemplate ct = new CertTemplate(); ct.setVersion( (INTEGER) seq.elementAt(0) ); ct.setSerialNumber( (INTEGER) seq.elementAt(1) ); ct.setSigningAlg( (AlgorithmIdentifier) seq.elementAt(2) ); if( seq.elementAt(3) != null ) { ct.setIssuer((Name)((EXPLICIT)seq.elementAt(3)).getContent() ); } // validity EXPLICIT explicit; CHOICE choice; ASN1Value val; if( seq.elementAt(4) != null ) { explicit = (EXPLICIT) ((SEQUENCE)seq.elementAt(4)).elementAt(0); if( explicit != null ) { choice = (CHOICE) explicit.getContent(); val = choice.getValue(); if( val instanceof TimeBase ) { ct.setNotBefore( ((TimeBase)val).toDate() ); } } explicit = (EXPLICIT) ((SEQUENCE)seq.elementAt(4)).elementAt(1); if( explicit != null ) { choice = (CHOICE) explicit.getContent(); val = choice.getValue(); if( val instanceof TimeBase ) { ct.setNotAfter( ((TimeBase)val).toDate() ); } } } if( seq.elementAt(5) != null ) { ct.setSubject((Name)((EXPLICIT)seq.elementAt(5)).getContent() ); } ct.setPublicKey( (SubjectPublicKeyInfo) seq.elementAt(6) ); ct.setIssuerUID( (BIT_STRING) seq.elementAt(7) ); ct.setSubjectUID( (BIT_STRING) seq.elementAt(8) ); ct.setExtensions( (SEQUENCE) seq.elementAt(9) ); return ct; } } public static void main(String args[]) { try { CertTemplate ct = new CertTemplate(); Name name; ct.setVersion(new INTEGER(5)); ct.setSerialNumber(new INTEGER(13112)); name = new Name(); name.addCommonName("You"); name.addStateOrProvinceName("California"); ct.setIssuer(name); ct.setNotBefore(new Date()); name = new Name(); name.addCommonName("Me"); name.addCountryName("US"); ct.setSubject(name); ct.setIssuerUID( new BIT_STRING( new byte[] {0x00, 0x01}, 0 ) ); System.out.println("Constructed CertTemplate:"); byte[] encoded = ASN1Util.encode(ct); java.io.FileOutputStream fos = new java.io.FileOutputStream("certTemplate"); fos.write(encoded); fos.close(); ct.print(System.out, 0); CertTemplate newCt = (CertTemplate) ASN1Util.decode( CertTemplate.getTemplate(), encoded ); System.out.println("\nDecoded CertTemplate:"); newCt.print(System.out, 0); } catch( Exception e ) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/ChallengeResponseException.java000066400000000000000000000024051326145000000261720ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; /** * An exception thrown when challenge response pop is requested. */ public class ChallengeResponseException extends java.lang.Exception { private ChallengeResponseException child=null; public ChallengeResponseException(String mesg) { super(mesg); } public ChallengeResponseException(ChallengeResponseException e, String mesg) { super(mesg); child = e; } /** * Prints out the exception class and error message, including * all the nested exceptions. */ public String toString() { if(child != null) { return (super.toString()+ " >> " + child.toStringNested()); } else { return super.toString(); } } /** * Prints out the error message of this exception, including all the * nested exceptions. */ public String toStringNested() { if(child != null) { return ( getMessage() + " >> " + child.toStringNested()); } else { return getMessage(); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/Control.java000066400000000000000000000066121326145000000223360ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.pkix.primitive.AVA; import org.mozilla.jss.util.Assert; /** * A CRMF Control. */ public class Control extends AVA implements ASN1Value { // general CRMF OIDs public static final OBJECT_IDENTIFIER id_pkix = new OBJECT_IDENTIFIER( new long[] { 1, 3, 6, 1, 5, 5, 7 } ); public static final OBJECT_IDENTIFIER id_pkip = id_pkix.subBranch( 5 ); public static final OBJECT_IDENTIFIER id_regCtrl = id_pkip.subBranch( 1 ); // Control OIDs public static final OBJECT_IDENTIFIER id_regCtrl_regToken = id_regCtrl.subBranch(1); public static final OBJECT_IDENTIFIER id_regCtrl_authenticator = id_regCtrl.subBranch(2); public static final OBJECT_IDENTIFIER id_regCtrl_pkiPublicationInfo = id_regCtrl.subBranch(3); public static final OBJECT_IDENTIFIER id_regCtrl_pkiArchiveOptions = id_regCtrl.subBranch(4); public static final OBJECT_IDENTIFIER id_regCtrl_oldCertID = id_regCtrl.subBranch(5); public static final OBJECT_IDENTIFIER id_regCtrl_protocolEncrKey = id_regCtrl.subBranch(6); public Control(OBJECT_IDENTIFIER oid, ASN1Value value) { super(oid, value); } /** * Returns the value of this control as a UTF8String, if it actually * is a UTF8String. */ public UTF8String getUTF8String() throws InvalidBERException { return (UTF8String) getValue().decodeWith(UTF8String.getTemplate()); } /** * Returns the value of this control as a PKIArchiveOptions, if it * actually is a PKIArchiveOptions. */ public PKIArchiveOptions getPKIArchiveOptions() throws InvalidBERException { return (PKIArchiveOptions) getValue().decodeWith( PKIArchiveOptions.getTemplate() ); } /** * Returns the value of this control as a PKIPublicationInfo, if it * actually is a PKIPublicationInfo. */ public PKIPublicationInfo getPKIPublicationInfo() throws InvalidBERException { return (PKIPublicationInfo) getValue().decodeWith( PKIPublicationInfo.getTemplate() ); } /** * A template class for decoding a Control from a BER stream. */ public static class Template extends AVA.Template implements ASN1Template { private SEQUENCE.Template seqTemplate; public Template() { seqTemplate = new SEQUENCE.Template(); seqTemplate.addElement( new OBJECT_IDENTIFIER.Template() ); seqTemplate.addElement( new ANY.Template() ); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqTemplate.decode(implicit, istream); OBJECT_IDENTIFIER oid = (OBJECT_IDENTIFIER) seq.elementAt(0); ANY any = (ANY) seq.elementAt(1); return new Control( oid, any ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/EncryptedKey.java000066400000000000000000000113001326145000000233120ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import java.io.*; public class EncryptedKey implements ASN1Value { /** * The type of EncryptedKey. */ public static class Type { private Type() { } static final Type ENCRYPTED_VALUE = new Type(); static final Type ENVELOPED_DATA = new Type(); } public static final Type ENCRYPTED_VALUE = Type.ENCRYPTED_VALUE; public static final Type ENVELOPED_DATA = Type.ENVELOPED_DATA; /////////////////////////////////////////////////////////////////////// // member and member access /////////////////////////////////////////////////////////////////////// private Type type; private EncryptedValue encryptedValue; private ANY envelopedData; public Type getType() { return type; } /** * Should only be called if getType returns * ENCRYPTED_VALUE. */ public EncryptedValue getEncryptedValue() { return encryptedValue; } /** * Should only be called if getType returns * ENVELOPED_DATA. ANY is returned to prevent a circular * dependency between the org.mozilla.jss.pkcs7 package and the * org.mozilla.jss.pkix hierarchy. */ public ANY getEnvelopedData() { return envelopedData; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private EncryptedKey() { } public EncryptedKey(EncryptedValue encryptedValue) { this.type = ENCRYPTED_VALUE; this.encryptedValue = encryptedValue; this.tag = SEQUENCE.TAG; } public EncryptedKey(ANY envelopedData) { this.type = ENVELOPED_DATA; this.envelopedData = envelopedData; this.tag = new Tag(0); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private Tag tag; // set by constructor based on type public Tag getTag() { return tag; } public void encode(OutputStream ostream) throws IOException { encode(getTag(), ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // no IMPLICIT tags allowed on ANY Assert._assert( getTag().equals(implicitTag)); if( type == ENCRYPTED_VALUE ) { Assert._assert( encryptedValue != null ); encryptedValue.encode(implicitTag, ostream); } else { Assert._assert(type == ENVELOPED_DATA); Assert._assert(envelopedData != null); envelopedData.encode(implicitTag, ostream); } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding BER-encoded EncryptedKeys. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( EncryptedValue.getTemplate() ); choicet.addElement( new Tag(0), ANY.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { try { CHOICE choice = (CHOICE) choicet.decode(istream); if( choice.getTag().equals(SEQUENCE.TAG) ) { return new EncryptedKey( (EncryptedValue) choice.getValue() ); } else { Assert._assert( choice.getTag().equals(new Tag(0)) ); return new EncryptedKey( (ANY) choice.getValue() ); } } catch(InvalidBERException e) { throw new InvalidBERException(e, "EncryptedKey"); } } /** * @param implicitTag This parameter is ignored, because a CHOICE * cannot have an implicitTag. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { Assert.notReached("EncryptedKey, being a CHOICE, cannot be"+ " implicitly tagged"); return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/EncryptedValue.java000066400000000000000000000135611326145000000236510ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.pkix.primitive.*; /** * The CRMF structure EncryptedValue for storing the encrypted * key to be archived. */ public class EncryptedValue implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private AlgorithmIdentifier intendedAlg; // may be null private AlgorithmIdentifier symmAlg; // may be null private BIT_STRING encSymmKey; // may be null private AlgorithmIdentifier keyAlg; // may be null private OCTET_STRING valueHint; // may be null private BIT_STRING encValue; // may be null private SEQUENCE sequence; /** * May return null. */ public AlgorithmIdentifier getIntendedAlg() { return intendedAlg; } /** * May return null. */ public AlgorithmIdentifier getSymmAlg() { return symmAlg; } /** * May return null. */ public BIT_STRING getEncSymmKey() { return encSymmKey; } /** * May return null. */ public AlgorithmIdentifier getKeyAlg() { return keyAlg; } /** * May return null. */ public OCTET_STRING getValueHint() { return valueHint; } public BIT_STRING getEncValue() { return encValue; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private EncryptedValue() { } /** * @param intendedAlg May be null. * @param symmAlg May be null. * @param encSymmKey May be null. * @param keyAlg May be null. * @param valueHint May be null. * @param encValue May not be null. */ public EncryptedValue( AlgorithmIdentifier intendedAlg, AlgorithmIdentifier symmAlg, BIT_STRING encSymmKey, AlgorithmIdentifier keyAlg, OCTET_STRING valueHint, BIT_STRING encValue ) { if( encValue == null ) { throw new IllegalArgumentException("encValue is null"); } this.intendedAlg = intendedAlg; this.symmAlg = symmAlg; this.encSymmKey = encSymmKey; this.keyAlg = keyAlg; this.valueHint = valueHint; this.encValue = encValue; sequence = new SEQUENCE(); if(intendedAlg!=null) { sequence.addElement( new Tag(0), intendedAlg ); } if( symmAlg!=null ) { sequence.addElement( new Tag(1), symmAlg ); } if( encSymmKey!=null ) { sequence.addElement( new Tag(2), encSymmKey ); } if( keyAlg!=null ) { sequence.addElement( new Tag(3), keyAlg ); } if( valueHint!=null ) { sequence.addElement( new Tag(4), valueHint ); } sequence.addElement(encValue); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template class for decoding BER-encoded EncryptedValues. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addOptionalElement( new Tag(0), AlgorithmIdentifier.getTemplate()); seqt.addOptionalElement( new Tag(1), AlgorithmIdentifier.getTemplate()); seqt.addOptionalElement( new Tag(2), BIT_STRING.getTemplate()); seqt.addOptionalElement( new Tag(3), AlgorithmIdentifier.getTemplate()); seqt.addOptionalElement( new Tag(4), OCTET_STRING.getTemplate()); seqt.addElement( BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { try { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new EncryptedValue( (AlgorithmIdentifier) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (BIT_STRING) seq.elementAt(2), (AlgorithmIdentifier) seq.elementAt(3), (OCTET_STRING) seq.elementAt(4), (BIT_STRING) seq.elementAt(5) ); } catch(InvalidBERException e ) { throw new InvalidBERException(e, "EncryptedValue"); } } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/PKIArchiveOptions.java000066400000000000000000000152611326145000000242170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.util.Assert; public class PKIArchiveOptions implements ASN1Value { /** * A type of PKIArchiveOption. */ public static class Type { private Type() { } static final Type ENCRYPTED_PRIV_KEY = new Type(); static final Type KEY_GEN_PARAMETERS = new Type(); static final Type ARCHIVE_REM_GEN_PRIV_KEY = new Type(); } public static final Type ENCRYPTED_PRIV_KEY = Type.ENCRYPTED_PRIV_KEY; public static final Type KEY_GEN_PARAMETERS = Type.KEY_GEN_PARAMETERS; public static final Type ARCHIVE_REM_GEN_PRIV_KEY = Type.ARCHIVE_REM_GEN_PRIV_KEY; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private EncryptedKey encryptedPrivKey; private OCTET_STRING keyGenParameters; private boolean archiveRemGenPrivKey; private Type type; /** * Returns the type of PKIArchiveOptions. */ public Type getType() { return type; } /** * Returns the encrypted key. Should only be called if the type * is ENCRYPTED_PRIV_KEY. */ public EncryptedKey getEncryptedKey( ) { Assert._assert(type == ENCRYPTED_PRIV_KEY); return encryptedPrivKey; } /** * Returns the key gen parameters. Should only be called if the type * is KEY_GEN_PARAMETERS. public byte[] getKeyGenParameters( ) { Assert._assert(type == KEY_GEN_PARAMETERS); return keyGenParameters; } /** * Returns the archiveRemGenPrivKey field, which indicates that * the sender wishes the receiver to generate and archive a key pair. * Should only be called if the type is * ARCHIVE_REM_GEN_PRIV_KEY. */ public boolean getArchiveRemGenPrivKey( ) { Assert._assert( type == ARCHIVE_REM_GEN_PRIV_KEY ); return archiveRemGenPrivKey; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private PKIArchiveOptions() { } public PKIArchiveOptions( EncryptedKey eKey ) { encryptedPrivKey = eKey; type = ENCRYPTED_PRIV_KEY; tag = new Tag(0); } public PKIArchiveOptions( byte[] keyGenParameters ) { this.keyGenParameters = new OCTET_STRING(keyGenParameters); type = KEY_GEN_PARAMETERS; tag = new Tag(1); } public PKIArchiveOptions( boolean archiveRemGenPrivKey ) { this.archiveRemGenPrivKey = archiveRemGenPrivKey; type = ARCHIVE_REM_GEN_PRIV_KEY; tag = new Tag(2); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private Tag tag; // set by the constructor depending on the type public Tag getTag() { return tag; } /** * DER-encodes a PKIArchiveOptions. */ public void encode(OutputStream ostream) throws IOException { encode( getTag(), ostream ); } /** * DER-encodes a PKIArchiveOptions. * @param implicitTag This parameter is ignored. A CHOICE cannot * have an implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { // no implicit tags on a CHOICE Assert._assert( implicitTag.equals(tag) ); if( type == ENCRYPTED_PRIV_KEY ) { // CHOICEs are always EXPLICITly tagged EXPLICIT explicit = new EXPLICIT( new Tag(0), encryptedPrivKey ); explicit.encode(tag, ostream); } else if( type == KEY_GEN_PARAMETERS ) { keyGenParameters.encode(tag, ostream); } else { Assert._assert( type == ARCHIVE_REM_GEN_PRIV_KEY ); (new BOOLEAN(archiveRemGenPrivKey)).encode(tag, ostream); } } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template for decoding PKIArchiveOptions. */ public static class Template implements ASN1Template { CHOICE.Template template; public Template() { template = new CHOICE.Template(); // CHOICEs are always EXPLICIT template.addElement( new EXPLICIT.Template( new Tag(0), new EncryptedKey.Template() )); template.addElement( new Tag(1), new OCTET_STRING.Template() ); template.addElement( new Tag(2), new BOOLEAN.Template() ); } /** * Returns true if the given tag can satisfy this CHOICE. */ public boolean tagMatch(Tag tag) { return template.tagMatch(tag); } /** * Decodes a PKIArchiveOptions. * @return A PKIArchiveOptions object. */ public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { CHOICE choice = (CHOICE) template.decode(istream); if( choice.getTag().getNum() == 0 ) { EncryptedKey ekey = (EncryptedKey) ((EXPLICIT)choice.getValue()).getContent(); return new PKIArchiveOptions(ekey); } else if( choice.getTag().getNum() == 1 ) { OCTET_STRING kgp = (OCTET_STRING) choice.getValue(); return new PKIArchiveOptions(kgp.toByteArray()); } else if( choice.getTag().getNum() == 2 ) { BOOLEAN arckey = (BOOLEAN) choice.getValue(); return new PKIArchiveOptions(arckey.toBoolean()); } else { String s = "Unrecognized tag in PKIArchiveOptions"; Assert.notReached(s); throw new InvalidBERException(s); } } /** * Decodes a PKIArchiveOptions. * @param implicitTag This parameter is ignored. Since * PKIArchiveOptions is a CHOICE, it cannot have an implicit tag. * @return A PKIArchiveOptions object. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/PKIPublicationInfo.java000066400000000000000000000120341326145000000243420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.*; /** * CRMF PKIPublicationInfo: *
 * PKIPublicationInfo ::= SEQUENCE {
 *      action          INTEGER {
 *          dontPublish     (0),
 *          pleasePublish   (1) },
 *      pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL }
 *
 * SinglePubInfo ::= SEQUENCE {
 *      pubMethod       INTEGER {
 *          dontCare    (0),
 *          x500        (1),
 *          web         (2),
 *          ldap        (3) },
 *      pubLocation     GeneralName OPTIONAL }
 * 
*/ public class PKIPublicationInfo implements ASN1Value { /** * A PKIPublicationInfo action. */ public static final int DONT_PUBLISH = 0; /** * A PKIPublicationInfo action. */ public static final int PLEASE_PUBLISH = 1; /** * A SinglePubInfo publication method. */ public static final int DONT_CARE = 0; /** * A SinglePubInfo publication method. */ public static final int X500 = 1; /** * A SinglePubInfo publication method. */ public static final int WEB = 2; /** * A SinglePubInfo publication method. */ public static final int LDAP = 3; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private int action; private SEQUENCE pubInfos; // may be null /** * Returns the action field. */ public int getAction() { return action; } /** * Returns the number of SinglePubInfos. May be zero. */ public int numPubInfos() { if( pubInfos == null ) { return 0; } else { return pubInfos.size(); } } /** * Returns the pubMethod in the SinglePubInfo at the given index. * Should return DONT_CARE, X500, WEB, or LDAP. */ public int getPubMethod(int index) { return ((INTEGER)((SEQUENCE)pubInfos.elementAt(index)). elementAt(0)).intValue(); } /** * Returns the pubLocation in the SinglePubInfo at the given index. * May return null, since pubLocation is an optional field. */ public ANY getPubLocation(int index) { return (ANY) ((SEQUENCE)pubInfos.elementAt(index)).elementAt(1); } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private PKIPublicationInfo() { } /** * Creates a new PKIPublicationInfo. * @param action DONT_PUBLISH or PLEASE_PUBLISH. * @param pubInfos A SEQUENCE of SinglePubInfo, may be null. */ public PKIPublicationInfo(int action, SEQUENCE pubInfos) { this.action = action; this.pubInfos = pubInfos; } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement( new INTEGER(action) ); seq.addElement( pubInfos ); seq.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a PKIPublicationInfo. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); SEQUENCE.Template pubInfot = new SEQUENCE.Template(); pubInfot.addElement(INTEGER.getTemplate()); pubInfot.addOptionalElement(ANY.getTemplate()); seqt.addOptionalElement( new SEQUENCE.OF_Template(pubInfot) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new PKIPublicationInfo( ((INTEGER)seq.elementAt(0)).intValue(), (SEQUENCE) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/POPOPrivKey.java000066400000000000000000000161611326145000000230050ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import java.io.*; /** * CRMF POPOPrivKey: *
 * POPOPrivKey ::= CHOICE {
 *      thisMessage         [0] BIT STRING,
 *      subsequentMessage   [1] SubsequentMessage,
 *      dhMAC               [2] BIT STRING }
 *
 * SubsequentMessage ::= INTEGER {
 *      encrCert        (0),
 *      challengeResp   (1) }
 * 
*/ public class POPOPrivKey implements ASN1Value { /** * The type of POPOPrivKey. */ public static class Type { private Type() { } static final Type THIS_MESSAGE = new Type(); static final Type SUBSEQUENT_MESSAGE = new Type(); static final Type DHMAC = new Type(); } public static final Type THIS_MESSAGE = Type.THIS_MESSAGE; public static final Type SUBSEQUENT_MESSAGE = Type.SUBSEQUENT_MESSAGE; public static final Type DHMAC = Type.DHMAC; /** * The SubsequentMessage field is encrCert. */ public static final int ENCR_CERT = 0; /** * The SubsequentMessage field is challengeResp. */ public static final int CHALLENGE_RESP = 1; /////////////////////////////////////////////////////////////////////// // Members and member access /////////////////////////////////////////////////////////////////////// private Type type; private BIT_STRING thisMessage; // if type == THIS_MESSAGE private INTEGER subsequentMessage; // if type == SUBSEQUENT_MESSAGE private BIT_STRING dhMAC; // if type == DHMAC /** * Returns the type of POPOPrivKey: THIS_MESSAGE, SUBSEQUENT_MESSAGE, * or DHMAC. */ public Type getType() { return type; } /** * If type==THIS_MESSAGE, returns the thisMessage field. Otherwise, * returns null. */ public BIT_STRING getThisMessage() { return thisMessage; } /** * If type==SUBSEQUENT_MESSAGE, returns the subsequentMessage field. * Otherwise, returns null. The return value can be converted to an * integer and compared with ENCR_CERT and CHALLENGE_RESP. */ public INTEGER getSubsequentMessage() { return subsequentMessage; } /** * If type==DHMAC, returns the dhMAC field. Otherwise, returns null. */ public BIT_STRING getDhMAC() { return dhMAC; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private POPOPrivKey() { } private POPOPrivKey(Type type, BIT_STRING thisMessage, INTEGER subsequentMessage, BIT_STRING dhMAC) { this.type = type; this.thisMessage = thisMessage; this.subsequentMessage = subsequentMessage; this.dhMAC = dhMAC; } /** * Creates a new POPOPrivKey with the given thisMessage field. */ public static POPOPrivKey createThisMessage(BIT_STRING thisMessage) { return new POPOPrivKey(THIS_MESSAGE, thisMessage, null, null); } /** * Creates a new POPOPrivKey with the given subsequentMessage field. */ public static POPOPrivKey createSubsequentMessage(int subsequentMessage) { if(subsequentMessage!=ENCR_CERT && subsequentMessage!=CHALLENGE_RESP) { throw new IllegalArgumentException( "Illegal subsequentMessage value: " + subsequentMessage ); } return new POPOPrivKey(SUBSEQUENT_MESSAGE, null, new INTEGER(subsequentMessage), null); } /** * Creates a new POPOPrivKey with the given dhMAC field. */ public static POPOPrivKey createDhMAC(BIT_STRING dhMAC) { return new POPOPrivKey(DHMAC, null, null, dhMAC); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if(type == THIS_MESSAGE) { return Tag.get(0); } else if(type == SUBSEQUENT_MESSAGE) { return Tag.get(1); } else { Assert._assert(type == DHMAC); return Tag.get(2); } } public void encode(OutputStream ostream) throws IOException { if(type == THIS_MESSAGE) { thisMessage.encode(Tag.get(0), ostream); } else if(type == SUBSEQUENT_MESSAGE) { subsequentMessage.encode(Tag.get(1), ostream); } else { Assert._assert(type == DHMAC); dhMAC.encode(Tag.get(2), ostream); } } /** * Should not be called, because POPOPrivKey is a CHOICE and cannot have * an implicit tag. */ public void encode(Tag implicitTag, OutputStream ostream) throws IOException { Assert.notReached( "POPOPrivKey is a CHOICE and cannot have an implicit tag"); encode(ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding a POPOPrivKey. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( Tag.get(0), BIT_STRING.getTemplate() ); choicet.addElement( Tag.get(1), INTEGER.getTemplate() ); choicet.addElement( Tag.get(2), BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } /** * Should not be called, because POPOPrivKey is a CHOICE and cannot * have an implicit tag. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { Assert.notReached( "POPOPrivKey is a CHOICE and cannot have an implicitTag"); return decode(istream); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE choice = (CHOICE) choicet.decode(istream); Tag chosen = choice.getTag(); if( chosen.equals(Tag.get(0)) ) { return createThisMessage( (BIT_STRING) choice.getValue() ); } else if( chosen.equals(Tag.get(1)) ) { INTEGER I = (INTEGER) choice.getValue(); int i = I.intValue(); if( i != ENCR_CERT && i != CHALLENGE_RESP ) { throw new InvalidBERException( "SubsequentMessage has invalid value: "+i); } return createSubsequentMessage( i ); } else { Assert._assert( chosen.equals(Tag.get(2)) ); return createDhMAC( (BIT_STRING) choice.getValue() ); } } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/POPOSigningKey.java000066400000000000000000000104041326145000000234550ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import java.io.*; /** * CRMF POPOSigningKey: *
 * POPOSigningKey ::= SEQUENCE {
 *      poposkInput         [0] POPOSigningKeyInput OPTIONAL,
 *      algorithmIdentifier AlgorithmIdentifier,
 *      signature           BIT STRING }
 * 
*/ public class POPOSigningKey implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private ANY poposkInput; // may be null private AlgorithmIdentifier algorithmIdentifier; private BIT_STRING signature; private SEQUENCE sequence; /** * Retrieves the input to the Proof-of-Possession of the signing key. * May return null, because this field is optional. Returns an ANY * because this type is not currently parsed. */ public ANY getPoposkInput() { return poposkInput; } /** * Retrieves the algorithm identifier for the signature. */ public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithmIdentifier; } /** * Retrieves the signature. */ public BIT_STRING getSignature() { return signature; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private POPOSigningKey() { } /** * Creates a POPOSigningKey. * @param poposkInput May be null. */ public POPOSigningKey(ANY poposkInput, AlgorithmIdentifier algorithmIdentifier, BIT_STRING signature) { if(algorithmIdentifier==null || signature==null) { throw new IllegalArgumentException("parameter to POPOSigningKey"+ " constructor is null"); } this.poposkInput = poposkInput; this.algorithmIdentifier = algorithmIdentifier; this.signature = signature; sequence = new SEQUENCE(); sequence.addElement( Tag.get(0), poposkInput ); sequence.addElement( algorithmIdentifier ); sequence.addElement( signature ); } /////////////////////////////////////////////////////////////////////// // encoding/decoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(TAG, ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A Template for decoding POPOSigningKey. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addOptionalElement( new EXPLICIT.Template( Tag.get(0), ANY.getTemplate()) ); seqt.addElement( AlgorithmIdentifier.getTemplate()); seqt.addElement( BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new POPOSigningKey( (ANY) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (BIT_STRING) seq.elementAt(2) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/ProofOfPossession.java000066400000000000000000000161471326145000000243620ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.crmf; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.util.Assert; /** * CRMF ProofOfPossession: *
 * ProofOfPossession ::= CHOICE {
 *      raVerified          [0] NULL,
 *      signature           [1] POPOSigningKey,
 *      keyEncipherment     [2] POPOPrivKey,
 *      keyAgreement        [3] POPOPrivKey }
 * 
*/ public class ProofOfPossession implements ASN1Value { /** * The type of ProofOfPossesion. */ public static class Type { private Type() { } static Type RA_VERIFIED = new Type(); static Type SIGNATURE = new Type(); static Type KEY_ENCIPHERMENT = new Type(); static Type KEY_AGREEMENT = new Type(); } public static Type RA_VERIFIED = Type.RA_VERIFIED; public static Type SIGNATURE = Type.SIGNATURE; public static Type KEY_ENCIPHERMENT = Type.KEY_ENCIPHERMENT; public static Type KEY_AGREEMENT = Type.KEY_AGREEMENT; /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private Type type; private POPOSigningKey signature; // if type == SIGNATURE private POPOPrivKey keyEncipherment; // if type == KEY_ENCIPHERMENT private POPOPrivKey keyAgreement; // if type == KEY_AGREEMENT /** * Returns the type of ProofOfPossesion:
    *
  • RA_VERIFIED *
  • SIGNATURE *
  • KEY_ENCIPHERMENT *
  • KEY_AGREEMENT *
*/ public Type getType() { return type; } /** * If type == SIGNATURE, returns the signature field. Otherwise, * returns null. */ public POPOSigningKey getSignature() { return signature; } /** * If type == KEY_ENCIPHERMENT, returns the keyEncipherment field. * Otherwise, returns null. */ public POPOPrivKey getKeyEncipherment() { return keyEncipherment; } /** * If type == KEY_AGREEMENT, returns the keyAgreement field. Otherwise, * returns null. */ public POPOPrivKey getKeyAgreement() { return keyAgreement; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private ProofOfPossession() { } private ProofOfPossession(Type type, POPOSigningKey signature, POPOPrivKey keyEncipherment, POPOPrivKey keyAgreement) { this.type = type; this.signature = signature; this.keyEncipherment = keyEncipherment; this.keyAgreement = keyAgreement; } /** * Creates a new ProofOfPossesion with an raVerified field. */ public static ProofOfPossession createRaVerified() { return new ProofOfPossession( RA_VERIFIED, null, null, null ); } /** * Creates a new ProofOfPossesion with the given signature field. */ public static ProofOfPossession createSignature(POPOSigningKey signature) { return new ProofOfPossession( SIGNATURE, signature, null, null ); } /** * Creates a new ProofOfPossesion with the given keyEncipherment field. */ public static ProofOfPossession createKeyEncipherment(POPOPrivKey keyEncipherment) { return new ProofOfPossession( KEY_ENCIPHERMENT, null, keyEncipherment, null ); } /** * Creates a new ProofOfPossesion with the given keyAgreement field. */ public static ProofOfPossession createKeyAgreement(POPOPrivKey keyAgreement) { return new ProofOfPossession( KEY_AGREEMENT, null, null, keyAgreement ); } /////////////////////////////////////////////////////////////////////// // decoding/encoding /////////////////////////////////////////////////////////////////////// public Tag getTag() { if( type == RA_VERIFIED ) { return Tag.get(0); } else if( type == SIGNATURE ) { return Tag.get(1); } else if( type == KEY_ENCIPHERMENT ) { return Tag.get(2); } else { Assert._assert( type == KEY_AGREEMENT ); return Tag.get(3); } } public void encode(OutputStream ostream) throws IOException { if( type == RA_VERIFIED ) { (new NULL()).encode(Tag.get(0), ostream); } else if( type == SIGNATURE ) { signature.encode(Tag.get(1), ostream); } else if( type == KEY_ENCIPHERMENT ) { // a CHOICE must be explicitly tagged EXPLICIT e = new EXPLICIT( Tag.get(2), keyEncipherment ); e.encode(ostream); } else { Assert._assert( type == KEY_AGREEMENT ); // a CHOICE must be explicitly tagged EXPLICIT e = new EXPLICIT( Tag.get(3), keyAgreement ); e.encode(ostream); } } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { Assert._assert(implicitTag.equals(getTag())); encode(ostream); } /** * A Template for decoding a ProofOfPossession. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( Tag.get(0), NULL.getTemplate() ); choicet.addElement( Tag.get(1), POPOSigningKey.getTemplate() ); EXPLICIT.Template et = new EXPLICIT.Template( Tag.get(2), POPOPrivKey.getTemplate() ); choicet.addElement( et ); et = new EXPLICIT.Template( Tag.get(3), POPOPrivKey.getTemplate() ); choicet.addElement( et ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { CHOICE c = (CHOICE) choicet.decode(istream); if( c.getTag().equals(Tag.get(0)) ) { return createRaVerified(); } else if( c.getTag().equals(Tag.get(1)) ) { return createSignature( (POPOSigningKey) c.getValue() ); } else if( c.getTag().equals(Tag.get(2)) ) { EXPLICIT e = (EXPLICIT) c.getValue(); return createKeyEncipherment( (POPOPrivKey) e.getContent() ); } else { Assert._assert( c.getTag().equals(Tag.get(3)) ); EXPLICIT e = (EXPLICIT) c.getValue(); return createKeyAgreement( (POPOPrivKey) e.getContent() ); } } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { Assert.notReached("A CHOICE cannot be implicitly tagged"); return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/crmf/package.html000066400000000000000000000004121326145000000223240ustar00rootroot00000000000000 The PKIX CRMF protocol. jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/000077500000000000000000000000001326145000000211275ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/AVA.java000066400000000000000000000053661326145000000224130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; /** * An AttributeValueAssertion, which has the following ASN.1 * definition (roughly): *
 *      AttributeValueAssertion ::= SEQUENCE {
 *          type        OBJECT IDENTIFIER,
 *          value       ANY DEFINED BY type }
 * 
*/ public class AVA implements ASN1Value { private OBJECT_IDENTIFIER oid; private ANY value; public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private AVA() { } public AVA(OBJECT_IDENTIFIER oid, ASN1Value value) { this.oid = oid; if( value instanceof ANY ) { this.value = (ANY) value; } else { byte[] encoded = ASN1Util.encode(value); try { this.value = (ANY) ASN1Util.decode(ANY.getTemplate(), encoded); } catch( InvalidBERException e ) { Assert.notReached("InvalidBERException while decoding as ANY"); } } } public OBJECT_IDENTIFIER getOID() { return oid; } /** * Returns the value of this AVA, encoded as an ANY. */ public ANY getValue() { return value; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(oid); seq.addElement(value); seq.encode(implicit, ostream); } /** * A Template for decoding an AVA. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement( new OBJECT_IDENTIFIER.Template() ); seqt.addElement( new ANY.Template() ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this Assert._assert(seq.size() == 2); return new AVA( (OBJECT_IDENTIFIER) seq.elementAt(0), seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/AlgorithmIdentifier.java000066400000000000000000000063411326145000000257270ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; public class AlgorithmIdentifier implements ASN1Value { private OBJECT_IDENTIFIER oid; private ASN1Value parameters=null; private SEQUENCE sequence = new SEQUENCE(); public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } /** * Creates an AlgorithmIdentifier with no parameter. */ public AlgorithmIdentifier(OBJECT_IDENTIFIER oid) { this.oid = oid; sequence.addElement( oid ); } /** * Creates an AlgorithmIdentifier. * * @param parameters The algorithm parameters. A value of null * will be encoded with an ASN.1 NULL. */ public AlgorithmIdentifier(OBJECT_IDENTIFIER oid, ASN1Value parameters) { this.oid = oid; sequence.addElement( oid ); this.parameters = parameters; if( parameters != null ) { sequence.addElement(parameters); } else { sequence.addElement(new NULL()); } } public OBJECT_IDENTIFIER getOID() { return oid; } /** * If this instance was constructed, returns the * parameter passed in to the constructor. If this instance was * decoded from a template, returns an ANY that was read from the * BER stream. In either case, it will return null if no parameters * were supplied. */ public ASN1Value getParameters() { return parameters; } private static final AlgorithmIdentifier.Template templateInstance = new AlgorithmIdentifier.Template(); public static AlgorithmIdentifier.Template getTemplate() { return templateInstance; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { sequence.encode(implicit, ostream); } public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement( new OBJECT_IDENTIFIER.Template() ); seqt.addOptionalElement( new ANY.Template() ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // the template should have enforced this Assert._assert( seq.size() == 2 ); return new AlgorithmIdentifier( (OBJECT_IDENTIFIER)seq.elementAt(0), // OID seq.elementAt(1) // parameters ); } } // end of Template } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/Attribute.java000066400000000000000000000055231326145000000237420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; /** * An Attribute, which has the following ASN.1 * definition (roughly): *
 *      Attribute ::= SEQUENCE {
 *          type        OBJECT IDENTIFIER,
 *          value       SET }
 * 
*/ public class Attribute implements ASN1Value { private OBJECT_IDENTIFIER type; private SET values; public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } private Attribute() { } public Attribute(OBJECT_IDENTIFIER type, SET values) { this.type = type; this.values = values; } public Attribute(OBJECT_IDENTIFIER type, ASN1Value value) { this.type = type; this.values = new SET(); values.addElement(value); } public OBJECT_IDENTIFIER getType() { return type; } /** * If this AVA was constructed, returns the SET of ASN1Values passed to the * constructor. If this Attribute was decoded with an Attribute.Template, * returns a SET of ANYs. */ public SET getValues() { return values; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement(type); seq.addElement(values); seq.encode(implicit, ostream); } public static Template getTemplate() { return templateInstance; } private static Template templateInstance = new Template(); /** * A Template for decoding an Attribute. */ public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.Template seqt = new SEQUENCE.Template(); seqt.addElement( new OBJECT_IDENTIFIER.Template() ); seqt.addElement( new SET.OF_Template(new ANY.Template())); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); // The template should have enforced this Assert._assert(seq.size() == 2); return new Attribute( (OBJECT_IDENTIFIER) seq.elementAt(0), (SET) seq.elementAt(1)); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/DirectoryString.java000066400000000000000000000124051326145000000251270ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.Assert; import java.io.CharConversionException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * An X.500 DirectoryString. * DirectoryString is defined as follows: *
 * DirectoryString ::= CHOICE {
 *      teletexString               TeletexString (SIZE (1..MAX)),
 *      printableString             PrintableString (SIZE (1..MAX)),
 *      universalString             UniversalString (SIZE (1..MAX)),
 *      utf8String                  UTF8String (SIZE (1..MAX)),
 *      bmpString                   BMPString (SIZE (1..MAX))  }
 * 
*/ public class DirectoryString implements ASN1Value { private DirectoryString() { } private CharacterString asn1String; /** * Encodes a Java String into a Directory String. * The following rules for choosing an encoding are from the * IETF * PKIX document Internet X.509 Public Key Infrastructure: * Certificate and CRL Profile:
    *
  • The preferred encoding is UTF8String, and all certificates * issued after December 31, 2003, MUST use UTF8String encoding, * with a few exceptions. *
  • Until December 31, 2003, strings that fit in the PrintableString * character set MAY use PrintableString. *
  • Until December 31, 2003, string that fit in the BMPString character * set MAY use BMPString. *
  • Strings that fit in neither the PrintableString nor the BMPString * character set MUST use UTF8String. *
* This is all very nice, but for backwards compatibility, what we really * do is:
    *
  • Try PrintableString *
  • Try TeletexString *
  • Try UniversalString *
*/ public DirectoryString(String s) throws CharConversionException { try { try { asn1String = new PrintableString(s); } catch( CharConversionException e ) { asn1String = new TeletexString(s); } } catch( CharConversionException e ) { asn1String = new UniversalString(s); } } /** * Creates a DirectoryString from an ASN.1 string. * @param s Must be a TeletexString, PrintableString, UniversalString, * UTF8String, or BMPString. */ public DirectoryString(CharacterString s) { if( !(s instanceof PrintableString ) && !(s instanceof BMPString) && !(s instanceof UTF8String) && !(s instanceof TeletexString) && !(s instanceof UniversalString) ) { throw new IllegalArgumentException("DirectoryString must be "+ "TeletexString, PrintableString, UniversalString, UTF8STring,"+ " or BMPString"); } asn1String = s; } /** * Converts an ASN.1 DirectoryString to a Java string. */ public String toString() { return asn1String.toString(); } public Tag getTag() { return asn1String.getTag(); } public void encode(OutputStream ostream) throws IOException { asn1String.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { asn1String.encode(implicitTag, ostream); } /** * Returns a singleton instance of the decoding template for this class. */ public static Template getTemplate() { return templateInstance; } private static final Template templateInstance = new Template(); /** * A Template for decoding DirectoryStrings from their BER encoding. */ public static class Template implements ASN1Template { private CHOICE.Template choicet; public Template() { choicet = new CHOICE.Template(); choicet.addElement( PrintableString.getTemplate() ); choicet.addElement( BMPString.getTemplate() ); choicet.addElement( UTF8String.getTemplate() ); choicet.addElement( TeletexString.getTemplate() ); choicet.addElement( UniversalString.getTemplate() ); } public boolean tagMatch(Tag tag) { return choicet.tagMatch(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { CHOICE choice = (CHOICE) choicet.decode(istream); return new DirectoryString( (CharacterString) choice.getValue()); } /** * @param implicitTag This parameter is ignored, because * DirectoryStrings (being CHOICEs) cannot have implicit tags. * @exception InvalidBERException If the encoding does not contain a * valid DirectoryString. */ public ASN1Value decode(Tag implicitTag, InputStream istream) throws IOException, InvalidBERException { Assert._assert( tagMatch(implicitTag) ); return decode(istream); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/EncryptedPrivateKeyInfo.java000066400000000000000000000425561326145000000265630ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.Assert; import java.security.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.Password; import org.mozilla.jss.crypto.PrivateKey; import java.security.spec.AlgorithmParameterSpec; /** * PKCS #8 EncryptedPrivateKeyInfo. *
 * EncryptedPrivateKeyInfo ::= SEQUENCE {
 *      encryptionAlgorithm     AlgorithmIdentifier,
 *      encryptedData           OCTET STRING }
 * 
*/ public class EncryptedPrivateKeyInfo implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private AlgorithmIdentifier encryptionAlgorithm; private OCTET_STRING encryptedData; private SEQUENCE sequence; public AlgorithmIdentifier getEncryptionAlgorithm() { return encryptionAlgorithm; } public OCTET_STRING getEncryptedData() { return encryptedData; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private EncryptedPrivateKeyInfo() { } /** * Creates an EncryptedPrivateKeyInfo from its components. * */ public EncryptedPrivateKeyInfo( AlgorithmIdentifier encryptionAlgorithm, OCTET_STRING encryptedData) { if( encryptionAlgorithm==null || encryptedData==null ) { throw new IllegalArgumentException( "EncryptedPrivateKeyInfo parameter is null"); } this.encryptionAlgorithm = encryptionAlgorithm; this.encryptedData = encryptedData; sequence = new SEQUENCE(); sequence.addElement(encryptionAlgorithm); sequence.addElement(encryptedData); } /////////////////////////////////////////////////////////////////////// // crypto shortcuts /////////////////////////////////////////////////////////////////////// /** * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted * with a password-based key. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param pki The PrivateKeyInfo to be encrypted and stored in the * EncryptedContentInfo. Before they are encrypted, they will be * padded using PKCS padding. */ public static EncryptedPrivateKeyInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, PrivateKeyInfo pki) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = (PBEAlgorithm) keyGenAlg; CryptoManager cman = CryptoManager.getInstance(); // generate key CryptoToken token = cman.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); } // perform encryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initEncrypt( key, params ); byte[] encrypted = cipher.doFinal( Cipher.pad( ASN1Util.encode(pki), encAlg.getBlockSize()) ); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedPrivateKeyInfo EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo ( encAlgID, new OCTET_STRING(encrypted) ); return epki; } catch( IllegalBlockSizeException e ) { Assert.notReached("IllegalBlockSizeException in EncryptedContentInfo" +".createPBE"); } catch( BadPaddingException e ) { Assert.notReached("BadPaddingException in EncryptedContentInfo" +".createPBE"); } return null; } /** * Export a private key in PBES2 format, using a random PBKDF2 salt. * * Token must support the CKM_PKCS5_PBKD2 mechanism. * * @param saltLen Length of salt in bytes (default: 16) * @param kdfIterations PBKDF2 iterations (default: 2000) * @param encAlg The symmetric encryption algorithm for enciphering the * private key. Determines the size of derived key. * @param pwd Password * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param privateKeyInfo The encoded PrivateKeyInfo to be encrypted and * stored in the EncryptedContentInfo. */ public static EncryptedPrivateKeyInfo createPBES2( int saltLen, int kdfIterations, EncryptionAlgorithm encAlg, Password pwd, KeyGenerator.CharToByteConverter charToByteConverter, PrivateKeyInfo privateKeyInfo) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { if (encAlg == null) throw new IllegalArgumentException("encAlg cannot be null"); if (pwd == null) throw new IllegalArgumentException("pwd cannot be null"); if (privateKeyInfo == null) throw new IllegalArgumentException("privateKeyInfo cannot be null"); if (kdfIterations < 1) kdfIterations = 2000; if (saltLen < 1) saltLen = 16; try { // generate random PBKDF2 salt SecureRandom random = new SecureRandom(); byte salt[] = new byte[saltLen]; random.nextBytes(salt); // derive symmetric key from passphrase using PBKDF2 CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( PBEAlgorithm.PBE_PKCS5_PBKDF2); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( pwd.getChars(), salt, kdfIterations, encAlg); if (charToByteConverter != null) kg.setCharToByteConverter(charToByteConverter); kg.initialize(pbekgParams); SymmetricKey sk = kg.generate(); // encrypt PrivateKeyInfo byte iv[] = new byte[encAlg.getBlockSize()]; random.nextBytes(iv); Cipher cipher = token.getCipherContext(encAlg); cipher.initEncrypt(sk, new IVParameterSpec(iv)); byte[] encData = cipher.doFinal(ASN1Util.encode(privateKeyInfo)); // construct KDF AlgorithmIdentifier SEQUENCE paramsKdf = new SEQUENCE(); paramsKdf.addElement(new OCTET_STRING(salt)); paramsKdf.addElement(new INTEGER((long) kdfIterations)); paramsKdf.addElement(new INTEGER((long) sk.getLength())); AlgorithmIdentifier algIdKdf = new AlgorithmIdentifier( PBEAlgorithm.PBE_PKCS5_PBKDF2.toOID(), paramsKdf); // construct encryption AlgorithmIdentifier AlgorithmIdentifier algIdEnc = new AlgorithmIdentifier( encAlg.toOID(), new OCTET_STRING(iv)); // construct "composite" PBES2 AlgorithmIdentifier SEQUENCE paramsPBES2 = new SEQUENCE(); paramsPBES2.addElement(algIdKdf); paramsPBES2.addElement(algIdEnc); AlgorithmIdentifier algIdPBES2 = new AlgorithmIdentifier( PBEAlgorithm.PBE_PKCS5_PBES2.toOID(), paramsPBES2); // construct EncryptedPrivateKeyInfo return new EncryptedPrivateKeyInfo(algIdPBES2, new OCTET_STRING(encData)); } catch (IllegalBlockSizeException e) { Assert.notReached("IllegalBlockSizeException in EncryptedContentInfo.createPBES2"); } catch (BadPaddingException e) { Assert.notReached("BadPaddingException in EncryptedContentInfo.createPBES2"); } return null; // unreachable } /** * Creates a new EncryptedPrivateKeyInfo, where the data is encrypted * with a password-based key- * with wrapping/unwrapping happening on token. * * @param keyGenAlg The algorithm for generating a symmetric key from * a password, salt, and iteration count. * @param password The password to use in generating the key. * @param salt The salt to use in generating the key. * @param iterationCount The number of hashing iterations to perform * while generating the key. * @param charToByteConverter The mechanism for converting the characters * in the password into bytes. If null, the default mechanism * will be used, which is UTF8. * @param pri The PrivateKey to be encrypted and stored in the * EncryptedContentInfo. */ public static EncryptedPrivateKeyInfo createPBE(PBEAlgorithm keyGenAlg, Password password, byte[] salt, int iterationCount, KeyGenerator.CharToByteConverter charToByteConverter, PrivateKey pri, CryptoToken token) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, CharConversionException { try { // check key gen algorithm if( ! (keyGenAlg instanceof PBEAlgorithm) ) { throw new NoSuchAlgorithmException("Key generation algorithm"+ " is not a PBE algorithm"); } PBEAlgorithm pbeAlg = (PBEAlgorithm) keyGenAlg; // generate key KeyGenerator kg = token.getKeyGenerator( keyGenAlg ); PBEKeyGenParams pbekgParams = new PBEKeyGenParams( password, salt, iterationCount); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(pbekgParams); kg.temporaryKeys(true); SymmetricKey key = kg.generate(); // generate IV EncryptionAlgorithm encAlg = pbeAlg.getEncryptionAlg(); AlgorithmParameterSpec params=null; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { params = new IVParameterSpec( kg.generatePBE_IV() ); } KeyWrapper wrapper = token.getKeyWrapper( KeyWrapAlgorithm.DES3_CBC_PAD); wrapper.initWrap(key, params); byte encrypted[] = wrapper.wrap(pri); // make encryption algorithm identifier PBEParameter pbeParam = new PBEParameter( salt, iterationCount ); AlgorithmIdentifier encAlgID = new AlgorithmIdentifier( keyGenAlg.toOID(), pbeParam); // create EncryptedPrivateKeyInfo EncryptedPrivateKeyInfo epki = new EncryptedPrivateKeyInfo ( encAlgID, new OCTET_STRING(encrypted) ); return epki; } catch (Exception e) { System.out.println("createPBE: exception:"+e.toString()); Assert.notReached("EncryptedPrivateKeyInfo exception:" +".createPBE"); } return null; } /** * Decrypts an EncryptedPrivateKeyInfo that was encrypted with a PBE * algorithm. The algorithm and its parameters are extracted from * the EncryptedPrivateKeyInfo. * * @param pass The password to use to generate the PBE key. * @param charToByteConverter The converter to change the password * characters to bytes. If null, the default conversion is used. */ public PrivateKeyInfo decrypt(Password pass, KeyGenerator.CharToByteConverter charToByteConverter) throws CryptoManager.NotInitializedException, NoSuchAlgorithmException, InvalidBERException, InvalidKeyException, InvalidAlgorithmParameterException, TokenException, IllegalBlockSizeException, BadPaddingException, CharConversionException { // get the key gen parameters AlgorithmIdentifier algid = encryptionAlgorithm; KeyGenAlgorithm kgAlg = KeyGenAlgorithm.fromOID(algid.getOID()); if( !(kgAlg instanceof PBEAlgorithm)) { throw new NoSuchAlgorithmException("KeyGenAlgorithm is not a "+ "PBE algorithm"); } ASN1Value params = algid.getParameters(); if( params == null ) { throw new InvalidAlgorithmParameterException( "PBE algorithms require parameters"); } PBEParameter pbeParams; if( params instanceof PBEParameter ) { pbeParams = (PBEParameter) params; } else { byte[] encodedParams = ASN1Util.encode(params); pbeParams = (PBEParameter) ASN1Util.decode(PBEParameter.getTemplate(), encodedParams); } PBEKeyGenParams kgp = new PBEKeyGenParams(pass, pbeParams.getSalt(), pbeParams.getIterations() ); // compute the key and IV CryptoToken token = CryptoManager.getInstance().getInternalCryptoToken(); KeyGenerator kg = token.getKeyGenerator( kgAlg ); if( charToByteConverter != null ) { kg.setCharToByteConverter( charToByteConverter ); } kg.initialize(kgp); SymmetricKey key = kg.generate(); // compute algorithm parameters EncryptionAlgorithm encAlg = ((PBEAlgorithm)kgAlg).getEncryptionAlg(); AlgorithmParameterSpec algParams; if( encAlg.getParameterClass().equals( IVParameterSpec.class ) ) { algParams = new IVParameterSpec( kg.generatePBE_IV() ); } else { algParams = null; } // perform the decryption Cipher cipher = token.getCipherContext( encAlg ); cipher.initDecrypt(key, algParams); byte[] decrypted = Cipher.unPad( cipher.doFinal( encryptedData.toByteArray() ) ); return (PrivateKeyInfo) ASN1Util.decode(PrivateKeyInfo.getTemplate(), decrypted); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template class for decoding EncryptedPrivateKeyInfos from BER. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new EncryptedPrivateKeyInfo( (AlgorithmIdentifier) seq.elementAt(0), (OCTET_STRING) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/Name.java000066400000000000000000000224531326145000000226600ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.CharConversionException; import java.io.ByteArrayInputStream; import org.mozilla.jss.asn1.*; /** * An X.500 Name. */ public class Name implements ASN1Value { SEQUENCE rdns; /** * Creates an empty Name. */ public Name() { rdns = new SEQUENCE(); } /** * Creates a name from a sequence of relative distinguished names. */ Name( SEQUENCE rdns ) { this.rdns = rdns; } /** * Adds a relative distinguished name to the Name. * * @param name A relative distinguished name (RDN) to be added to the Name. */ public void addElement( RDN name ) { rdns.addElement( name ); } /** * Adds a relative distinguished name containing a single AVA. * * @param ava An AttributeValueAssertion, which will be inserted as * the sole element of a new RDN, which will be stored in the Name. */ public void addElement( AVA ava ) { rdns.addElement( new RDN( ava ) ); } /** * Inserts the given RDN at the given index in the Name. */ public void insertElementAt( RDN name, int idx ) { rdns.insertElementAt( name, idx); } /** * Returns the RDN at the given index in the Name. */ public RDN elementAt( int idx ) { return (RDN) rdns.elementAt(idx); } /** * Removes the Name element at the given index. */ public void removeElementAt( int idx ) { rdns.removeElementAt( idx ); } /** * Returns the number of RDNs in the Name. */ public int size() { return rdns.size(); } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { rdns.encode(ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { rdns.encode(implicit, ostream); } /** * The OID for the common name (CN) attribute. */ public static final OBJECT_IDENTIFIER commonName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 3 } ); /** * The OID for the country name (C) attribute. */ public static final OBJECT_IDENTIFIER countryName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 6 } ); /** * The OID for the locality name (L) attribute. */ public static final OBJECT_IDENTIFIER localityName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 7 } ); /** * The OID for the state or province name (S) attribute. */ public static final OBJECT_IDENTIFIER stateOrProvinceName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 8 } ); /** * The OID for the organization name (O) attribute. */ public static final OBJECT_IDENTIFIER organizationName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 10 } ); /** * The OID for the organizational unit name (OU) attribute. */ public static final OBJECT_IDENTIFIER organizationalUnitName = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 11 } ); /** * Adds a common name (CN) to the Name. * @param CN The common name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addCommonName(String CN) throws CharConversionException { addElement( new AVA( commonName, new DirectoryString(CN) ) ); } /** * Adds a country name (C) to the Name. It must be exactly two characters. * @param C The country name. * It will be formatted according to the IETF PKIX rules for * directory strings. * @exception IllegalArgumentException If C.length() != 2. */ public void addCountryName(String C) throws CharConversionException { if( C.length() != 2 ) { throw new IllegalArgumentException("Country name must be exactly"+ " 2 characters"); } addElement( new AVA( countryName, new DirectoryString(C) ) ); } /** * Adds a locality name (L) to the Name. * @param L The locality name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addLocalityName(String L) throws CharConversionException { addElement( new AVA( localityName, new DirectoryString(L) ) ); } /** * Adds a state or province name (S) to the Name. * @param S The state or province name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addStateOrProvinceName(String S) throws CharConversionException { addElement( new AVA( stateOrProvinceName, new DirectoryString(S) ) ); } /** * Adds an organization name (O) to the Name. * @param O The organization name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addOrganizationName(String O) throws CharConversionException { addElement( new AVA( organizationName, new DirectoryString(O) ) ); } /** * Adds an organizational unit name (OU) to the Name. * @param OU The organizational unit name. * It will be formatted according to the IETF PKIX rules for * directory strings. */ public void addOrganizationalUnitName(String OU) throws CharConversionException { addElement( new AVA( organizationalUnitName, new DirectoryString(OU) ) ); } private String typeToString( OBJECT_IDENTIFIER type ) { if( type.equals(commonName) ) { return "CN"; } else if( type.equals(countryName) ) { return "C"; } else if( type.equals(localityName) ) { return "L"; } else if( type.equals(stateOrProvinceName) ) { return "S"; } else if( type.equals(organizationName) ) { return "O"; } else if( type.equals(organizationalUnitName) ) { return "OU"; } else { return null; } } private String AVAToString(AVA ava) throws InvalidBERException { OBJECT_IDENTIFIER oid = ava.getOID(); String type = typeToString( oid ); if( type == null ) { return ""; } else { return type + "=" + (DirectoryString) (((ANY)ava.getValue()). decodeWith(DirectoryString.getTemplate())); } } public String getRFC1485() throws InvalidBERException { StringBuffer buf = new StringBuffer(80); for( int r = 0; r < rdns.size(); r++ ) { if( r > 0) { buf.append(", "); } buf.append( AVAToString( ((RDN)rdns.elementAt(r)).at(0)) ); } return buf.toString(); } private static final Name.Template templateInstance = new Name.Template(); public static Name.Template getTemplate() { return templateInstance; } public static void main(String args[]) { try { if(args.length == 0) { Name name = new Name(); OBJECT_IDENTIFIER oid; oid = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 10 } ); AVA ava = new AVA( oid, new PrintableString("Netscape") ); name.addElement( ava ); oid = new OBJECT_IDENTIFIER( new long[]{ 2, 5, 4, 3} ); ava = new AVA( oid, new PrintableString("moi")); name.addElement( ava ); name.encode(System.out); } else { BufferedInputStream bis = new BufferedInputStream( new FileInputStream(args[0]) ); Name.Template temp = new Name.Template(); Name name = (Name) temp.decode(bis); System.out.println("Got name."); for( int i = 0; i < name.size(); i++ ) { AVA a = name.elementAt(i).at(0); PrintableString.Template pst = new PrintableString.Template(); PrintableString ps = (PrintableString) pst.decode( new ByteArrayInputStream( ((ANY)a.getValue()).getEncoded() ) ); System.out.println("OID: "+a.getOID()+", String: "+ps); } System.out.println("End of name"); } } catch( Exception e) { e.printStackTrace(); } } public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE.OF_Template seqt = new SEQUENCE.OF_Template( new RDN.Template() ); SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); return new Name( seq ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/PBEParameter.java000066400000000000000000000070201326145000000242400ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import java.io.*; /** * PKCS #5 PBEParameter, and PKCS #12 pkcs-12PbeParams. The only * difference between the two is that PKCS #5 dictates that the size of the * salt must be 8 bytes, while PKCS #12 leaves the salt length undefined. * To work with both standards, this class does not check the length of the * salt but rather leaves that to the application. */ public class PBEParameter implements ASN1Value { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private byte[] salt; private int iterations; private SEQUENCE sequence; public byte[] getSalt() { return salt; } public int getIterations() { return iterations; } /////////////////////////////////////////////////////////////////////// // constructors /////////////////////////////////////////////////////////////////////// private PBEParameter() { } /** * Creates a PBEParameter from a salt and iteration count. Neither * may be null. */ public PBEParameter(byte[] salt, int iterations) { this.salt = salt; this.iterations = iterations; sequence = new SEQUENCE(); sequence.addElement( new OCTET_STRING(salt) ); sequence.addElement( new INTEGER(iterations) ); } /** * Creates a PBEParameter from a salt and iteration count. Neither * may be null. */ public PBEParameter(OCTET_STRING salt, INTEGER iterations) { this( salt.toByteArray(), iterations.intValue() ); } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template class for decoding a PBEParameter. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( OCTET_STRING.getTemplate() ); seqt.addElement( INTEGER.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new PBEParameter( (OCTET_STRING) seq.elementAt(0), (INTEGER) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/PrivateKeyInfo.java000066400000000000000000000123121326145000000246700ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import java.io.*; import org.mozilla.jss.crypto.PrivateKey; import java.security.NoSuchAlgorithmException; public class PrivateKeyInfo implements ASN1Value, java.security.PrivateKey { /////////////////////////////////////////////////////////////////////// // members and member access /////////////////////////////////////////////////////////////////////// private INTEGER version; private AlgorithmIdentifier privateKeyAlgorithm; private OCTET_STRING privateKey; private SET attributes; // may be null private SEQUENCE sequence; public INTEGER getVersion() { return version; } public AlgorithmIdentifier getPrivateKeyAlgorithm() { return privateKeyAlgorithm; } public String getAlgorithm() { try { return PrivateKey.Type.fromOID(privateKeyAlgorithm.getOID()) .toString(); } catch( NoSuchAlgorithmException e ) { return null; } } public String getFormat() { return "PKCS#8"; } public byte[] getEncoded() { return privateKey.toByteArray(); } public OCTET_STRING getPrivateKey() { return privateKey; } /** * May return null if no attributes are present. */ public SET getAttributes() { return attributes; } /////////////////////////////////////////////////////////////////////// // Constructors /////////////////////////////////////////////////////////////////////// private PrivateKeyInfo() { } /** * Create a PrivateKeyInfo from its components. * * @param attributes May be null if there are no attributes, in which * case the attributes field will be omitted from the DER encoding. * Each element must be a org.mozilla.jss.pkix.primitive.Attribute. */ public PrivateKeyInfo(INTEGER version, AlgorithmIdentifier privateKeyAlgorithm, OCTET_STRING privateKey, SET attributes) { if( version==null || privateKeyAlgorithm==null || privateKey==null ) { throw new IllegalArgumentException( "PrivateKeyInfo parameter is null"); } this.version = version; this.privateKeyAlgorithm = privateKeyAlgorithm; this.privateKey = privateKey; this.attributes = attributes; sequence = new SEQUENCE(); sequence.addElement(version); sequence.addElement(privateKeyAlgorithm); sequence.addElement(privateKey); if(attributes!=null) { sequence.addElement( new Tag(0), attributes ); // make sure all the attributes are Attributes int size = attributes.size(); for(int i=0; i < size; i++) { if( ! (attributes.elementAt(i) instanceof Attribute) ) { throw new IllegalArgumentException("element "+i+ " of attributes is not an Attribute"); } } } } /////////////////////////////////////////////////////////////////////// // DER encoding /////////////////////////////////////////////////////////////////////// private static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { sequence.encode(ostream); } public void encode(Tag implicitTag, OutputStream ostream) throws IOException { sequence.encode(implicitTag, ostream); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * A template class for decoding PrivateKeyInfos from BER. */ public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( INTEGER.getTemplate() ); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( OCTET_STRING.getTemplate() ); seqt.addOptionalElement( new Tag(0), new SET.OF_Template( Attribute.getTemplate() ) ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws InvalidBERException, IOException { return decode(TAG, istream); } public ASN1Value decode(Tag implicitTag, InputStream istream) throws InvalidBERException, IOException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicitTag, istream); return new PrivateKeyInfo( (INTEGER) seq.elementAt(0), (AlgorithmIdentifier) seq.elementAt(1), (OCTET_STRING) seq.elementAt(2), (SET) seq.elementAt(3) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/RDN.java000066400000000000000000000051201326145000000224130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.asn1.*; /** * A RelativeDistinguishedName, whose ASN.1 is: *
 * RelativeDistinguishedName ::= SET SIZE(1..MAX) OF AttributeValueAssertion
 * 
*/ public class RDN implements ASN1Value { private SET avas; private RDN() { } /** * An RDN must have at least one element at all times, so an initial * element must be provided. */ public RDN(AVA initialElement) { avas = new SET(); avas.addElement(initialElement); } // This is for private use only, so we can be constructed from our // template. RDN(SET avas) { this.avas = avas; } public void add( AVA ava ) { avas.addElement( ava ); } public AVA at( int idx ) { return (AVA) avas.elementAt( idx ); } /** * @exception TooFewElementsException If removing this element would * result in the RDN being empty. */ public void removeAt( int idx ) throws TooFewElementsException { if( avas.size() <= 1 ) { throw new TooFewElementsException(); } avas.removeElementAt( idx ); } public int size() { return avas.size(); } public static final Tag TAG = SET.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { avas.encode(ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { avas.encode(implicit, ostream); } public static class Template implements ASN1Template { public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { AVA.Template avatemp = new AVA.Template(); SET.OF_Template sett = new SET.OF_Template( avatemp ); SET set = (SET) sett.decode(implicit, istream); if(set.size() < 1) { throw new InvalidBERException("RDN with zero elements; "+ "an RDN must have at least one element"); } return new RDN(set); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/SubjectPublicKeyInfo.java000066400000000000000000000105231326145000000260160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; import org.mozilla.jss.asn1.*; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import org.mozilla.jss.util.Assert; import java.security.PublicKey; import java.security.NoSuchAlgorithmException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.pkcs11.PK11PubKey; /** * A SubjectPublicKeyInfo, which stores information about a public key. * This class implements java.security.PublicKey. */ public class SubjectPublicKeyInfo extends java.security.spec.X509EncodedKeySpec implements ASN1Value, java.security.PublicKey { private AlgorithmIdentifier algorithm; private BIT_STRING subjectPublicKey; public String getAlgorithm() { try { return PrivateKey.Type.fromOID(algorithm.getOID()).toString(); } catch( NoSuchAlgorithmException e ) { // unknown algorithm return null; } } public byte[] getEncoded() { return ASN1Util.encode(this); } public AlgorithmIdentifier getAlgorithmIdentifier() { return algorithm; } public BIT_STRING getSubjectPublicKey() { return subjectPublicKey; } private SubjectPublicKeyInfo() { super(new byte[] {0});} public SubjectPublicKeyInfo(AlgorithmIdentifier algorithm, BIT_STRING subjectPublicKey) { super( new byte[] {0} ); // super constructor can't handle null this.algorithm = algorithm; this.subjectPublicKey = subjectPublicKey; } public SubjectPublicKeyInfo(PublicKey pubk) throws InvalidBERException, IOException { super( new byte[] {0}); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode( getTemplate(), pubk.getEncoded() ); algorithm = spki.algorithm; subjectPublicKey = spki.subjectPublicKey; } public static final Tag TAG = SEQUENCE.TAG; public Tag getTag() { return TAG; } public void encode(OutputStream ostream) throws IOException { encode(TAG, ostream); } public void encode(Tag implicit, OutputStream ostream) throws IOException { SEQUENCE seq = new SEQUENCE(); seq.addElement( algorithm ); seq.addElement( subjectPublicKey ); seq.encode( implicit, ostream ); } private static final Template templateInstance = new Template(); public static Template getTemplate() { return templateInstance; } /** * Creates a PublicKey from the public key information. Currently * only RSA and DSA keys can be converted. * * @exception NoSuchAlgorithmException If the cryptographic provider * does not recognize the algorithm for this public key. * @exception InvalidKeyFormatException If the subjectPublicKey could * not be decoded correctly. */ public PublicKey toPublicKey() throws NoSuchAlgorithmException, InvalidKeyFormatException { if( subjectPublicKey.getPadCount() != 0 ) { throw new InvalidKeyFormatException(); } return PK11PubKey.fromSPKI(getEncoded()); } public static class Template implements ASN1Template { private SEQUENCE.Template seqt; public Template() { seqt = new SEQUENCE.Template(); seqt.addElement( AlgorithmIdentifier.getTemplate() ); seqt.addElement( BIT_STRING.getTemplate() ); } public boolean tagMatch(Tag tag) { return TAG.equals(tag); } public ASN1Value decode(InputStream istream) throws IOException, InvalidBERException { return decode(TAG, istream); } public ASN1Value decode(Tag implicit, InputStream istream) throws IOException, InvalidBERException { SEQUENCE seq = (SEQUENCE) seqt.decode(implicit, istream); return new SubjectPublicKeyInfo( (AlgorithmIdentifier) seq.elementAt(0), (BIT_STRING) seq.elementAt(1) ); } } } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/TooFewElementsException.java000066400000000000000000000004621326145000000265530ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.pkix.primitive; public class TooFewElementsException extends Exception { } jss-4.4.3/jss/org/mozilla/jss/pkix/primitive/package.html000066400000000000000000000005261326145000000234130ustar00rootroot00000000000000 Frequently-used primitive ASN.1 types, such as AlgorithmIdentifier, PrivateKeyInfo, and X.500 Name. jss-4.4.3/jss/org/mozilla/jss/provider/000077500000000000000000000000001326145000000177765ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/provider/Makefile000066400000000000000000000034631326145000000214440ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/provider/java/000077500000000000000000000000001326145000000207175ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/provider/java/Makefile000066400000000000000000000034631326145000000223650ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/provider/java/config.mk000066400000000000000000000004201326145000000225110ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/provider/java/manifest.mn000066400000000000000000000004351326145000000230630ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../../.. MODULE = jss DIRS = security \ $(NULL) jss-4.4.3/jss/org/mozilla/jss/provider/java/security/000077500000000000000000000000001326145000000225665ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/provider/java/security/IvAlgorithmParameters.java000066400000000000000000000044031326145000000277030ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import java.security.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.IvParameterSpec; import java.io.IOException; import org.mozilla.jss.util.Assert; /** * This class is only intended to be used to implement * CipherSpi.getAlgorithmParameters(). */ public class IvAlgorithmParameters extends AlgorithmParametersSpi { private IvParameterSpec ivParamSpec; public void engineInit(AlgorithmParameterSpec paramSpec) { ivParamSpec = (IvParameterSpec) paramSpec; } public AlgorithmParameterSpec engineGetParameterSpec(Class clazz) throws InvalidParameterSpecException { if( clazz != null && !(clazz.isInstance(ivParamSpec)) ) { Class paramSpecClass = ivParamSpec.getClass(); throw new InvalidParameterSpecException( "Mozilla-JSS IvParameter spec class error" + paramSpecClass.getName()); } return ivParamSpec; } public void engineInit(byte[] params) throws IOException { Assert.notReached("engineInit(byte[]) not supported"); throw new IOException("engineInit(byte[]) not supported"); } public void engineInit(byte[] params, String format) throws IOException { Assert.notReached("engineInit(byte[],String) not supported"); throw new IOException("engineInit(byte[],String) not supported"); } public byte[] engineGetEncoded() throws IOException { Assert.notReached("encoding IvAlgorithmParameters not supported"); throw new IOException("encoding IvAlgorithmParameters not supported"); } public byte[] engineGetEncoded(String format) throws IOException { Assert.notReached("encoding IvAlgorithmParameters not supported"); throw new IOException("encoding IvAlgorithmParameters not supported"); } public String engineToString() { Assert.notReached("engineToString() not supported"); return getClass().getName(); } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/JSSKeyPairGeneratorSpi.java000066400000000000000000000041471326145000000277060ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import org.mozilla.jss.crypto.*; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.security.InvalidAlgorithmParameterException; class JSSKeyPairGeneratorSpi extends java.security.KeyPairGeneratorSpi { private KeyPairGenerator kpg; private JSSKeyPairGeneratorSpi() { super(); } protected JSSKeyPairGeneratorSpi(KeyPairAlgorithm alg) { super(); CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); try { try { kpg = token.getKeyPairGenerator(alg); } catch(java.security.NoSuchAlgorithmException e) { throw new UnsupportedOperationException( "Token '" + token.getName() + "' does not support algorithm " + alg.toString()); } } catch(TokenException e) { throw new TokenRuntimeException(e.getMessage()); } } public void initialize(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { kpg.initialize(params, random); } public void initialize(int keysize, SecureRandom random) { kpg.initialize(keysize, random); } public KeyPair generateKeyPair() { try { return kpg.genKeyPair(); } catch(TokenException e) { throw new TokenRuntimeException(e.getMessage()); } } public static class RSA extends JSSKeyPairGeneratorSpi { public RSA() { super(KeyPairAlgorithm.RSA); } } public static class DSA extends JSSKeyPairGeneratorSpi { public DSA() { super(KeyPairAlgorithm.DSA); } } public static class EC extends JSSKeyPairGeneratorSpi { public EC() { super(KeyPairAlgorithm.EC); } } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.c000066400000000000000000000653671326145000000255540ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "_jni/org_mozilla_jss_provider_java_security_JSSKeyStoreSpi.h" #include #include #include #include #include #include #include #include #include "java_ids.h" static PRStatus getTokenSlotPtr(JNIEnv *env, jobject keyStoreObj, PK11SlotInfo **ptr) { return JSS_getPtrFromProxyOwner(env, keyStoreObj, "proxy", "Lorg/mozilla/jss/pkcs11/TokenProxy;", (void**)ptr); } typedef enum { PRIVKEY=0x01, PUBKEY=0x02, SYMKEY=0x04, CERT=0x08 } TokenObjectType; #define ALL_OBJECT_TYPES (PRIVKEY | PUBKEY | SYMKEY | CERT ) typedef struct { PRStatus status; PRBool deleteIt; PRBool stopIterating; } JSSTraversalStatus; #define INIT_TRAVSTAT {PR_FAILURE, PR_FALSE, PR_FALSE} /* * contract: you must throw an exception if you return PRFailure. */ typedef JSSTraversalStatus (*TokenObjectTraversalCallback) (JNIEnv* env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data); /* * objectType is bitwise-OR of all the object types you want to traverse. */ static PRStatus traverseTokenObjects (JNIEnv *env, PK11SlotInfo *slot, TokenObjectTraversalCallback cb, int objectTypes, void *data) { PRStatus status = PR_FAILURE; JSSTraversalStatus travstat = INIT_TRAVSTAT; SECKEYPrivateKeyList* privkList = NULL; SECKEYPublicKeyList* pubkList = NULL; PK11SymKey *symKey = NULL; CERTCertList *certList = NULL; /* * Get all private keys */ if( objectTypes & PRIVKEY ) { SECKEYPrivateKeyListNode *node = NULL; privkList = PK11_ListPrivKeysInSlot(slot, NULL /*nickname*/, NULL /*wincx*/); if( privkList != NULL ) { for( node = PRIVKEY_LIST_HEAD(privkList); ! PRIVKEY_LIST_END(node, privkList); node = PRIVKEY_LIST_NEXT(node) ) { travstat = cb(env, slot, PRIVKEY, (void*) node->key, data); if( travstat.status == PR_FAILURE ) { goto finish; } if( travstat.deleteIt ) { /* Setting "force" to PR_FALSE means that if there is a * matching cert, the key won't be deleted. * If the KeyStore API is being followed, the cert * should have the same nickname as the key. So * both will get deleted when we scan for matching * certs later. */ PK11_DeleteTokenPrivateKey(node->key, PR_FALSE /*force*/); node->key = NULL; PR_REMOVE_LINK(&node->links); /* we don't free node because it is allocated from * the list's arena and will get freed when the list * is freed. */ } if( travstat.stopIterating ) { goto stop_early; } } } } /* * Get all symmetric keys */ if(objectTypes & SYMKEY) { /* this function returns a chained list of symmetric keys */ symKey = PK11_ListFixedKeysInSlot(slot, NULL /*nickname*/, NULL/*wincx*/); while( symKey != NULL ) { PK11SymKey *deadKey; travstat = cb(env, slot, SYMKEY, (void*) symKey, data); if( travstat.status != PR_SUCCESS ) { goto finish; } if( travstat.deleteIt ) { /* this just deletes the PKCS #11 object. The data structure * is NOT deleted. */ PK11_DeleteTokenSymKey(symKey); } if( travstat.stopIterating ) { goto stop_early; } deadKey = symKey; symKey = PK11_GetNextSymKey(symKey); PK11_FreeSymKey(deadKey); } } /* * get all public keys */ if( objectTypes & PUBKEY ) { SECKEYPublicKeyListNode *node = NULL; pubkList = PK11_ListPublicKeysInSlot(slot, NULL /*nickname*/); if( pubkList != NULL ) { for( node = PUBKEY_LIST_HEAD(pubkList); ! PUBKEY_LIST_END(node, pubkList); node = PUBKEY_LIST_NEXT(node) ) { if( node->key == NULL ) { /* workaround NSS bug 130699: PK11_ListPublicKeysInSlot * returns NULL if slot contains token symmetric key */ continue; } travstat = cb(env, slot, PUBKEY, (void*) node->key, data); if( travstat.status != PR_SUCCESS ) { goto finish; } if( travstat.deleteIt ) { /* XXX!!! * Workaround for 125408: PK11_DeleteTokenPublic key asserts * Don't delete the public key. * PK11_DeleteTokenPublicKey(node->key); * node->key = NULL; * PR_REMOVE_LINK(&node->links); */ /* node is allocated from the list's arena, it will get * freed with the list */ } if( travstat.stopIterating ) { goto stop_early; } } /* * XXX!!! * Destroy the list before we move on. Why bother, since we'll * do it anyway in the finish block? Because of bug 125408. * If we delete the cert and private key while traversing certs, * we'll delete the public key too, and then we'll crash when * we free the same public key while destroying the list. */ SECKEY_DestroyPublicKeyList(pubkList); pubkList = NULL; } } /* * Get all certs */ if( objectTypes & CERT ) { CERTCertListNode *node = NULL; certList = PK11_ListCertsInSlot(slot); if( certList == NULL ) { JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Failed to list certificates on token"); goto finish; } for( node = CERT_LIST_HEAD(certList); ! CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node) ) { travstat = cb(env, slot, CERT, (void*) node->cert, data); if( travstat.status != PR_SUCCESS ) { goto finish; } if( travstat.deleteIt ) { /* * Since, in a KeyStore, certs and private keys go together, * remove the private key too, if there is one. * * The hack here is that PK11_DeleteTokenCertAndKey will * not delete the cert if there is no matching private key. * We want to the cert to be deleted even if the key isn't * there. So we only call that function if we're sure the * key is there. Otherwise we delete the cert directly. */ SECKEYPrivateKey *privKey = PK11_FindKeyByAnyCert(node->cert, NULL /*wincx*/); PRBool keyPresent = (privKey != NULL); SECKEY_DestroyPrivateKey(privKey); if( keyPresent ) { PK11_DeleteTokenCertAndKey(node->cert, NULL /*wincx*/); } else { SEC_DeletePermCertificate(node->cert); } PR_REMOVE_LINK(&node->links); /* node is allocated from the list's arena, it will get freed * with the list */ } if( travstat.stopIterating ) { goto stop_early; } } } stop_early: status = PR_SUCCESS; finish: if( privkList != NULL ) { SECKEY_DestroyPrivateKeyList(privkList); } if( pubkList != NULL ) { SECKEY_DestroyPublicKeyList(pubkList); } while( symKey != NULL ) { PK11SymKey *deadKey; deadKey = symKey; symKey = PK11_GetNextSymKey(symKey); PK11_FreeSymKey(deadKey); } if( certList != NULL ) { CERT_DestroyCertList(certList); } return status; } /* allocates memory if type != CERT */ static char* getObjectNick(void *obj, TokenObjectType type) { switch(type) { case PRIVKEY: /* NOTE: this function allocates memory for the nickname */ return PK11_GetPrivateKeyNickname((SECKEYPrivateKey*)obj); case SYMKEY: /* NOTE: this function allocates memory for the nickname */ return PK11_GetSymKeyNickname((PK11SymKey*)obj); case PUBKEY: /* NOTE: this function allocates memory for the nickname */ return PK11_GetPublicKeyNickname((SECKEYPublicKey*)obj); case CERT: return ((CERTCertificate*)obj)->nickname; default: PR_ASSERT(PR_FALSE); return NULL; } } static void freeObjectNick(char *nick, TokenObjectType type) { if( type != CERT && nick != NULL) { PR_Free(nick); } } typedef struct { jobject setObj; jmethodID setAdd; } EngineAliasesCBInfo; static JSSTraversalStatus engineAliasesTraversalCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus travStat = INIT_TRAVSTAT; EngineAliasesCBInfo *cbinfo = (EngineAliasesCBInfo*)data; char *nickname=NULL; nickname = getObjectNick(obj, type); if( nickname != NULL ) { jstring nickString; /* convert it to a string */ nickString = (*env)->NewStringUTF(env, nickname); freeObjectNick(nickname, type); if( nickString == NULL ) { /* exception was thrown */ goto finish; } /* store the string in the vector */ (*env)->CallBooleanMethod(env, cbinfo->setObj, cbinfo->setAdd, nickString); if( (*env)->ExceptionOccurred(env) ) { goto finish; } } travStat.status = PR_SUCCESS; finish: return travStat; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getRawAliases (JNIEnv *env, jobject this) { PK11SlotInfo *slot = NULL; jobject setObj=NULL; jmethodID setAdd=NULL; EngineAliasesCBInfo cbinfo; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* * Create the vector object and get its method IDs */ { jclass setClass; jmethodID setCons; setClass = (*env)->FindClass(env, "java/util/HashSet"); if( setClass == NULL ) { /* should have thrown an exception */ goto finish; } setCons = (*env)->GetMethodID(env, setClass, "", "()V"); if( setCons == NULL ) { goto finish; } setObj = (*env)->NewObject(env, setClass, setCons); if( setObj == NULL ) { goto finish; } setAdd = (*env)->GetMethodID(env, setClass, "add", "(Ljava/lang/Object;)Z"); if( setAdd == NULL ) { goto finish; } } cbinfo.setObj = setObj; cbinfo.setAdd = setAdd; /* * traverse all slot objects */ if( traverseTokenObjects( env, slot, engineAliasesTraversalCallback, ALL_OBJECT_TYPES, &cbinfo) != PR_SUCCESS ) { goto finish; } finish: return setObj; } typedef struct { const char *targetNickname; } EngineDeleteEntryCBInfo; static JSSTraversalStatus engineDeleteEntryTraversalCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { EngineDeleteEntryCBInfo *cbinfo = (EngineDeleteEntryCBInfo*)data; JSSTraversalStatus status = INIT_TRAVSTAT; char *nickname = getObjectNick(obj, type); if( nickname != NULL && (PL_strcmp(nickname, cbinfo->targetNickname) == 0) ) { status.deleteIt = PR_TRUE; } freeObjectNick(nickname, type); status.status = PR_SUCCESS; return status; } JNIEXPORT void JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineDeleteEntry (JNIEnv *env, jobject this, jobject aliasString) { EngineDeleteEntryCBInfo cbinfo; PK11SlotInfo *slot = NULL; cbinfo.targetNickname = NULL; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* get the nickname */ cbinfo.targetNickname = (*env)->GetStringUTFChars(env, aliasString, NULL); if( cbinfo.targetNickname == NULL ) { goto finish; } /* traverse */ /* * traverse all slot objects */ traverseTokenObjects( env, slot, engineDeleteEntryTraversalCallback, ALL_OBJECT_TYPES, (void*) &cbinfo); finish: if( cbinfo.targetNickname != NULL ) { (*env)->ReleaseStringUTFChars(env, aliasString, cbinfo.targetNickname); } } typedef struct { const char *targetNickname; CERTCertificate *cert; } EngineGetCertificateCBInfo; static JSSTraversalStatus engineGetCertificateTraversalCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus travStat = INIT_TRAVSTAT; CERTCertificate *cert = (CERTCertificate*) obj; EngineGetCertificateCBInfo *cbinfo = (EngineGetCertificateCBInfo*)data; PR_ASSERT(type == CERT); /* shouldn't get called otherwise */ PR_ASSERT(cbinfo->cert == NULL); if( cert->nickname != NULL && PL_strcmp(cert->nickname, cbinfo->targetNickname) == 0 ) { cbinfo->cert = CERT_DupCertificate(cert); travStat.stopIterating = PR_TRUE; } travStat.status = PR_SUCCESS; return travStat; } static CERTCertificate* lookupCertByNickname(JNIEnv *env, jobject this, jstring alias) { PK11SlotInfo *slot; EngineGetCertificateCBInfo cbinfo = {NULL,NULL}; PRStatus status = PR_FAILURE; if( alias == NULL ) goto finish; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } cbinfo.targetNickname = (*env)->GetStringUTFChars(env, alias, NULL); if(cbinfo.targetNickname == NULL ) goto finish; status = traverseTokenObjects( env, slot, engineGetCertificateTraversalCallback, CERT, (void*) &cbinfo); finish: if( cbinfo.targetNickname != NULL ) { (*env)->ReleaseStringUTFChars(env, alias, cbinfo.targetNickname); } if( status != PR_SUCCESS && cbinfo.cert != NULL) { CERT_DestroyCertificate(cbinfo.cert); cbinfo.cert = NULL; } return cbinfo.cert; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertObject (JNIEnv *env, jobject this, jstring alias) { CERTCertificate *cert = NULL; PK11SlotInfo *slot = NULL; jobject certObj = NULL; cert = lookupCertByNickname(env, this, alias); if( cert == NULL ) { goto finish; } if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } slot = PK11_ReferenceSlot(slot); certObj = JSS_PK11_wrapCertAndSlot(env, &cert, &slot); finish: if( cert != NULL ) { CERT_DestroyCertificate(cert); } if( slot != NULL ) { PK11_FreeSlot(slot); } if( certObj == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); } return certObj; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getDERCert (JNIEnv *env, jobject this, jstring alias) { CERTCertificate * cert = NULL; jbyteArray derCertBA = NULL; cert = lookupCertByNickname(env, this, alias); if( cert == NULL ) { goto finish; } derCertBA = JSS_SECItemToByteArray(env, &cert->derCert); finish: if( cert != NULL) { CERT_DestroyCertificate(cert); } if( derCertBA == NULL ) { PR_ASSERT( (*env)->ExceptionOccurred(env) ); } return derCertBA; } JNIEXPORT jstring JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertNickname (JNIEnv *env, jobject this, jbyteArray derCertBA) { PK11SlotInfo *slot=NULL; SECItem *derCert=NULL; CERTCertificate * cert=NULL; CERTCertificate searchCert; jstring nickString = NULL; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } /* convert derCert to SECItem */ derCert = JSS_ByteArrayToSECItem(env, derCertBA); if( derCert == NULL ) { /* exception was thrown */ goto finish; } /* lookup cert by derCert */ searchCert.derCert = *derCert; cert = PK11_FindCertFromDERCert(slot, &searchCert, NULL /*wincx*/); if( cert == NULL ) { /* not found. return NULL */ goto finish; } /* convert cert nickname to Java string */ nickString = (*env)->NewStringUTF(env, cert->nickname); finish: if( derCert != NULL ) { SECITEM_FreeItem(derCert, PR_TRUE /*freeit*/); } if( cert != NULL ) { CERT_DestroyCertificate(cert); } return nickString; } typedef struct { const char *label; SECKEYPrivateKey *privk; PK11SymKey *symk; } FindKeyCBInfo; static JSSTraversalStatus findKeyCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus status = INIT_TRAVSTAT; FindKeyCBInfo *cbinfo = (FindKeyCBInfo*)data; const char *objNick = getObjectNick(obj, type); status.status = PR_SUCCESS; PR_ASSERT(cbinfo->privk==NULL && cbinfo->symk==NULL); if( PL_strcmp(objNick, cbinfo->label) == 0 ) { /* found it */ status.stopIterating = PR_TRUE; switch( type ) { case PRIVKEY: cbinfo->privk = (SECKEYPrivateKey*)obj; break; case SYMKEY: cbinfo->symk = (PK11SymKey*)obj; break; default: PR_ASSERT(PR_FALSE); status.status = PR_FAILURE; } } freeObjectNick(obj, type); return status; } typedef struct { const char *targetNickname; SECKEYPrivateKey *privk; } GetKeyByCertNickCBInfo; static JSSTraversalStatus getKeyByCertNickCallback (JNIEnv *env, PK11SlotInfo *slot, TokenObjectType type, void *obj, void *data) { JSSTraversalStatus travStat = INIT_TRAVSTAT; CERTCertificate *cert = (CERTCertificate*) obj; GetKeyByCertNickCBInfo *cbinfo = (GetKeyByCertNickCBInfo*) data; PR_ASSERT(type == CERT); /* shouldn't get called otherwise */ PR_ASSERT(cbinfo->privk == NULL); if( cert->nickname != NULL && PL_strcmp(cert->nickname, cbinfo->targetNickname) == 0 ) { travStat.stopIterating = PR_TRUE; cbinfo->privk = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*wincx*/); if( cbinfo->privk ) { printf("Found private key from cert with label '%s'\n", cert->nickname); } } travStat.status = PR_SUCCESS; return travStat; } /* * This is only here for backward compatibility. */ JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKey (JNIEnv *env, jobject this, jstring alias, jcharArray password) { PR_ASSERT(0); JSS_throwMsg(env, "java/lang/RuntimeException", "Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engine" "GetKey not implemented"); return NULL; } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineGetKeyNative (JNIEnv *env, jobject this, jstring alias, jcharArray password) { PK11SlotInfo *slot=NULL; FindKeyCBInfo keyCbinfo = {NULL, NULL, NULL}; GetKeyByCertNickCBInfo certCbinfo = {NULL, NULL}; jobject keyObj = NULL; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } if( alias == NULL ) { goto finish; } /* * first look for a matching key */ keyCbinfo.label = (*env)->GetStringUTFChars(env, alias, NULL); if( keyCbinfo.label == NULL ) { goto finish; } if( traverseTokenObjects( env, slot, findKeyCallback, PRIVKEY | SYMKEY, &keyCbinfo) != PR_SUCCESS ) { goto finish; } if(keyCbinfo.privk != NULL ) { /* found a matching private key */ keyObj = JSS_PK11_wrapPrivKey(env, &keyCbinfo.privk); } else if( keyCbinfo.symk != NULL ) { /* found a matching symmetric key */ keyObj = JSS_PK11_wrapSymKey(env, &keyCbinfo.symk); } if( keyObj == NULL ) { /* * If we didn't find a matching key, look for a matching cert */ certCbinfo.targetNickname = (*env)->GetStringUTFChars(env, alias, NULL); if(certCbinfo.targetNickname == NULL ) goto finish; if( traverseTokenObjects( env, slot, getKeyByCertNickCallback, CERT, (void*) &certCbinfo) != PR_SUCCESS ) { goto finish; } if( certCbinfo.privk != NULL ) { keyObj = JSS_PK11_wrapPrivKey(env, &certCbinfo.privk); } } finish: if( keyCbinfo.label != NULL ) { (*env)->ReleaseStringUTFChars(env, alias, keyCbinfo.label); } if( certCbinfo.targetNickname != NULL ) { (*env)->ReleaseStringUTFChars(env, alias, certCbinfo.targetNickname); } PR_ASSERT( keyCbinfo.privk==NULL && keyCbinfo.symk==NULL); PR_ASSERT( certCbinfo.privk==NULL ); return keyObj; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineIsCertificateEntry (JNIEnv *env, jobject this, jstring alias) { PK11SlotInfo *slot; EngineGetCertificateCBInfo cbinfo = {NULL,NULL}; jboolean retVal = JNI_FALSE; if( alias == NULL ) goto finish; if( getTokenSlotPtr(env, this, &slot) != PR_SUCCESS ) { /* exception was thrown */ goto finish; } cbinfo.targetNickname = (*env)->GetStringUTFChars(env, alias, NULL); if(cbinfo.targetNickname == NULL ) goto finish; if( traverseTokenObjects( env, slot, engineGetCertificateTraversalCallback, CERT, (void*) &cbinfo) != PR_SUCCESS ) { goto finish; } if( cbinfo.cert != NULL ) { unsigned int allTrust; CERTCertTrust trust; SECStatus status; status = CERT_GetCertTrust(cbinfo.cert, &trust); if( status != SECSuccess ) { goto finish; } allTrust = trust.sslFlags | trust.emailFlags | trust.objectSigningFlags; if( (allTrust & (CERTDB_TRUSTED | CERTDB_TRUSTED_CA | CERTDB_NS_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA)) && !(allTrust & CERTDB_USER) ) { /* It's a trusted cert and not a user cert. */ retVal = JNI_TRUE; } } finish: if( cbinfo.targetNickname != NULL ) { (*env)->ReleaseStringUTFChars(env, alias, cbinfo.targetNickname); } if( cbinfo.cert != NULL) { CERT_DestroyCertificate(cbinfo.cert); } return retVal; } JNIEXPORT void JNICALL Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_engineSetKeyEntryNative (JNIEnv *env, jobject this, jstring alias, jobject keyObj, jcharArray password, jobjectArray certChain) { jclass privkClass, symkClass; const char *nickname = NULL; SECKEYPrivateKey *tokenPrivk=NULL; PK11SymKey *tokenSymk=NULL; if( keyObj==NULL || alias==NULL) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } nickname = (*env)->GetStringUTFChars(env, alias, NULL); if( nickname == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } privkClass = (*env)->FindClass(env, PK11PRIVKEY_CLASS_NAME); symkClass = (*env)->FindClass(env, PK11SYMKEY_CLASS_NAME); if( privkClass==NULL || symkClass==NULL) { ASSERT_OUTOFMEM(env); goto finish; } if( (*env)->IsInstanceOf(env, keyObj, privkClass) ) { SECKEYPrivateKey *privk; if( JSS_PK11_getPrivKeyPtr(env, keyObj, &privk) != PR_SUCCESS ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to extract NSS key from private key object"); goto finish; } tokenPrivk = PK11_ConvertSessionPrivKeyToTokenPrivKey(privk, NULL); if( tokenPrivk == NULL ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to copy private key to permanent token object"); goto finish; } if( PK11_SetPrivateKeyNickname(tokenPrivk, nickname) != SECSuccess ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to set alias of copied private key"); goto finish; } } else if( (*env)->IsInstanceOf(env, keyObj, symkClass) ) { PK11SymKey *symk; if( JSS_PK11_getSymKeyPtr(env, keyObj, &symk) != PR_SUCCESS ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to extract NSS key from symmetric key object"); goto finish; } tokenSymk = PK11_ConvertSessionSymKeyToTokenSymKey(symk, NULL); if( tokenSymk == NULL ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to copy symmetric key to permanent token object"); goto finish; } if( PK11_SetSymKeyNickname(tokenSymk, nickname) != SECSuccess ) { JSS_throwMsgPrErr(env, KEYSTORE_EXCEPTION, "Failed to set alias of symmetric key"); goto finish; } } else { JSS_throwMsg(env, KEYSTORE_EXCEPTION, "Unrecognized key type: must be JSS private key (PK11PrivKey) or" " JSS symmetric key (PK11SymKey)"); goto finish; } finish: if( nickname != NULL ) { (*env)->ReleaseStringUTFChars(env, alias, nickname); } if( tokenPrivk != NULL ) { SECKEY_DestroyPrivateKey(tokenPrivk); } if( tokenSymk != NULL ) { PK11_FreeSymKey(tokenSymk); } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.java000066400000000000000000000206521326145000000262370ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; import java.security.Key; import java.security.KeyStoreException; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import java.security.cert.CertificateException; import java.security.cert.CertificateEncodingException; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.pkcs11.TokenProxy; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.CryptoManager; /** * The JSS implementation of the JCA KeyStore SPI. * *

Implementation notes *

    *
  1. deleteEntry will delete all entries with that label. If the entry is a * cert with a matching private key, it will also delete the private key. * *
  2. getCertificate returns first cert with matching nickname. Converts it * into a java.security.cert.X509Certificate (not a JSS cert). * *
  3. getCertificateChain only returns a single certificate. That's because * we don't have a way to build a chain from a specific slot--only from * the set of all slots. * *
  4. getCreationDate is unsupported because NSS doesn't store that * information. * *
  5. getKey first looks for a private/symmetric key with the given label. * It returns the first one it finds. If it doesn't find one, it looks for a * cert with the given nickname. If it finds one, it returns the private key * for that cert. * *
  6. isCertificateEntry returns true if there is a cert with this nickname, * but it doesn't have a private key. isKeyEntry returns true if there is a key * with this nickname, or if there is a cert with this nickname and the cert * has an associated private key. * *
  7. load and store are no-ops. * *
  8. setCertificateEntry doesn't work.NSS doesn't have a way of storing a * certificate on a specific token unless it has an associated private key. * That rules out trusted certificate entries. * *
  9. setKeyEntry not supported yet. Need to convert a temporary key * into a permanent key. *
*/ public class JSSKeyStoreSpi extends java.security.KeyStoreSpi { protected TokenProxy proxy; public JSSKeyStoreSpi() { CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); PK11Token pk11tok = (PK11Token)token; proxy = pk11tok.getProxy(); } /** * Converts an Iterator into an Enumeration. */ private static class IteratorEnumeration implements Enumeration { private Iterator iter; public IteratorEnumeration(Iterator iter) { this.iter = iter; } public boolean hasMoreElements() { return iter.hasNext(); } public Object nextElement() { return iter.next(); } } private native HashSet getRawAliases(); /** * Returns a list of unique aliases. */ public Enumeration engineAliases() { return new IteratorEnumeration( getRawAliases().iterator() ); } public boolean engineContainsAlias(String alias) { return getRawAliases().contains(alias); } public native void engineDeleteEntry(String alias); /* * XXX-!!! Is shared cert factory thread safe? */ private CertificateFactory certFactory=null; { try { certFactory = CertificateFactory.getInstance("X.509"); } catch(CertificateException e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } public Certificate engineGetCertificate(String alias) { byte[] derCert = getDERCert(alias); if( derCert == null ) { return null; } else { try { return certFactory.generateCertificate( new ByteArrayInputStream(derCert) ); } catch( CertificateException e ) { e.printStackTrace(); return null; } } } private native byte[] getDERCert(String alias); private native X509Certificate getCertObject(String alias); public String engineGetCertificateAlias(Certificate cert) { try { return getCertNickname( cert.getEncoded() ); } catch(CertificateEncodingException e) { return null; } } private native String getCertNickname(byte[] derCert); public Certificate[] engineGetCertificateChain(String alias) { try { X509Certificate leaf = getCertObject(alias); if( leaf == null ) { return null; } CryptoManager cm = CryptoManager.getInstance(); X509Certificate[] jssChain = cm.buildCertificateChain(leaf); Certificate[] chain = new Certificate[jssChain.length]; for( int i=0; i < chain.length; ++i) { chain[i] = certFactory.generateCertificate( new ByteArrayInputStream(jssChain[i].getEncoded()) ); } return chain; } catch(TokenException te ) { throw new TokenRuntimeException(te.toString()); } catch(CryptoManager.NotInitializedException e) { throw new RuntimeException("CryptoManager not initialized"); } catch(CertificateException ce) { ce.printStackTrace(); return null; } } /* * Not supported. */ public java.util.Date engineGetCreationDate(String alias) { return null; } public Key engineGetKey(String alias, char[] password) { Object o = engineGetKeyNative(alias, password); if( o instanceof SymmetricKey ) { return new SecretKeyFacade((SymmetricKey)o); } else { return (Key) o; } } public native Object engineGetKeyNative(String alias, char[] password); /** * Returns true if there is a cert with this nickname but there is no * key associated with the cert. */ public native boolean engineIsCertificateEntry(String alias); /** * Returns true if there is a key with this alias, or if * there is a cert with this alias that has an associated key. */ public boolean engineIsKeyEntry(String alias) { /* this is somewhat wasteful but we can speed it up later */ return ( engineGetKey(alias, null) != null ); } public void engineLoad(InputStream stream, char[] password) throws IOException { } /** * NSS doesn't have a way of storing a certificate on a specific token * unless it has an associated private key. That rules out * trusted certificate entries, so we can't supply this method currently. */ public void engineSetCertificateEntry(String alias, Certificate cert) throws KeyStoreException { throw new KeyStoreException( "Storing trusted certificate entries to a JSS KeyStore is not" + " supported."); } public void engineSetKeyEntry(String alias, byte[] key, Certificate[] chain) throws KeyStoreException { throw new KeyStoreException("Storing plaintext keys is not supported."+ "Store the key as a handle instead."); } public void engineSetKeyEntry(String alias, Key key, char[] password, Certificate[] chain) throws KeyStoreException { if( key instanceof SecretKeyFacade ) { SecretKeyFacade skf = (SecretKeyFacade)key; engineSetKeyEntryNative(alias, skf.key, password, chain); } else { engineSetKeyEntryNative(alias, key, password, chain); } } private native void engineSetKeyEntryNative(String alias, Object key, char[] password, Certificate[] chain) throws KeyStoreException; public int engineSize() { return getRawAliases().size(); } public void engineStore(OutputStream stream, char[] password) throws IOException { } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/JSSMessageDigestSpi.java000066400000000000000000000073011326145000000272120ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import java.security.DigestException; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import java.security.MessageDigestSpi; public abstract class JSSMessageDigestSpi extends MessageDigestSpi { private JSSMessageDigest digest; private JSSMessageDigestSpi() { } protected JSSMessageDigestSpi(DigestAlgorithm alg) { super(); CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); try { CryptoManager cm = CryptoManager.getInstance(); CryptoToken ikst = cm.getInternalKeyStorageToken(); if( token.equals(ikst) ) { // InternalKeyStorageToken doesn't support message digesting token = cm.getInternalCryptoToken(); } try { digest = token.getDigestContext(alg); } catch(java.security.NoSuchAlgorithmException e) { throw new UnsupportedOperationException( "Token '" + token.getName() + "' does not support " + "algorithm " + alg.toString()); } } catch(TokenException e) { throw new TokenRuntimeException(e.getMessage()); } catch(DigestException e1) { throw new TokenRuntimeException(e1.getMessage()); } catch(CryptoManager.NotInitializedException e2) { throw new TokenRuntimeException(e2.getMessage()); } } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public byte[] engineDigest() { try { return digest.digest(); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public int engineDigest(byte[] buf, int offset, int len) throws DigestException { return digest.digest(buf, offset, len); } public int engineGetDigestLength() { return digest.getOutputSize(); } public void engineReset() { try { digest.reset(); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public void engineUpdate(byte input) { try { digest.update(input); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public void engineUpdate(byte[] input, int offset, int len) { try { digest.update(input,offset,len); } catch(java.security.DigestException de) { throw new TokenRuntimeException(de.getMessage()); } } public static class SHA1 extends JSSMessageDigestSpi { public SHA1() { super( DigestAlgorithm.SHA1 ); } } public static class SHA256 extends JSSMessageDigestSpi { public SHA256() { super( DigestAlgorithm.SHA256 ); } } public static class SHA384 extends JSSMessageDigestSpi { public SHA384() { super( DigestAlgorithm.SHA384 ); } } public static class SHA512 extends JSSMessageDigestSpi { public SHA512() { super( DigestAlgorithm.SHA512 ); } } public static class MD5 extends JSSMessageDigestSpi { public MD5() { super( DigestAlgorithm.MD5 ); } } public static class MD2 extends JSSMessageDigestSpi { public MD2() { super( DigestAlgorithm.MD2 ); } } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/JSSSecureRandomSpi.java000066400000000000000000000016521326145000000270600ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.JSSSecureRandom; public class JSSSecureRandomSpi extends java.security.SecureRandomSpi { JSSSecureRandom engine; public JSSSecureRandomSpi() { super(); engine = TokenSupplierManager.getTokenSupplier().getSecureRNG(); } protected byte[] engineGenerateSeed(int numBytes) { byte[] bytes = new byte[numBytes]; engine.nextBytes(bytes); return bytes; } protected void engineNextBytes(byte[] bytes) { engine.nextBytes(bytes); } protected void engineSetSeed(byte[] seed) { engine.setSeed(seed); } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/JSSSignatureSpi.java000066400000000000000000000164061326145000000264350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import org.mozilla.jss.crypto.PrivateKey; import java.security.*; import java.security.spec.*; import org.mozilla.jss.crypto.*; class JSSSignatureSpi extends java.security.SignatureSpi { org.mozilla.jss.crypto.Signature sig; SignatureAlgorithm alg; private JSSSignatureSpi() { } protected JSSSignatureSpi(SignatureAlgorithm alg) { this.alg = alg; } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public void engineInitSign(java.security.PrivateKey privateKey, SecureRandom random) throws InvalidKeyException { // discard the random engineInitSign(privateKey); } public void engineInitSign(java.security.PrivateKey privateKey) throws InvalidKeyException { try { sig = getSigContext(privateKey); sig.initSign((PrivateKey)privateKey); } catch(java.security.NoSuchAlgorithmException e) { throw new InvalidKeyException("Algorithm not supported"); } catch(TokenException e) { throw new InvalidKeyException("Token exception occurred"); } } private org.mozilla.jss.crypto.Signature getSigContext(java.security.PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeyException, TokenException { CryptoToken token; PrivateKey privk; if( ! (privateKey instanceof PrivateKey) ) { throw new InvalidKeyException(); } privk = (PrivateKey)privateKey; token = privk.getOwningToken(); return token.getSignatureContext(alg); } public void engineInitVerify(PublicKey publicKey) throws InvalidKeyException { try { CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); sig = token.getSignatureContext(alg); // convert the public key into a JSS public key if necessary if( ! (publicKey instanceof org.mozilla.jss.pkcs11.PK11PubKey) ) { if( ! publicKey.getFormat().equalsIgnoreCase("X.509") ) { throw new InvalidKeyException( "Unsupported public key format: " + publicKey.getFormat()); } X509EncodedKeySpec encodedKey = new X509EncodedKeySpec(publicKey.getEncoded()); KeyFactory fact = KeyFactory.getInstance( publicKey.getAlgorithm(), "Mozilla-JSS"); publicKey = fact.generatePublic(encodedKey); } sig.initVerify(publicKey); } catch(NoSuchProviderException e) { throw new InvalidKeyException("Unable to convert non-JSS key " + "to JSS key"); } catch(java.security.spec.InvalidKeySpecException e) { throw new InvalidKeyException("Unable to convert non-JSS key " + "to JSS key"); } catch(java.security.NoSuchAlgorithmException e) { throw new InvalidKeyException("Algorithm not supported"); } catch(TokenException e) { throw new InvalidKeyException("Token exception occurred"); } } public void engineUpdate(byte b) throws SignatureException { try { sig.update(b); } catch( TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public void engineUpdate(byte[] b, int off, int len) throws SignatureException { try { sig.update(b, off, len); } catch( TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public byte[] engineSign() throws SignatureException { try { return sig.sign(); } catch(TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public int engineSign(byte[] outbuf, int offset, int len) throws SignatureException { try { return sig.sign(outbuf, offset, len); } catch(TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public boolean engineVerify(byte[] sigBytes) throws SignatureException { try { return sig.verify(sigBytes); } catch( TokenException e) { throw new SignatureException("TokenException: "+e.toString()); } } public void engineSetParameter(AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { try { sig.setParameter(params); } catch( TokenException e ) { throw new InvalidAlgorithmParameterException( "TokenException: "+e.toString()); } } public Object engineGetParameter(String param) throws InvalidParameterException { throw new InvalidParameterException( "name/value parameters not supported"); } public void engineSetParameter(String param, Object value) throws InvalidParameterException { throw new InvalidParameterException( "name/value parameters not supported"); } public static class DSA extends JSSSignatureSpi { public DSA() { super(SignatureAlgorithm.DSASignatureWithSHA1Digest); } } public static class SHA1EC extends JSSSignatureSpi { public SHA1EC() { super(SignatureAlgorithm.ECSignatureWithSHA1Digest); } } public static class SHA256EC extends JSSSignatureSpi { public SHA256EC() { super(SignatureAlgorithm.ECSignatureWithSHA256Digest); } } public static class SHA384EC extends JSSSignatureSpi { public SHA384EC() { super(SignatureAlgorithm.ECSignatureWithSHA384Digest); } } public static class SHA512EC extends JSSSignatureSpi { public SHA512EC() { super(SignatureAlgorithm.ECSignatureWithSHA512Digest); } } public static class MD2RSA extends JSSSignatureSpi { public MD2RSA() { super(SignatureAlgorithm.RSASignatureWithMD2Digest); } } public static class MD5RSA extends JSSSignatureSpi { public MD5RSA() { super(SignatureAlgorithm.RSASignatureWithMD5Digest); } } public static class SHA1RSA extends JSSSignatureSpi { public SHA1RSA() { super(SignatureAlgorithm.RSASignatureWithSHA1Digest); } } public static class SHA256RSA extends JSSSignatureSpi { public SHA256RSA() { super(SignatureAlgorithm.RSASignatureWithSHA256Digest); } } public static class SHA384RSA extends JSSSignatureSpi { public SHA384RSA() { super(SignatureAlgorithm.RSASignatureWithSHA384Digest); } } public static class SHA512RSA extends JSSSignatureSpi { public SHA512RSA() { super(SignatureAlgorithm.RSASignatureWithSHA512Digest); } } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/KeyFactorySpi1_2.java000066400000000000000000000244641326145000000265010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import java.security.PublicKey; import java.security.spec.*; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkcs11.PK11PubKey; import org.mozilla.jss.pkcs11.PK11PrivKey; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.util.Assert; import java.security.Key; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.math.BigInteger; import java.io.StringWriter; import java.io.PrintWriter; public class KeyFactorySpi1_2 extends java.security.KeyFactorySpi { protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { if( keySpec instanceof RSAPublicKeySpec ) { RSAPublicKeySpec spec = (RSAPublicKeySpec) keySpec; // Generate a DER RSA public key SEQUENCE seq = new SEQUENCE(); seq.addElement( new INTEGER(spec.getModulus())); seq.addElement( new INTEGER(spec.getPublicExponent())); return PK11PubKey.fromRaw( PrivateKey.RSA, ASN1Util.encode(seq) ); } else if( keySpec instanceof DSAPublicKeySpec ) { // We need to import both the public value and the PQG parameters. // The only way to get all that information in DER is to send // a full SubjectPublicKeyInfo. So we encode all the information // into an SPKI. DSAPublicKeySpec spec = (DSAPublicKeySpec) keySpec; SEQUENCE pqg = new SEQUENCE(); pqg.addElement( new INTEGER(spec.getP()) ); pqg.addElement( new INTEGER(spec.getQ()) ); pqg.addElement( new INTEGER(spec.getG()) ); OBJECT_IDENTIFIER oid = null; try { oid = SignatureAlgorithm.DSASignature.toOID(); } catch(NoSuchAlgorithmException ex ) { Assert.notReached("no such algorithm as DSA?"); } AlgorithmIdentifier algID = new AlgorithmIdentifier( oid, pqg ); INTEGER publicValue = new INTEGER(spec.getY()); byte[] encodedPublicValue = ASN1Util.encode(publicValue); SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo( algID, new BIT_STRING(encodedPublicValue, 0) ); return PK11PubKey.fromSPKI( ASN1Util.encode(spki) ); // // requires JAVA 1.5 // //} else if( keySpec instanceof ECPublicKeySpec ) { // // We need to import both the public value and the curve. // // The only way to get all that information in DER is to send // // a full SubjectPublicKeyInfo. So we encode all the information // // into an SPKI. // // ECPublicKeySpec spec = (ECPublicKeySpec) keySpec; // AlgorithmParameters algParams = getInstance("ECParameters"); // // algParameters.init(spec.getECParameters()); // OBJECT_IDENTIFIER oid = null; // try { // oid = SignatureAlgorithm.ECSignature.toOID(); // } catch(NoSuchAlgorithmException ex ) { // Assert.notReached("no such algorithm as DSA?"); // } // AlgorithmIdentifier algID = // new AlgorithmIdentifier(oid, ecParams.getParams() ); // INTEGER publicValueX = new INTEGER(spec.getW().getAffineX()); // INTEGER publicValueY = new INTEGER(spec.getW().getAffineY()); // byte[] encodedPublicValue; // encodedPublicValue[0] = EC_UNCOMPRESSED_POINT; // encodedPublicValue += spec.getW().getAffineX().toByteArray(); // encodedPublicValue += spec.getW().getAffineY().toByteArray(); // // byte[] encodedPublicValue = ASN1Util.encode(publicValue); // SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo( // algID, new BIT_STRING(encodedPublicValue, 0) ); // // return PK11PubKey.fromSPKI( ASN1Util.encode(spki) ); // // use the following for EC keys in 1.4.2 } else if( keySpec instanceof X509EncodedKeySpec ) { // // SubjectPublicKeyInfo // X509EncodedKeySpec spec = (X509EncodedKeySpec) keySpec; return PK11PubKey.fromSPKI( spec.getEncoded() ); } throw new InvalidKeySpecException("Unsupported KeySpec type: " + keySpec.getClass().getName()); } /** * We don't support RSAPrivateKeySpec because it doesn't have enough * information. You need to provide an RSAPrivateCrtKeySpec. */ protected java.security.PrivateKey engineGeneratePrivate(KeySpec keySpec) throws InvalidKeySpecException { try { if( keySpec instanceof RSAPrivateCrtKeySpec ) { // // PKCS #1 RSAPrivateKey // RSAPrivateCrtKeySpec spec = (RSAPrivateCrtKeySpec) keySpec; SEQUENCE privKey = new SEQUENCE(); privKey.addElement( new INTEGER(0) ) ; // version privKey.addElement( new INTEGER(spec.getModulus()) ); privKey.addElement( new INTEGER(spec.getPublicExponent()) ); privKey.addElement( new INTEGER(spec.getPrivateExponent()) ); privKey.addElement( new INTEGER(spec.getPrimeP()) ); privKey.addElement( new INTEGER(spec.getPrimeQ()) ); privKey.addElement( new INTEGER(spec.getPrimeExponentP()) ); privKey.addElement( new INTEGER(spec.getPrimeExponentQ()) ); privKey.addElement( new INTEGER(spec.getCrtCoefficient()) ); AlgorithmIdentifier algID = new AlgorithmIdentifier( PrivateKey.RSA.toOID(), null ); OCTET_STRING encodedPrivKey = new OCTET_STRING( ASN1Util.encode(privKey) ); PrivateKeyInfo pki = new PrivateKeyInfo( new INTEGER(0), // version algID, encodedPrivKey, (SET)null // OPTIONAL SET OF Attribute ); return PK11PrivKey.fromPrivateKeyInfo( ASN1Util.encode(pki), TokenSupplierManager.getTokenSupplier().getThreadToken() ); } else if( keySpec instanceof DSAPrivateKeySpec ) { DSAPrivateKeySpec spec = (DSAPrivateKeySpec) keySpec; SEQUENCE pqgParams = new SEQUENCE(); pqgParams.addElement(new INTEGER(spec.getP())); pqgParams.addElement(new INTEGER(spec.getQ())); pqgParams.addElement(new INTEGER(spec.getG())); AlgorithmIdentifier algID = new AlgorithmIdentifier( PrivateKey.DSA.toOID(), pqgParams ); OCTET_STRING privateKey = new OCTET_STRING( ASN1Util.encode(new INTEGER(spec.getX())) ); PrivateKeyInfo pki = new PrivateKeyInfo( new INTEGER(0), // version algID, privateKey, null // OPTIONAL SET OF Attribute ); // Derive the public key from the private key BigInteger y = spec.getG().modPow(spec.getX(), spec.getP()); byte[] yBA = y.toByteArray(); // we need to chop off a leading zero byte if( y.bitLength() % 8 == 0 ) { byte[] newBA = new byte[yBA.length-1]; Assert._assert(newBA.length >= 0); System.arraycopy(yBA, 1, newBA, 0, newBA.length); yBA = newBA; } return PK11PrivKey.fromPrivateKeyInfo( ASN1Util.encode(pki), TokenSupplierManager.getTokenSupplier().getThreadToken(), yBA ); } else if( keySpec instanceof PKCS8EncodedKeySpec ) { return PK11PrivKey.fromPrivateKeyInfo( (PKCS8EncodedKeySpec)keySpec, TokenSupplierManager.getTokenSupplier().getThreadToken() ); } throw new InvalidKeySpecException("Unsupported KeySpec type: " + keySpec.getClass().getName()); } catch(TokenException te) { StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); te.printStackTrace(pw); throw new InvalidKeySpecException("TokenException: " + sw.toString()); } } protected KeySpec engineGetKeySpec(Key key, Class keySpec) throws InvalidKeySpecException { throw new InvalidKeySpecException( "Exporting raw key data is not supported. Wrap the key instead."); } /** * Translates key by calling getEncoded() to get its encoded form, * then importing the key from its encoding. Two formats are supported: * "X.509", which is decoded with an X509EncodedKeySpec; * and "PKCS#8", which is decoded with a PKCS8EncodedKeySpec. * *

This method is not well standardized: the documentation is very vague * about how the key is supposed to be translated. It is better * to move keys around by wrapping and unwrapping them; or by manually * translating to a KeySpec, then manually translating back to a Key. */ protected Key engineTranslateKey(Key key) throws InvalidKeyException { byte[] encoded = key.getEncoded(); String format = key.getFormat(); try { if( format.equals("SubjectPublicKeyInfo") || format.equalsIgnoreCase("X.509")) { X509EncodedKeySpec spec = new X509EncodedKeySpec(encoded); return engineGeneratePublic(spec); } else if( format.equals("PrivateKeyInfo") || format.equalsIgnoreCase("PKCS#8")) { PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded); return engineGeneratePrivate(spec); } } catch(InvalidKeySpecException e) { throw new InvalidKeyException(e.getMessage()); } throw new InvalidKeyException( "Unsupported encoding format: " + format); } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/KeyFactorySpi1_4.java000066400000000000000000000022431326145000000264720ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import java.security.PublicKey; import java.security.spec.*; import org.mozilla.jss.crypto.InvalidKeyFormatException; import org.mozilla.jss.crypto.PrivateKey; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkcs11.PK11PubKey; import java.security.Key; import java.security.InvalidKeyException; import javax.crypto.spec.DHPublicKeySpec; public class KeyFactorySpi1_4 extends KeyFactorySpi1_2 { protected PublicKey engineGeneratePublic(KeySpec keySpec) throws InvalidKeySpecException { if( keySpec instanceof DHPublicKeySpec ) { DHPublicKeySpec spec = (DHPublicKeySpec) keySpec; // Generate a DER DH public key INTEGER pubval = new INTEGER( spec.getY() ); return PK11PubKey.fromRaw( PrivateKey.DiffieHellman, ASN1Util.encode(pubval)); } else { return super.engineGeneratePublic(keySpec); } } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/Makefile000066400000000000000000000035521326145000000242330ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/provider/java/security/RC2AlgorithmParameters.java000066400000000000000000000044021326145000000277120ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.java.security; import java.security.*; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import javax.crypto.spec.RC2ParameterSpec; import java.io.IOException; import org.mozilla.jss.util.Assert; /** * This class is only intended to be used to implement * CipherSpi.getAlgorithmParameters(). */ public class RC2AlgorithmParameters extends AlgorithmParametersSpi { private RC2ParameterSpec RC2ParamSpec; public void engineInit(AlgorithmParameterSpec paramSpec) { RC2ParamSpec = (RC2ParameterSpec) paramSpec; } public AlgorithmParameterSpec engineGetParameterSpec(Class clazz) throws InvalidParameterSpecException { if( clazz != null && !clazz.isInstance(RC2ParamSpec) ) { Class paramSpecClass = RC2ParamSpec.getClass(); throw new InvalidParameterSpecException( "RC2 getParameterSpec has class " + paramSpecClass.getName()); } return RC2ParamSpec; } public void engineInit(byte[] params) throws IOException { Assert.notReached("engineInit(byte[]) not supported"); throw new IOException("engineInit(byte[]) not supported"); } public void engineInit(byte[] params, String format) throws IOException { Assert.notReached("engineInit(byte[],String) not supported"); throw new IOException("engineInit(byte[],String) not supported"); } public byte[] engineGetEncoded() throws IOException { Assert.notReached("encoding RC2AlgorithmParameters not supported"); throw new IOException("encoding RC2AlgorithmParameters not supported"); } public byte[] engineGetEncoded(String format) throws IOException { Assert.notReached("encoding RC2AlgorithmParameters not supported"); throw new IOException("encoding RC2AlgorithmParameters not supported"); } public String engineToString() { String str = new String("Mozilla-JSS RC2AlgorithmParameters " + getClass().getName()); return str; } } jss-4.4.3/jss/org/mozilla/jss/provider/java/security/config.mk000066400000000000000000000004201326145000000243600ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/provider/java/security/manifest.mn000066400000000000000000000011351326145000000247300ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../../../.. MODULE = jss NS_USE_JDK = 1 REQUIRES = nspr20 nss PACKAGE = org/mozilla/jss/provider/java/security/ # These are meant to be used within Ninja only. PRIVATE_EXPORTS = \ $(NULL) CSRCS = \ JSSKeyStoreSpi.c \ $(NULL) LIBRARY_NAME = jss_provider_java_security jss-4.4.3/jss/org/mozilla/jss/provider/javax/000077500000000000000000000000001326145000000211075ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/provider/javax/crypto/000077500000000000000000000000001326145000000224275ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/provider/javax/crypto/JSSCipherSpi.java000066400000000000000000000471041326145000000255460ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.javax.crypto; import java.security.spec.AlgorithmParameterSpec; import java.security.spec.InvalidParameterSpecException; import java.security.*; import java.security.NoSuchAlgorithmException; import javax.crypto.Cipher; import javax.crypto.ShortBufferException; import javax.crypto.IllegalBlockSizeException; import javax.crypto.BadPaddingException; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.SecretKeyFactory; import javax.crypto.SecretKey; import org.mozilla.jss.crypto.KeyWrapper; import org.mozilla.jss.crypto.KeyWrapAlgorithm; import org.mozilla.jss.crypto.EncryptionAlgorithm; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.Algorithm; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.Assert; import org.mozilla.jss.pkcs11.PK11PubKey; import org.mozilla.jss.pkcs11.PK11PrivKey; import org.mozilla.jss.pkix.primitive.SubjectPublicKeyInfo; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.BIT_STRING; import org.mozilla.jss.asn1.InvalidBERException; import java.security.SecureRandom; class JSSCipherSpi extends javax.crypto.CipherSpi { private String algFamily=null; private String algMode=null; private String algPadding=null; CryptoToken token = null; private org.mozilla.jss.crypto.Cipher cipher=null; private EncryptionAlgorithm encAlg = null; private org.mozilla.jss.crypto.KeyWrapper wrapper=null; private KeyWrapAlgorithm wrapAlg = null; private AlgorithmParameterSpec params = null; private int blockSize; //keyStrength is used for RC2ParameterSpec and EncryptionAlgorithm.lookup private int keyStrength; private JSSCipherSpi() { } protected JSSCipherSpi(String algFamily) { this.algFamily = algFamily; token = TokenSupplierManager.getTokenSupplier().getThreadToken(); } public void engineSetMode(String mode) { this.algMode = mode; } public void engineSetPadding(String padding) { this.algPadding = padding; } static private SecretKey importKey(Key key) throws InvalidKeyException { if (key instanceof SecretKey) { SecretKey sKey = (SecretKey) key; SecretKeyFactory fact = null; try { fact = SecretKeyFactory.getInstance(sKey.getAlgorithm(), "Mozilla-JSS"); } catch (NoSuchAlgorithmException e) { throw new InvalidKeyException( "Unable to translate key with Algorithm" + key.getAlgorithm()); } catch (NoSuchProviderException ex) { throw new InvalidKeyException( "Unable to find provider, this should not happen"); } return fact.translateKey(sKey); }else { throw new InvalidKeyException("Invalid key type: " + key.getClass().getName()); } } public void engineInit(int opmode, Key key, AlgorithmParameterSpec givenParams, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { try { // throw away any previous state cipher = null; wrapper = null; params = givenParams; if( algFamily==null ) { throw new InvalidAlgorithmParameterException( "incorrectly specified algorithm"); } if( opmode != Cipher.ENCRYPT_MODE && opmode != Cipher.DECRYPT_MODE && opmode != Cipher.WRAP_MODE && opmode != Cipher.UNWRAP_MODE ) { throw new InvalidKeyException("Invalid opmode"); } StringBuffer buf = new StringBuffer(); buf.append(algFamily); if( algMode != null ) { buf.append('/'); buf.append(algMode); } if( algPadding != null ) { buf.append('/'); buf.append(algPadding); } if( opmode == Cipher.ENCRYPT_MODE || opmode == Cipher.DECRYPT_MODE ) { if( ! (key instanceof SecretKeyFacade) ) { key = importKey(key); } SymmetricKey symkey = ((SecretKeyFacade)key).key; // lookup the encryption algorithm keyStrength = symkey.getStrength(); encAlg = EncryptionAlgorithm.lookup(algFamily, algMode, algPadding, keyStrength); blockSize = encAlg.getBlockSize(); if( !token.doesAlgorithm(encAlg) ) { throw new NoSuchAlgorithmException( encAlg.toString() + " is not supported by this token " + token.getName()); } cipher = token.getCipherContext(encAlg); if( opmode == Cipher.ENCRYPT_MODE ) { if( params == noAlgParams ) { // we're supposed to generate some params params = generateAlgParams(encAlg, blockSize); } cipher.initEncrypt(symkey, params); } else if( opmode == Cipher.DECRYPT_MODE ) { if( params == noAlgParams) { params = null; } cipher.initDecrypt(symkey, params); } } else { Assert._assert( opmode==Cipher.WRAP_MODE || opmode==Cipher.UNWRAP_MODE); wrapAlg = KeyWrapAlgorithm.fromString(buf.toString()); blockSize = wrapAlg.getBlockSize(); wrapper = token.getKeyWrapper(wrapAlg); // generate params if necessary if( params == noAlgParams ) { if( opmode == Cipher.WRAP_MODE ) { params = generateAlgParams(wrapAlg, blockSize); } else { Assert._assert(opmode == Cipher.UNWRAP_MODE); params = null; } } if( key instanceof org.mozilla.jss.crypto.PrivateKey ) { if( opmode != Cipher.UNWRAP_MODE ) { throw new InvalidKeyException( "Private key can only be used for unwrapping"); } wrapper.initUnwrap( (org.mozilla.jss.crypto.PrivateKey) key, params ); } else if( key instanceof PublicKey ) { if( opmode != Cipher.WRAP_MODE ) { throw new InvalidKeyException( "Public key can only be used for wrapping"); } wrapper.initWrap((PublicKey) key, params); } else if( key instanceof org.mozilla.jss.crypto.SecretKeyFacade) { org.mozilla.jss.crypto.SecretKeyFacade sk = (org.mozilla.jss.crypto.SecretKeyFacade) key; if( opmode == Cipher.WRAP_MODE ) { wrapper.initWrap( sk.key, params ); } else { Assert._assert(opmode==Cipher.UNWRAP_MODE); wrapper.initUnwrap( sk.key, params ); } } else { throw new InvalidKeyException("Invalid key type: " + key.getClass().getName()); } } } catch (NoSuchAlgorithmException e) { throw new InvalidAlgorithmParameterException(e.getMessage()); } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public void engineInit(int opmode, Key key, AlgorithmParameters givenParams, SecureRandom random) throws InvalidKeyException, InvalidAlgorithmParameterException { try { AlgorithmParameterSpec gp = null; if (algFamily.compareToIgnoreCase("RC2") == 0) { gp = givenParams.getParameterSpec( javax.crypto.spec.RC2ParameterSpec.class ); } else if (algMode.compareToIgnoreCase("CBC") == 0) { gp = givenParams.getParameterSpec( javax.crypto.spec.IvParameterSpec.class ); } if (gp != null) { engineInit(opmode, key, gp, random); } else { throw new InvalidAlgorithmParameterException("Unknown Parameter Spec"); } } catch(Exception e) { throw new InvalidAlgorithmParameterException(e.getMessage()); } } public void engineInit(int opmode, Key key, SecureRandom random) throws InvalidKeyException { try { engineInit(opmode, key, noAlgParams, random); } catch(InvalidAlgorithmParameterException e) { throw new InvalidKeyException(e.getMessage()); } } private AlgorithmParameterSpec generateAlgParams(Algorithm alg, int blockSize) throws InvalidKeyException { Class [] paramClasses = alg.getParameterClasses(); AlgorithmParameterSpec algParSpec = null; if( paramClasses == null ) { // no parameters are needed return null; } // generate an IV byte[] iv = new byte[blockSize]; try { SecureRandom random = SecureRandom.getInstance("pkcs11prng", "Mozilla-JSS"); random.nextBytes(iv); } catch (Exception e) { Assert.notReached(e.getMessage()); } for (int i = 0; i < paramClasses.length; i ++) { if( paramClasses[i].equals( javax.crypto.spec.IvParameterSpec.class ) ) { algParSpec = new javax.crypto.spec.IvParameterSpec(iv); break; } else if ( paramClasses[i].equals( RC2ParameterSpec.class ) ) { algParSpec = new RC2ParameterSpec(keyStrength, iv); break; } } return algParSpec; } private static class NoAlgParams implements AlgorithmParameterSpec { } private static final NoAlgParams noAlgParams = new NoAlgParams(); public int engineGetBlockSize() { return blockSize; } public byte[] engineGetIV() { if( params == null ) { return null; } if( params instanceof IvParameterSpec) { return ((IvParameterSpec)params).getIV(); } else if( params instanceof RC2ParameterSpec ) { return ((RC2ParameterSpec)params).getIV(); } else { return null; } } public AlgorithmParameters engineGetParameters() { AlgorithmParameters algParams = null; try { if(( params instanceof IvParameterSpec ) || ( params instanceof RC2ParameterSpec )) { algParams = AlgorithmParameters.getInstance(algFamily); algParams.init(params); } } catch(NoSuchAlgorithmException nsae) { Assert.notReached(nsae.getMessage()); } catch(InvalidParameterSpecException ipse) { Assert.notReached(ipse.getMessage()); } return algParams; } public int engineGetOutputSize(int inputLen) { int total = (blockSize-1) + inputLen; return ((total / blockSize) + 1) * blockSize; } public byte[] engineUpdate(byte[] input, int inputOffset, int inputLen) { if(cipher == null) { // Cipher is supposed to catch an illegal state, so we should never // get here Assert.notReached(); return null; } try { return cipher.update(input, inputOffset, inputLen); } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public int engineUpdate(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException { byte[] bytes = engineUpdate(input, inputOffset, inputLen); if( bytes.length > output.length-outputOffset ) { throw new ShortBufferException(bytes.length + " needed, " + (output.length-outputOffset) + " supplied"); } System.arraycopy(bytes, 0, output, outputOffset, bytes.length); return bytes.length; } public byte[] engineDoFinal(byte[] input, int inputOffset, int inputLen) throws IllegalBlockSizeException, BadPaddingException { if( cipher == null ) { // Cipher is supposed to catch an illegal state, so we should never // get here Assert.notReached(); return null; } try { if( input == null || inputLen == 0) { return cipher.doFinal(); } else { return cipher.doFinal(input, inputOffset, inputLen); } } catch(IllegalStateException ise) { Assert.notReached(); return null; } catch(org.mozilla.jss.crypto.IllegalBlockSizeException ibse) { throw new IllegalBlockSizeException(ibse.getMessage()); } catch(org.mozilla.jss.crypto.BadPaddingException bpe) { throw new BadPaddingException(bpe.getMessage()); } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public int engineDoFinal(byte[] input, int inputOffset, int inputLen, byte[] output, int outputOffset) throws ShortBufferException, IllegalBlockSizeException, BadPaddingException { byte[] bytes = engineDoFinal(input, inputOffset, inputLen); if( bytes.length > output.length-outputOffset ) { throw new ShortBufferException(bytes.length + " needed, " + (output.length-outputOffset) + " supplied"); } System.arraycopy(bytes, 0, output, outputOffset, bytes.length); return bytes.length; } public byte[] engineWrap(Key key) throws IllegalBlockSizeException, InvalidKeyException { if( wrapper == null ) { Assert.notReached(); return null; } try { if( key instanceof org.mozilla.jss.crypto.PrivateKey ) { return wrapper.wrap( (org.mozilla.jss.crypto.PrivateKey) key); } else if( key instanceof org.mozilla.jss.crypto.SecretKeyFacade) { return wrapper.wrap( ((org.mozilla.jss.crypto.SecretKeyFacade)key).key ); } else { throw new InvalidKeyException("Unsupported key type: " + key.getClass().getName()); } } catch(IllegalStateException ise) { // Cipher is supposed to catch this Assert.notReached(); return null; } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } } public Key engineUnwrap(byte[] wrappedKey, String wrappedKeyAlgorithm, int wrappedKeyType) throws InvalidKeyException, NoSuchAlgorithmException { if( wrapper == null ) { Assert.notReached(); return null; } try { switch(wrappedKeyType) { case Cipher.SECRET_KEY: return engineUnwrapSecret(wrappedKey, wrappedKeyAlgorithm); case Cipher.PRIVATE_KEY: return engineUnwrapPrivate(wrappedKey, wrappedKeyAlgorithm); case Cipher.PUBLIC_KEY: throw new UnsupportedOperationException( "Unable to unwrap public keys"); default: throw new NoSuchAlgorithmException( "Invalid key type: " + wrappedKeyType); } } catch(IllegalStateException ise) { // Cipher is supposed to catch this Assert.notReached(); return null; } } private Key engineUnwrapSecret(byte[] wrappedKey, String wrappedKeyAlg) throws InvalidKeyException, NoSuchAlgorithmException { try { int idx = wrappedKeyAlg.indexOf('/'); if( idx != -1 ) { wrappedKeyAlg = wrappedKeyAlg.substring(0, idx); } SymmetricKey.Type wrappedKeyType = SymmetricKey.Type.fromName(wrappedKeyAlg); // Specify 0 for key length. This will use the default key length. // Won't work for algorithms without a default, like RC4, unless a // padded algorithm is used. SymmetricKey key = wrapper.unwrapSymmetric(wrappedKey, wrappedKeyType, 0); return new SecretKeyFacade(key); } catch(StringIndexOutOfBoundsException e) { throw new NoSuchAlgorithmException("Unknown algorithm: " + wrappedKeyAlg); } catch(TokenException te ) { throw new TokenRuntimeException(te.getMessage()); } catch(InvalidAlgorithmParameterException iape ) { throw new NoSuchAlgorithmException("Invalid algorithm parameters" + iape.getMessage()); } } private Key engineUnwrapPrivate(byte[] wrappedKey, String wrappedKeyAlg) throws InvalidKeyException, NoSuchAlgorithmException { throw new NoSuchAlgorithmException( "Unwrapping private keys via the JCA interface is not supported: "+ "http://bugzilla.mozilla.org/show_bug.cgi?id=135328"); } public int engineGetKeySize(Key key) throws InvalidKeyException { if( key instanceof PK11PrivKey ) { return ((PK11PrivKey)key).getStrength(); } else if( key instanceof PK11PubKey ) { try { byte[] encoded = ((PK11PubKey)key).getEncoded(); SubjectPublicKeyInfo.Template spkiTemp = new SubjectPublicKeyInfo.Template(); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode(spkiTemp, encoded); BIT_STRING pk = spki.getSubjectPublicKey(); return pk.getBits().length - pk.getPadCount(); } catch(InvalidBERException e) { throw new InvalidKeyException("Exception while decoding " + "public key: " + e.getMessage()); } } else if( key instanceof SecretKeyFacade ) { SymmetricKey symkey = ((SecretKeyFacade)key).key; return symkey.getLength(); } else { key = importKey(key); SymmetricKey symkey = ((SecretKeyFacade)key).key; return symkey.getLength(); } } static public class DES extends JSSCipherSpi { public DES() { super("DES"); } } static public class DESede extends JSSCipherSpi { public DESede() { super("DESede"); } } static public class AES extends JSSCipherSpi { public AES() { super("AES"); } } static public class RC4 extends JSSCipherSpi { public RC4() { super("RC4"); } } static public class RSA extends JSSCipherSpi { public RSA() { super("RSA"); } } static public class RC2 extends JSSCipherSpi { public RC2() { super("RC2"); } } } jss-4.4.3/jss/org/mozilla/jss/provider/javax/crypto/JSSKeyGeneratorSpi.java000066400000000000000000000073051326145000000267320ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.javax.crypto; import java.io.CharConversionException; import java.security.*; import java.security.spec.*; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.TokenRuntimeException; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.SymmetricKey; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.TokenSupplierManager; import javax.crypto.*; class JSSKeyGeneratorSpi extends javax.crypto.KeyGeneratorSpi { private KeyGenerator keyGenerator= null; private JSSKeyGeneratorSpi() {} protected JSSKeyGeneratorSpi(KeyGenAlgorithm alg) { try { CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); keyGenerator = token.getKeyGenerator(alg); } catch( TokenException te) { throw new TokenRuntimeException(te.getMessage()); } catch(NoSuchAlgorithmException nsae) { throw new TokenRuntimeException(nsae.getMessage()); } } protected void engineInit(int keysize, SecureRandom random) throws InvalidParameterException { try { keyGenerator.initialize(keysize); } catch(InvalidAlgorithmParameterException e) { throw new InvalidParameterException(e.getMessage()); } } protected void engineInit( SecureRandom random) throws InvalidParameterException { // no-op. KeyGenerator.initialize isn't called if there // are no arguments. } protected void engineInit(AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { keyGenerator.initialize(params); } protected SecretKey engineGenerateKey() { try { return new SecretKeyFacade( keyGenerator.generate() ); } catch(IllegalStateException ise) { throw new TokenRuntimeException( "IllegalStateException: " + ise.getMessage()); } catch(TokenException te) { throw new TokenRuntimeException( te.getMessage()); } catch(CharConversionException cce) { throw new TokenRuntimeException( "CharConversionException: " + cce.getMessage()); } } public static class DES extends JSSKeyGeneratorSpi { public DES() { super(KeyGenAlgorithm.DES); } } public static class DESede extends JSSKeyGeneratorSpi { public DESede() { super(KeyGenAlgorithm.DESede); } } public static class AES extends JSSKeyGeneratorSpi { public AES() { super(KeyGenAlgorithm.AES); } } public static class RC4 extends JSSKeyGeneratorSpi { public RC4() { super(KeyGenAlgorithm.RC4); } } public static class RC2 extends JSSKeyGeneratorSpi { public RC2() { super(KeyGenAlgorithm.RC2); } } /** * @deprecated This class name is misleading. This algorithm * is used for generating Password-Based Authentication keys * for use with HmacSHA1. Use PBAHmacSHA1 instead. */ public static class HmacSHA1 extends JSSKeyGeneratorSpi { public HmacSHA1() { super(KeyGenAlgorithm.PBA_SHA1_HMAC); } } public static class PBAHmacSHA1 extends JSSKeyGeneratorSpi { public PBAHmacSHA1() { super(KeyGenAlgorithm.PBA_SHA1_HMAC); } } } jss-4.4.3/jss/org/mozilla/jss/provider/javax/crypto/JSSMacSpi.java000066400000000000000000000065151326145000000250350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.javax.crypto; import java.security.*; import java.security.spec.*; import org.mozilla.jss.crypto.JSSMessageDigest; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.JSSMessageDigest; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.HMACAlgorithm; import org.mozilla.jss.crypto.TokenRuntimeException; class JSSMacSpi extends javax.crypto.MacSpi { private JSSMessageDigest digest=null; private HMACAlgorithm alg; private JSSMacSpi() { } protected JSSMacSpi(HMACAlgorithm alg) { try { this.alg = alg; CryptoToken token = TokenSupplierManager.getTokenSupplier().getThreadToken(); digest = token.getDigestContext(alg); } catch( DigestException de) { throw new TokenRuntimeException(de.getMessage()); } catch(NoSuchAlgorithmException nsae) { throw new TokenRuntimeException(nsae.getMessage()); } } public int engineGetMacLength() { return alg.getOutputSize(); } public void engineInit(Key key, AlgorithmParameterSpec params) throws InvalidKeyException, InvalidAlgorithmParameterException { try { if( ! (key instanceof SecretKeyFacade) ) { throw new InvalidKeyException("Must use a JSS key"); } SecretKeyFacade facade = (SecretKeyFacade)key; digest.initHMAC(facade.key); } catch(DigestException de) { throw new InvalidKeyException( "DigestException: " + de.getMessage()); } } public void engineUpdate(byte input) { try { digest.update(input); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public void engineUpdate(byte[] input, int offset, int len) { try { digest.update(input, offset, len); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public byte[] engineDoFinal() { try { return digest.digest(); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public void engineReset() { try { digest.reset(); } catch(DigestException de) { throw new TokenRuntimeException("DigestException: " + de.getMessage()); } } public Object clone() throws CloneNotSupportedException { throw new CloneNotSupportedException(); } public static class HmacSHA1 extends JSSMacSpi { public HmacSHA1() { super(HMACAlgorithm.SHA1); } } public static class HmacSHA256 extends JSSMacSpi { public HmacSHA256() { super(HMACAlgorithm.SHA256); } } public static class HmacSHA384 extends JSSMacSpi { public HmacSHA384() { super(HMACAlgorithm.SHA384); } } public static class HmacSHA512 extends JSSMacSpi { public HmacSHA512() { super(HMACAlgorithm.SHA512); } } } jss-4.4.3/jss/org/mozilla/jss/provider/javax/crypto/JSSSecretKeyFactorySpi.java000066400000000000000000000372501326145000000275630ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.provider.javax.crypto; import javax.crypto.*; import javax.crypto.spec.*; import java.io.CharConversionException; import java.security.*; import java.security.spec.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.Assert; import org.mozilla.jss.util.Password; import org.mozilla.jss.crypto.PBEKeyGenParams; import java.lang.reflect.*; class JSSSecretKeyFactorySpi extends SecretKeyFactorySpi { private KeyGenAlgorithm alg = null; private CryptoToken token = null; private JSSSecretKeyFactorySpi() { } protected JSSSecretKeyFactorySpi(KeyGenAlgorithm alg) { this.alg = alg; token = TokenSupplierManager.getTokenSupplier().getThreadToken(); } private SecretKey generateKeyFromBits(byte[] bits, SymmetricKey.Type keyType) throws NoSuchAlgorithmException, TokenException, InvalidKeySpecException, InvalidAlgorithmParameterException { try { KeyWrapper wrapper = token.getKeyWrapper(KeyWrapAlgorithm.PLAINTEXT); wrapper.initUnwrap(); SymmetricKey symk = wrapper.unwrapSymmetric(bits, keyType, 0); return new SecretKeyFacade(symk); } catch(InvalidKeyException e) { throw new InvalidKeySpecException(e.getMessage()); } } private static PBEKeyGenParams makePBEKeyGenParams(PBEKeySpec spec) throws InvalidKeySpecException { // The PBEKeySpec in JCE 1.2.1 does not contain salt or iteration. // The PBEKeySpec in JDK 1.4 does contain salt and iteration. // If this is a JCE 1.2.1 PBEKeySpec, we don't have enough // information and we have to throw an exception. If it's a JDK 1.4 // PBEKeySpec, we can get the information. The only way I know of // to find this out at runtime and be compatible with both // versions is to use the reflection API. Class specClass = spec.getClass(); try { Method getSaltMethod = specClass.getMethod("getSalt", (java.lang.Class[]) null); Method getIterationMethod = specClass.getMethod("getIterationCount", (java.lang.Class[]) null); byte[] salt = (byte[]) getSaltMethod.invoke(spec, (java.lang.Object[]) null); Integer itCountObj = (Integer) getIterationMethod.invoke(spec, (java.lang.Object[]) null); int iterationCount = itCountObj.intValue(); Password pass = new Password(spec.getPassword()); PBEKeyGenParams params = new PBEKeyGenParams(pass, salt, iterationCount); pass.clear(); return params; } catch(NoSuchMethodException nsme) { // fall through } catch(SecurityException se) { throw new InvalidKeySpecException( "SecurityException calling getMethod() on the key " + "spec's class: " + se.getMessage()); } catch(IllegalAccessException iae) { throw new InvalidKeySpecException( "IllegalAccessException invoking method on PBEKeySpec: " + iae.getMessage()); } catch(InvocationTargetException ite) { String message=""; Throwable t = ite.getTargetException(); if( t != null ) { message = t.getMessage(); } throw new InvalidKeySpecException( "InvocationTargetException invoking method on PBEKeySpec: "+ message); } throw new InvalidKeySpecException( "This version of PBEKeySpec is unsupported. It must " + "implement getSalt() and getIterationCount(). The PBEKeySpec in " + "JDK 1.4 works, as does org.mozilla.jss.crypto.PBEKeyGenParams. " + "The PBEKeySpec in JCE 1.2.1 and earlier does NOT work."); } public SecretKey engineGenerateSecret(KeySpec spec) throws InvalidKeySpecException { try { if( spec instanceof PBEKeySpec || spec instanceof PBEKeyGenParams) { PBEKeyGenParams params; if( spec instanceof PBEKeySpec ) { params = makePBEKeyGenParams((PBEKeySpec)spec); } else { params = (org.mozilla.jss.crypto.PBEKeyGenParams) spec; } org.mozilla.jss.crypto.KeyGenerator gen =token.getKeyGenerator(alg); gen.initialize(params); SymmetricKey symk = gen.generate(); params.clear(); return new SecretKeyFacade(symk); } else if (spec instanceof DESedeKeySpec) { if( alg != KeyGenAlgorithm.DES3 ) { throw new InvalidKeySpecException( "Incorrect KeySpec type (" + spec.getClass().getName() + ") for algorithm (" + alg.toString() + ")"); } return generateKeyFromBits( ((DESedeKeySpec)spec).getKey(), SymmetricKey.Type.DES3 ); } else if (spec instanceof DESKeySpec) { if( alg != KeyGenAlgorithm.DES ) { throw new InvalidKeySpecException( "Incorrect KeySpec type (" + spec.getClass().getName() + ") for algorithm (" + alg.toString() + ")"); } return generateKeyFromBits( ((DESKeySpec)spec).getKey(), SymmetricKey.Type.DES ); } else if( spec instanceof SecretKeySpec ) { SecretKeySpec kspec = (SecretKeySpec) spec; SymmetricKey.Type type = SymmetricKey.Type.fromName( kspec.getAlgorithm()); return generateKeyFromBits( kspec.getEncoded(), type); } else { throw new InvalidKeySpecException( "Unsupported KeySpec: " + spec.getClass().getName()); } } catch(TokenException te) { throw new TokenRuntimeException(te.getMessage()); } catch(InvalidAlgorithmParameterException iape) { throw new InvalidKeySpecException( "InvalidAlgorithmParameterException: " + iape.getMessage()); } catch(IllegalStateException ise) { Assert.notReached("IllegalStateException"); throw new TokenRuntimeException("IllegalStateException: " + ise.getMessage()); } catch(CharConversionException cce) { throw new InvalidKeySpecException("CharConversionException: " + cce.getMessage()); } catch(NoSuchAlgorithmException nsae) { throw new InvalidKeySpecException("NoSuchAlgorithmException: " + nsae.getMessage()); } } public KeySpec engineGetKeySpec(SecretKey key, Class keySpec) throws InvalidKeySpecException { try { if( ! (key instanceof SecretKeyFacade) ) { throw new InvalidKeySpecException("key is not a JSS key"); } SymmetricKey symkey = ((SecretKeyFacade)key).key; byte[] keyBits = symkey.getKeyData(); SymmetricKey.Type keyType = symkey.getType(); if( keySpec.equals(DESedeKeySpec.class) ) { if( keyType != SymmetricKey.Type.DES3 ) { throw new InvalidKeySpecException( "key/spec mismatch: " + keyType + " key, DESede spec"); } return new DESedeKeySpec(keyBits); } else if( keySpec.equals(DESKeySpec.class) ) { if( keyType != SymmetricKey.Type.DES ) { throw new InvalidKeySpecException( "key/spec mismatch: " + keyType + " key, DES spec"); } return new DESKeySpec(keyBits); } else if( keySpec.equals(SecretKeySpec.class) ) { return new SecretKeySpec(keyBits, keyType.toString()); } else { throw new InvalidKeySpecException( "Unsupported key spec: " + keySpec.getName()); } } catch(SymmetricKey.NotExtractableException nee) { throw new InvalidKeySpecException("key is not extractable"); } catch(InvalidKeyException ike) { // This gets thrown by the key spec constructor if there's something // wrong with the key bits. But since those key bits came from // a real key, this should never happen. Assert.notReached("Invalid key: " + ike.getMessage()); throw new InvalidKeySpecException("Invalid key: " + ike.getMessage()); } } public SecretKey engineTranslateKey(SecretKey key) throws InvalidKeyException { if( key instanceof SecretKeyFacade ) { // try cloning the key try { SymmetricKey oldkey = ((SecretKeyFacade)key).key; CryptoToken owningToken = oldkey.getOwningToken(); org.mozilla.jss.crypto.KeyGenerator keygen = token.getKeyGenerator(oldkey.getType().getKeyGenAlg()); SymmetricKey newkey = keygen.clone(oldkey); return new SecretKeyFacade(newkey); } catch(SymmetricKey.NotExtractableException nee) { // no way around this, we fail throw new InvalidKeyException("key is not extractable"); } catch(TokenException te) { // fall through and try doing it the long way } catch(NoSuchAlgorithmException nsae) { throw new InvalidKeyException("Unsupported algorithm: " + nsae.getMessage()); } } // try extracting the key value and then creating a new key try { byte[] keyBits = key.getEncoded(); if( keyBits == null ) { throw new InvalidKeyException("Key is not extractable"); } SymmetricKey.Type keyType = SymmetricKey.Type.fromName( key.getAlgorithm() ); return generateKeyFromBits( keyBits, keyType); } catch( NoSuchAlgorithmException nsae ) { throw new InvalidKeyException("Unsupported algorithm: " + key.getAlgorithm()); } catch(TokenException te) { throw new InvalidKeyException("Token failed to process key: " + te.getMessage()); } catch(InvalidKeySpecException ikse) { throw new InvalidKeyException("Invalid key spec: " + ikse.getMessage()); } catch(InvalidAlgorithmParameterException iape) { throw new InvalidKeyException("Invalid algorithm parameters: " + iape.getMessage()); } } public static void main(String args[]) { try { CryptoManager.initialize("."); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalCryptoToken(); cm.setThreadToken(tok); org.mozilla.jss.crypto.KeyGenerator keygen = tok.getKeyGenerator(KeyGenAlgorithm.DES3); SymmetricKey symk = keygen.generate(); SecretKeyFacade origKey = new SecretKeyFacade(symk); JSSSecretKeyFactorySpi fact = new JSSSecretKeyFactorySpi(KeyGenAlgorithm.DES3); DESedeKeySpec kspec = (DESedeKeySpec) fact.engineGetKeySpec(origKey, DESedeKeySpec.class); SecretKeyFacade newKey = (SecretKeyFacade) fact.engineGenerateSecret(kspec); org.mozilla.jss.crypto.Cipher cipher = tok.getCipherContext(EncryptionAlgorithm.DES3_ECB); cipher.initEncrypt(origKey.key); String original = "Hello, World!!!!"; byte[] cipherText = cipher.doFinal( original.getBytes("UTF-8") ); System.out.println("ciphertext is " + cipherText.length + " bytes"); cipher.initDecrypt(newKey.key); byte[] plainText = cipher.doFinal(cipherText); System.out.println("recovered plaintext is " + plainText.length + " bytes"); String recovered = new String(plainText, "UTF-8"); System.out.println("Recovered '" + recovered + "'"); if( ! recovered.equals(original) ) { throw new Exception("recovered string is different from original"); } char[] pw = "foobarpw".toCharArray(); byte[] salt = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }; int iterationCount = 2; // generate a PBE key the old-fashioned way keygen = tok.getKeyGenerator(PBEAlgorithm.PBE_SHA1_DES3_CBC); PBEKeyGenParams jssKeySpec = new PBEKeyGenParams(pw, salt, iterationCount); keygen.initialize(jssKeySpec); symk = keygen.generate(); byte[] keydata = symk.getKeyData(); // generate a PBE key with the JCE SecretKeyFactory keyFact = SecretKeyFactory.getInstance("PBEWithSHA1AndDESede", "Mozilla-JSS"); newKey = (SecretKeyFacade) keyFact.generateSecret(jssKeySpec); byte[] newkeydata = newKey.key.getKeyData(); if( ! java.util.Arrays.equals(keydata, newkeydata) ) { throw new Exception("generated PBE keys are different"); } System.out.println("generated PBE keys are the same"); /* XXX JDK 1.4 ONLY // now try with a JDK 1.4 PBEKeySpec PBEKeySpec keySpec = new PBEKeySpec(pw, salt, iterationCount); newKey = (SecretKeyFacade) keyFact.generateSecret(keySpec); if( ! java.util.Arrays.equals(keydata, newKey.key.getKeyData()) ) { throw new Exception("generated PBE keys are different"); } System.out.println("generated PBE keys are the same"); */ System.exit(0); } catch(Throwable t) { t.printStackTrace(); System.exit(-1); } } public static class DES extends JSSSecretKeyFactorySpi { public DES() { super(KeyGenAlgorithm.DES); } } public static class DESede extends JSSSecretKeyFactorySpi { public DESede() { super(KeyGenAlgorithm.DESede); } } public static class AES extends JSSSecretKeyFactorySpi { public AES() { super(KeyGenAlgorithm.AES); } } public static class RC4 extends JSSSecretKeyFactorySpi { public RC4() { super(KeyGenAlgorithm.RC4); } } public static class RC2 extends JSSSecretKeyFactorySpi { public RC2() { super(KeyGenAlgorithm.RC2); } } public static class PBE_MD5_DES_CBC extends JSSSecretKeyFactorySpi { public PBE_MD5_DES_CBC() { super(PBEAlgorithm.PBE_MD5_DES_CBC); } } public static class PBE_SHA1_DES_CBC extends JSSSecretKeyFactorySpi { public PBE_SHA1_DES_CBC() { super(PBEAlgorithm.PBE_SHA1_DES_CBC); } } public static class PBE_SHA1_DES3_CBC extends JSSSecretKeyFactorySpi { public PBE_SHA1_DES3_CBC() { super(PBEAlgorithm.PBE_SHA1_DES3_CBC); } } public static class PBE_SHA1_RC4_128 extends JSSSecretKeyFactorySpi { public PBE_SHA1_RC4_128() { super(PBEAlgorithm.PBE_SHA1_RC4_128); } } /** * @deprecated This class name is misleading. This algorithm * is used for generating Password-Based Authentication keys * for use with HmacSHA1. Use PBAHmacSHA1 instead. */ public static class HmacSHA1 extends JSSSecretKeyFactorySpi { public HmacSHA1() { super(KeyGenAlgorithm.PBA_SHA1_HMAC); } } public static class PBAHmacSHA1 extends JSSSecretKeyFactorySpi { public PBAHmacSHA1() { super(KeyGenAlgorithm.PBA_SHA1_HMAC); } } } jss-4.4.3/jss/org/mozilla/jss/provider/manifest.mn000066400000000000000000000004261326145000000221420ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss DIRS = java \ $(NULL) jss-4.4.3/jss/org/mozilla/jss/rules.mk000066400000000000000000000035231326145000000176320ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. JAVADOC_TARGETS= \ org.mozilla.jss \ org.mozilla.jss.asn1 \ org.mozilla.jss.crypto \ org.mozilla.jss.pkcs7 \ org.mozilla.jss.pkcs10 \ org.mozilla.jss.pkcs11 \ org.mozilla.jss.pkcs12 \ org.mozilla.jss.pkix.primitive \ org.mozilla.jss.pkix.cert \ org.mozilla.jss.pkix.cmc \ org.mozilla.jss.pkix.cmmf \ org.mozilla.jss.pkix.cms \ org.mozilla.jss.pkix.crmf \ org.mozilla.jss.provider \ org.mozilla.jss.ssl \ org.mozilla.jss.tests \ org.mozilla.jss.util \ $(NULL) ifneq ($(HTML_HEADER),) HTML_HEADER_OPT=-header '$(HTML_HEADER)' endif javadoc: cp -i manage/*.java . if [ ! -d "$(DIST)/jssdoc" ] ; then mkdir -p $(CORE_DEPTH)/jssdoc ; fi $(JAVADOC) -native -private -sourcepath $(CORE_DEPTH)/jss -d $(CORE_DEPTH)/jssdoc $(HTML_HEADER_OPT) $(JAVADOC_TARGETS) rm -i *.java jss-4.4.3/jss/org/mozilla/jss/ssl/000077500000000000000000000000001326145000000167455ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/ssl/Makefile000066400000000000000000000036401326145000000204100ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### include rules.mk jdktest:: echo $(JDK_DEBUG_SUFFIX) jss-4.4.3/jss/org/mozilla/jss/ssl/PrintOutputStreamWriter.java000066400000000000000000000013461326145000000245020ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // // // // $Id$ package org.mozilla.jss.ssl; import java.io.*; import java.util.*; class PrintOutputStreamWriter extends java.io.OutputStreamWriter { public PrintOutputStreamWriter(OutputStream out) { super(out); } public void print(String x) throws java.io.IOException { write(x, 0, x.length()); } public void println(String x) throws java.io.IOException { // String line = new String(x + "\n"); String line = x + "\n"; write(line, 0, line.length()); flush(); } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLAlertDescription.java000066400000000000000000000043271326145000000234530ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; public enum SSLAlertDescription { // see lib/ssl/ssl3prot.h in NSS CLOSE_NOTIFY (0), END_OF_EARLY_DATA (1), // TLS 1.3 UNEXPECTED_MESSAGE (10), BAD_RECORD_MAC (20), DECRYPTION_FAILED (21), // RFC 5246 RECORD_OVERFLOW (22), // TLS only DECOMPRESSION_FAILURE (30), HANDSHAKE_FAILURE (40), NO_CERTIFICATE (41), // SSL3 only, NOT TLS BAD_CERTIFICATE (42), UNSUPPORTED_CERTIFICATE (43), CERTIFICATE_REVOKED (44), CERTIFICATE_EXPIRED (45), CERTIFICATE_UNKNOWN (46), ILLEGAL_PARAMETER (47), // All alerts below are TLS only. UNKNOWN_CA (48), ACCESS_DENIED (49), DECODE_ERROR (50), DECRYPT_ERROR (51), EXPORT_RESTRICTION (60), PROTOCOL_VERSION (70), INSUFFICIENT_SECURITY (71), INTERNAL_ERROR (80), INAPPROPRIATE_FALLBACK (86), // could also be sent for SSLv3 USER_CANCELED (90), NO_RENEGOTIATION (100), // Alerts for client hello extensions MISSING_EXTENSION (109), UNSUPPORTED_EXTENSION (110), CERTIFICATE_UNOBTAINABLE (111), UNRECOGNIZED_NAME (112), BAD_CERTIFICATE_STATUS_RESPONSE (113), BAD_CERTIFICATE_HASH_VALUE (114), NO_APPLICATION_PROTOCOL (120); private int id; private SSLAlertDescription(int id) { this.id = id; } public int getID() { return id; } public static SSLAlertDescription valueOf(int id) { for (SSLAlertDescription description : SSLAlertDescription.class.getEnumConstants()) { if (description.id == id) return description; } return null; } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLAlertEvent.java000066400000000000000000000015351326145000000222470ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.util.EventObject; public class SSLAlertEvent extends EventObject { private static final long serialVersionUID = 1L; int level; int description; public SSLAlertEvent(SSLSocket socket) { super(socket); } public SSLSocket getSocket() { return (SSLSocket)getSource(); } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public int getDescription() { return description; } public void setDescription(int description) { this.description = description; } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLAlertLevel.java000066400000000000000000000012561326145000000222350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; public enum SSLAlertLevel { // see lib/ssl/ssl3prot.h in NSS WARNING (1), FATAL (2); private int id; private SSLAlertLevel(int id) { this.id = id; } public int getID() { return id; } public static SSLAlertLevel valueOf(int id) { for (SSLAlertLevel level : SSLAlertLevel.class.getEnumConstants()) { if (level.id == id) return level; } return null; } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLCertificateApprovalCallback.java000066400000000000000000000141451326145000000255430ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * SSLSecurityStatus.java * */ package org.mozilla.jss.ssl; import org.mozilla.jss.pkcs11.*; import java.io.IOException; import java.io.InterruptedIOException; import java.util.*; import java.net.*; import org.mozilla.jss.crypto.X509Certificate; /** * This interface is what you should implement if you want to * be able to decide whether or not you want to approve the peer's cert, * instead of having NSS do that. */ public interface SSLCertificateApprovalCallback { /** * This method is called when the server sends it's certificate to * the client. * * The 'status' argument passed to this method is constructed by * NSS. It's a list of things 'wrong' with the certificate (which * you can see by calling the status.getReasons() method. So, * if there are problems regarding validity or trust of any of the * certificates in the chain, you can present this info to the user. * * If there are no items in the Enumeration returned by getReasons(), * you can assume that the certificate is trustworthy, and return * true, or you can continue to make further tests of your own * to determine trustworthiness. * * @param cert the peer's server certificate * @param status the ValidityStatus object containing a list * of all the problems with the cert * * @return true allow the connection to continue
* false terminate the connection (Expect an IOException * on the outstanding read()/write() on the socket) */ public boolean approve(org.mozilla.jss.crypto.X509Certificate cert, ValidityStatus status); /** * This class holds details about the errors for each cert in * the chain that the server presented * * To use this class, getReasons(), then iterate over the enumeration */ class ValidityStatus { public static final int EXPIRED_CERTIFICATE = -8192 + 11; public static final int REVOKED_CERTIFICATE = -8192 + 12; public static final int INADEQUATE_KEY_USAGE = -8192 + 90; public static final int INADEQUATE_CERT_TYPE = -8192 + 91; public static final int UNTRUSTED_CERT = -8192 + 21; public static final int CERT_STATUS_SERVER_ERROR = -8192 +115; public static final int UNKNOWN_ISSUER = -8192 + 13; public static final int UNTRUSTED_ISSUER = -8192 + 20; public static final int CERT_NOT_IN_NAME_SPACE = -8192 + 112; public static final int CA_CERT_INVALID = -8192 + 36; public static final int PATH_LEN_CONSTRAINT_INVALID = -8192 + 37; public static final int BAD_KEY = -8192 + 14; public static final int BAD_SIGNATURE = -8192 + 10; public static final int EXPIRED_ISSUER_CERTIFICATE = -8192 +30; public static final int INVALID_TIME = -8192 + 8; public static final int UNKNOWN_SIGNER = -8192 + 116; public static final int SEC_ERROR_CRL_EXPIRED = -8192 + 31; public static final int SEC_ERROR_CRL_BAD_SIGNATURE = -8192 + 32; public static final int SEC_ERROR_CRL_INVALID = -8192 + 33; public static final int CERT_BAD_ACCESS_LOCATION = -8192 + 117; public static final int OCSP_UNKNOWN_RESPONSE_TYPE = -8192 + 118; public static final int OCSP_BAD_HTTP_RESPONSE = -8192 + 119; public static final int OCSP_MALFORMED_REQUEST = -8192 + 120; public static final int OCSP_SERVER_ERROR = -8192 + 121; public static final int OCSP_TRY_SERVER_LATER = -8192 + 122; public static final int OCSP_REQUEST_NEEDS_SIG = -8192 + 123; public static final int OCSP_UNAUTHORIZED_REQUEST = -8192 + 124; public static final int OCSP_UNKNOWN_RESPONSE_STATUS= -8192 + 125; public static final int OCSP_UNKNOWN_CERT = -8192 + 126; public static final int OCSP_NOT_ENABLED = -8192 + 127; public static final int OCSP_NO_DEFAULT_RESPONDER = -8192 + 128; public static final int OCSP_MALFORMED_RESPONSE = -8192 + 129; public static final int OCSP_UNAUTHORIZED_RESPONSE = -8192 + 130; public static final int OCSP_FUTURE_RESPONSE = -8192 + 131; public static final int OCSP_OLD_RESPONSE = -8192 + 132; /** this indicates common-name mismatch */ public static final int BAD_CERT_DOMAIN = -12288 + 12; private Vector reasons = new Vector(); /** * add a new failure reason to this enumeration. This is called from the * native code callback when it does a verify on the cert chain * * @param newReason sslerr.h error code - see constants defined above; * @param cert a reference to the cert - so you can see the subject name, etc * @param depth the index of this cert in the chain. 0 is the server cert. */ public void addReason(int newReason, PK11Cert cert, int depth) { ValidityItem status = new ValidityItem(newReason,cert,depth); reasons.addElement(status); } /** * returns an enumeration. The elements in the enumeration are * all of type 'ValidityItem' */ public Enumeration getReasons() { return reasons.elements(); } } class ValidityItem { private int reason; private int depth; private PK11Cert cert; public ValidityItem(int reason, PK11Cert cert, int depth) { this.reason = reason; this.cert = cert; this.depth = depth; } /** * @return the NSS error code which caused the error - see the list of * error codes above for those which could be returned */ public int getReason() { return reason; } /** * @return the index into the cert chain of the certificate which caused * this error. In a chain 5-certs long, 0 is the server-cert. * 1,2,3 would be the intermediates, and 4 would be the root */ public int getDepth() { return depth; } /** * @return the certificate associated with this error. You can use * the X509Certificate functions to get details such as issuer/subject * name, serial number, etc. */ public PK11Cert getCert() { return cert; } } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLCipher.java000066400000000000000000000260761326145000000214170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; /** * SSL cipher. */ public enum SSLCipher { /** * * Note the following cipher-suites constants are not all implemented. * You need to call SSLSocket.getImplementedCiphersuites(). * */ SSL2_RC4_128_WITH_MD5 (0xFF01), SSL2_RC4_128_EXPORT40_WITH_MD5 (0xFF02), SSL2_RC2_128_CBC_WITH_MD5 (0xFF03), SSL2_RC2_128_CBC_EXPORT40_WITH_MD5 (0xFF04), SSL2_IDEA_128_CBC_WITH_MD5 (0xFF05), SSL2_DES_64_CBC_WITH_MD5 (0xFF06), SSL2_DES_192_EDE3_CBC_WITH_MD5 (0xFF07), /** * @deprecated Replaced with TLS_RSA_WITH_NULL_MD5. */ @Deprecated SSL3_RSA_WITH_NULL_MD5 (0x0001), TLS_RSA_WITH_NULL_MD5 (0x0001), /** * @deprecated Replaced with TLS_RSA_WITH_NULL_SHA. */ @Deprecated SSL3_RSA_WITH_NULL_SHA (0x0002), TLS_RSA_WITH_NULL_SHA (0x0002), SSL3_RSA_EXPORT_WITH_RC4_40_MD5 (0x0003), /** * @deprecated Replaced with TLS_RSA_WITH_RC4_128_MD5. */ @Deprecated SSL3_RSA_WITH_RC4_128_MD5 (0x0004), TLS_RSA_WITH_RC4_128_MD5 (0x0004), /** * @deprecated Replaced with TLS_RSA_WITH_RC4_128_SHA. */ @Deprecated SSL3_RSA_WITH_RC4_128_SHA (0x0005), TLS_RSA_WITH_RC4_128_SHA (0x0005), SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5 (0x0006), /** * @deprecated Replaced with TLS_RSA_WITH_IDEA_CBC_SHA. */ @Deprecated SSL3_RSA_WITH_IDEA_CBC_SHA (0x0007), TLS_RSA_WITH_IDEA_CBC_SHA (0x0007), SSL3_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0008), /** * @deprecated Replaced with TLS_RSA_WITH_DES_CBC_SHA. */ @Deprecated SSL3_RSA_WITH_DES_CBC_SHA (0x0009), TLS_RSA_WITH_DES_CBC_SHA (0x0009), /** * @deprecated Replaced with TLS_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_RSA_WITH_3DES_EDE_CBC_SHA (0x000a), TLS_RSA_WITH_3DES_EDE_CBC_SHA (0x000a), SSL3_DH_DSS_EXPORT_WITH_DES40_CBC_SHA (0x000b), /** * @deprecated Replaced with TLS_DH_DSS_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DH_DSS_WITH_DES_CBC_SHA (0x000c), TLS_DH_DSS_WITH_DES_CBC_SHA (0x000c), /** * @deprecated Replaced with TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DH_DSS_WITH_3DES_EDE_CBC_SHA (0x000d), TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA (0x000d), SSL3_DH_RSA_EXPORT_WITH_DES40_CBC_SHA (0x000e), /** * @deprecated Replaced with TLS_DH_RSA_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DH_RSA_WITH_DES_CBC_SHA (0x000f), TLS_DH_RSA_WITH_DES_CBC_SHA (0x000f), /** * @deprecated Replaced with TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DH_RSA_WITH_3DES_EDE_CBC_SHA (0x0010), TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA (0x0010), SSL3_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA (0x0011), /** * @deprecated Replaced with TLS_DHE_DSS_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DHE_DSS_WITH_DES_CBC_SHA (0x0012), TLS_DHE_DSS_WITH_DES_CBC_SHA (0x0012), /** * @deprecated Replaced with TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013), TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA (0x0013), SSL3_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA (0x0014), /** * @deprecated Replaced with TLS_DHE_RSA_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DHE_RSA_WITH_DES_CBC_SHA (0x0015), TLS_DHE_RSA_WITH_DES_CBC_SHA (0x0015), /** * @deprecated Replaced with TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016), TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA (0x0016), SSL3_DH_ANON_EXPORT_WITH_RC4_40_MD5 (0x0017), /** * @deprecated Replaced with TLS_DH_anon_WITH_RC4_128_MD5. */ @Deprecated SSL3_DH_ANON_WITH_RC4_128_MD5 (0x0018), TLS_DH_anon_WITH_RC4_128_MD5 (0x0018), SSL3_DH_ANON_EXPORT_WITH_DES40_CBC_SHA (0x0019), /** * @deprecated Replaced with TLS_DH_anon_WITH_DES_CBC_SHA. */ @Deprecated SSL3_DH_ANON_WITH_DES_CBC_SHA (0x001a), TLS_DH_anon_WITH_DES_CBC_SHA (0x001a), /** * @deprecated Replaced with TLS_DH_anon_WITH_3DES_EDE_CBC_SHA. */ @Deprecated SSL3_DH_ANON_WITH_3DES_EDE_CBC_SHA (0x001b), TLS_DH_anon_WITH_3DES_EDE_CBC_SHA (0x001b), /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated SSL3_FORTEZZA_DMS_WITH_NULL_SHA (0x001c), /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA (0x001d), /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA (0x001e), SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA (0xfeff), SSL_RSA_FIPS_WITH_DES_CBC_SHA (0xfefe), TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA (0x0062), TLS_RSA_EXPORT1024_WITH_RC4_56_SHA (0x0064), TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA (0x0063), TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA (0x0065), TLS_DHE_DSS_WITH_RC4_128_SHA (0x0066), TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x0067), TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x006B), // New TLS cipher suites in NSS 3.4 TLS_RSA_WITH_AES_128_CBC_SHA (0x002F), TLS_DH_DSS_WITH_AES_128_CBC_SHA (0x0030), TLS_DH_RSA_WITH_AES_128_CBC_SHA (0x0031), TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x0032), TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x0033), /** * @deprecated Replaced with TLS_DH_anon_WITH_AES_128_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_AES_128_CBC_SHA (0x0034), TLS_DH_anon_WITH_AES_128_CBC_SHA (0x0034), TLS_RSA_WITH_AES_256_CBC_SHA (0x0035), TLS_DH_DSS_WITH_AES_256_CBC_SHA (0x0036), TLS_DH_RSA_WITH_AES_256_CBC_SHA (0x0037), TLS_DHE_DSS_WITH_AES_256_CBC_SHA (0x0038), TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x0039), /** * @deprecated Replaced with TLS_DH_anon_WITH_AES_256_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_AES_256_CBC_SHA (0x003A), TLS_DH_anon_WITH_AES_256_CBC_SHA (0x003A), TLS_RSA_WITH_NULL_SHA256 (0x003B), TLS_RSA_WITH_AES_128_CBC_SHA256 (0x003C), TLS_RSA_WITH_AES_256_CBC_SHA256 (0x003D), TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0041), TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0042), TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0043), TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA (0x0044), TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA (0x0045), /** * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA (0x0046), TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA (0x0046), TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0084), TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0085), TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0086), TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA (0x0087), TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA (0x0088), /** * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA. */ @Deprecated TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA (0x0089), TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA (0x0089), TLS_RSA_WITH_SEED_CBC_SHA (0x0096), TLS_RSA_WITH_AES_128_GCM_SHA256 (0x009C), TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x009E), TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 (0x00A2), TLS_ECDH_ECDSA_WITH_NULL_SHA (0xc001, true), TLS_ECDH_ECDSA_WITH_RC4_128_SHA (0xc002, true), TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc003, true), TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA (0xc004, true), TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA (0xc005, true), TLS_ECDHE_ECDSA_WITH_NULL_SHA (0xc006, true), TLS_ECDHE_ECDSA_WITH_RC4_128_SHA (0xc007, true), TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA (0xc008, true), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009, true), TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a, true), TLS_ECDH_RSA_WITH_NULL_SHA (0xc00b, true), TLS_ECDH_RSA_WITH_RC4_128_SHA (0xc00c, true), TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA (0xc00d, true), TLS_ECDH_RSA_WITH_AES_128_CBC_SHA (0xc00e, true), TLS_ECDH_RSA_WITH_AES_256_CBC_SHA (0xc00f, true), TLS_ECDHE_RSA_WITH_NULL_SHA (0xc010, true), TLS_ECDHE_RSA_WITH_RC4_128_SHA (0xc011, true), TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA (0xc012, true), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013, true), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014, true), TLS_ECDH_anon_WITH_NULL_SHA (0xc015, true), TLS_ECDH_anon_WITH_RC4_128_SHA (0xc016, true), TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA (0xc017, true), TLS_ECDH_anon_WITH_AES_128_CBC_SHA (0xc018, true), TLS_ECDH_anon_WITH_AES_256_CBC_SHA (0xc019, true), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 (0xc023, true), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027, true), TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02B, true), TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02D, true), TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02F, true), TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 (0xc031, true); private int id; private boolean ecc; private SSLCipher(int id) { this.id = id; } private SSLCipher(int id, boolean ecc) { this.id = id; this.ecc = ecc; } public int getID() { return id; } public boolean isECC() { return ecc; } public static SSLCipher valueOf(int id) { for (SSLCipher cipher : SSLCipher.class.getEnumConstants()) { if (cipher.id == id) return cipher; } return null; } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLClient.java000066400000000000000000000274621326145000000214230ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // This demonstrates the SSL client-side support // package org.mozilla.jss.ssl; import java.io.*; import java.util.*; import java.net.*; import org.mozilla.jss.*; import org.mozilla.jss.crypto.AlreadyInitializedException; /** * Parameters supported by this socket test: * * filename file to be read from https server (default: /index.html) * port port to connect to (default: 443) * ipaddr address to connect to (overrides hostname, no default) * hostname host to connect to (no default) * clientauth do client-auth or not (default: no client-auth) * * The following parameters are used for regression testing, so * we can print success or failure of the test. * * filesize size of file to be read * status security status of connection - this has to be an integer * cipher * sessionKeySize * sessionSecretSize * issuer * subject * certSerialNum * */ public class SSLClient { boolean handshakeEventHappened = false; boolean doClientAuth = false; Hashtable args; PrintStream results; String versionStr; String argNames[] = { "filename", "port", "ipaddr", "hostname", "filesize", "status", "sessionKeySize", "sessionSecretSize", "cipher", "issuer", "subject", "certSerialNum", }; String values[] = { "/index", // filename "443", // port to connect to "", // ipaddr (use hostname instead) "trading.etrade.com", // hostname to connect to "1024", // filesize "2", // status, 2 means ??? "128", // expected session key size "128", // expected session key secret bits "RC48", // expected cipher "CN=Hardcore Certificate Server II, OU=Hardcore, O=Netscape Communications Corporation, C=US", // expected issuer DN of server "CN=hbombsgi.mcom.com, OU=Hardcore, C=US", // expected subject DN of server "00C3", // serial number }; String okay = "okay"; String failed = "FAILED"; private static String htmlHeader = "SSL Client Tester"; private static String htmlTail = "\n"; /* simple helper functions */ private boolean isInvalid(String s) { return (s == null) || s.equals(""); } private String getArgument(String key) { return (String) args.get(key); } /* * return "okay" or "FAILED" based on equality of * the argument strings */ private String cmp(String s1, String s2) { if(s1 == s2) return okay; if(s1 == null) return failed; if(s1.equals(s2)) return okay; return failed; } private String cmp(String s1, int s2) { return cmp(s1, new Integer(s2).toString()); } public void run(boolean printHeader) { try { SSLHandshakeCompletedListener listener = null; if(printHeader) results.println(htmlHeader); results.println("SSL Client Tester"); results.println( "$Id$ " + versionStr ); SSLSocket s; String hostname; int port; String filename = getArgument("filename"); if(isInvalid(filename)) { filename = "/index.html"; } String msg = "GET " + filename; String portstr = getArgument("port"); if(isInvalid(portstr)) { port = 443; } else { port = Integer.valueOf(portstr).intValue(); } String addrstr = getArgument("ipaddr"); hostname = addrstr; // unless it gets changed String tmpStr = getArgument("clientauth"); if(isInvalid(tmpStr)) doClientAuth = false; else { tmpStr = tmpStr.toLowerCase(); doClientAuth = !(tmpStr.equals("off") || tmpStr.equals("false") || tmpStr.equals("0")); } if(isInvalid(addrstr)) { // check for a host name hostname = getArgument("hostname"); if(isInvalid(hostname)) { throw new Exception("hostname not specified"); } } results.println("Connecting to " + hostname + " on port " + port ); SSLCertificateApprovalCallback approvalCallback = new TestCertApprovalCallback(); SSLClientCertificateSelectionCallback certSelectionCallback = new TestClientCertificateSelectionCallback(); Socket js = new Socket(InetAddress.getByName(hostname), port); //s = new SSLSocket(hostname, port, null, 0, s = new SSLSocket(js, hostname, approvalCallback, certSelectionCallback ); s.forceHandshake(); results.println("Connected."); // select the cert for client auth // You will have to provide a certificate with this // name if you expect client auth to work. //s.setClientCertNickname("JavaSSLTestClientCert"); // Setup a handshake callback. This listener will get invoked // When the SSL handshake is completed on this socket. listener = new ClientHandshakeCB(this); s.addHandshakeCompletedListener(listener); //s.forceHandshake(); OutputStream o = s.getOutputStream(); PrintOutputStreamWriter out = new PrintOutputStreamWriter(o); results.println("Sending: " + msg + " to " + hostname + ", " + port ); // send HTTP GET message across SSL connection out.println(msg + "\r"); InputStream in = s.getInputStream(); byte[] bytes = new byte[4096]; int totalBytes = 0; int numReads = 0; String lastBytes = null; // now try to read data back from the SSL connection try { for(;;) { results.println("Calling Read."); int n = in.read(bytes, 0, bytes.length); if(n == -1) { results.println("EOF found."); break; } if(n == 0) { results.println("Zero bytes read?"); break; } numReads++; if(totalBytes == 0) { // don't print forever... String data = new String(bytes, 0, 30, "8859_1"); results.println("Read " + n + " bytes of data"); results.println("First 30 bytes: " + escapeHTML(data)); } totalBytes += n; lastBytes = new String(bytes, n-31, 30, "8859_1"); } } catch (IOException e) { results.println( "IOException while reading from pipe? Actually got " + totalBytes + " bytes total"); e.printStackTrace(results); results.println(""); throw e; } finally { results.println("Last 30 bytes: " + lastBytes); results.println("Number of read() calls: " + numReads ); /* * if you want to test sslimpl.c's nsn_ThrowError(), try * uncommenting the following line. This will cause the * getStatus() call to fail. */ // in.close(); results.println("Diagnostics"); String tmp; SSLSecurityStatus status = s.getStatus(); results.println("Total bytes read: " + totalBytes ); results.println("Security status of session:"); results.println(status.toString()); // now, for the regression testing stuff if (false) { results.println("Regression Tests"); results.println("Handshake callback event happened: " + ((handshakeEventHappened) ? okay : failed)); if(!isInvalid(tmp = getArgument("filesize"))) { results.println("filesize: " + cmp(tmp, totalBytes)); } if(!isInvalid(tmp = getArgument("status"))) { results.println("status: " + cmp(tmp, status.getSecurityStatus())); } if(!isInvalid(tmp = getArgument("sessionKeySize"))) { results.println("sessionKeySize: " + cmp(tmp, status.getSessionKeySize())); } if(!isInvalid(tmp = getArgument("sessionSecretSize"))) { results.println("sessionSecretSize: " + cmp(tmp, status.getSessionSecretSize())); } if(!isInvalid(tmp = getArgument("cipher"))) { results.println("cipher: " + cmp(tmp, status.getCipher())); } if(!isInvalid(tmp = getArgument("issuer"))) { results.println("issuer: " + cmp(tmp, status.getRemoteIssuer())); } if(!isInvalid(tmp = getArgument("subject"))) { results.println("subject: " + cmp(tmp, status.getRemoteSubject())); } if(!isInvalid(tmp = getArgument("certSerialNum"))) { String serialNum = status.getSerialNumber(); results.println("certSerialNum: " + cmp(tmp, serialNum)); } } // if false } // Got here, so no exception thrown above. // Try to clean up. o.close(); o = null; in.close(); in = null; if (listener != null) { s.removeHandshakeCompletedListener(listener); listener = null; } s.close(); s = null; } catch(Exception e) { results.println("***** TEST FAILED *****"); e.printStackTrace(results); results.println("If there is no stack trace, try disabling the JIT and trying again."); } results.println("END OF TEST"); } /** * given an input string, convert less-than, greater-than, and ampersand * from raw characters to escaped characters * (< becomes `&lt;', etc.) */ private String escapeHTML(String s) { StringBuffer result = new StringBuffer(); // this is inefficient, but I don't care for(int i=0; i': result.append(">"); break; case '&': result.append("&"); break; default: result.append(c); break; } } return result.toString(); } public SSLClient( PrintStream ps, String verStr, String[] argv) { this.args = new Hashtable(); this.results = ps; this.versionStr = verStr; for(int i=0; i 0) { size = (int) (n < 2048 ? n : 2048); int nread = read(trash, 0, size); if( nread <= 0 ) { break; } numSkipped += nread; n -= nread; } return numSkipped; } private SSLSocket sock; } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLOutputStream.java000066400000000000000000000014461326145000000226530ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.io.IOException; class SSLOutputStream extends java.io.OutputStream { SSLOutputStream(SSLSocket sock) { this.sock = sock; } public void write(int b) throws IOException { write( new byte[] {(byte)b}, 0, 1 ); } public void write(byte[] b) throws IOException { write( b, 0, b.length); } public void write(byte[] b, int off, int len) throws IOException { sock.write(b, off, len); } public void close() throws IOException { sock.close(); } private SSLSocket sock; } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLSecurityStatus.java000066400000000000000000000102761326145000000232130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.io.IOException; import java.io.InterruptedIOException; import java.net.*; import org.mozilla.jss.crypto.X509Certificate; /** * This class represents the known state of an SSL connection: what cipher * is being used, how secure it is, and who's on the other end. */ public class SSLSecurityStatus { int status; String cipher; int sessionKeySize; int sessionSecretSize; String issuer; String subject; String serialNumber; X509Certificate certificate; // Certificate may be null if client does not present certificate final public int STATUS_NOOPT = -1; final public int STATUS_OFF = 0; final public int STATUS_ON_HIGH = 1; final public int STATUS_ON_LOW = 2; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * STATUS_FORTEZZA is a placeholder for backward compatibility. */ final public int STATUS_FORTEZZA = 3; /** * This constructor is called from the native SSL code * It's not necessary for you to call this. */ public SSLSecurityStatus(int status, String cipher, int sessionKeySize, int sessionSecretSize, String issuer, String subject, String serialNumber, X509Certificate certificate) { String noCert = "no certificate"; this.status = status; this.cipher = cipher; this.sessionKeySize = sessionKeySize; this.sessionSecretSize = sessionSecretSize; this.certificate = certificate; if(noCert.equals(issuer)) this.issuer = null; else this.issuer = issuer; if(noCert.equals(subject)) this.subject = null; else this.subject = subject; this.serialNumber = serialNumber; } /** * Query if security is enabled on this socket. */ public boolean isSecurityOn() { return status > 0; } /** * Get exact security status of socket. */ public int getSecurityStatus() { return status; } /** * Query which cipher is being used in this session. */ public String getCipher() { return cipher; } /** * Query how many bits long the session key is. More bits are better. */ public int getSessionKeySize() { return sessionKeySize; } /** * To satisfy export restrictions, some of the session key may * be revealed. This function tells you how many bits are * actually secret. */ public int getSessionSecretSize() { return sessionSecretSize; } /** * Get the distinguished name of the remote certificate's issuer */ public String getRemoteIssuer() { return issuer; } /** * Get the distinguished name of the subject of the remote certificate */ public String getRemoteSubject() { return subject; } /** * Get the serial number of the remote certificate */ public String getSerialNumber() { return serialNumber; } /** * Retrieve certificate presented by the other other end * of the socket

Not Supported in NSS 2.0 Beta release. *

Can be null if peer did not present a certificate. */ public X509Certificate getPeerCertificate() { return certificate; } /** * Get a pretty string to show to a user, summarizing the contents * of this object */ public String toString() { String statusString; switch(status) { case STATUS_NOOPT: statusString = "NOOPT"; break; case STATUS_OFF: statusString = "OFF"; break; case STATUS_ON_HIGH: statusString = "ON HIGH"; break; case STATUS_ON_LOW: statusString = "ON LOW"; break; case STATUS_FORTEZZA: statusString = "FORTEZZA"; break; default: statusString = "unknown"; break; } return "Status: " + statusString + "\n" + "Cipher: " + cipher + "\n" + "Session key size: " + sessionKeySize + "\n" + "Session secret size: " + sessionSecretSize + "\n" + "Issuer: " + issuer + "\n" + "Subject: " + subject + "\n" + "Serial number: " + serialNumber + "\n"; } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLServer.java000066400000000000000000000214651326145000000214500ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ // This program demonstrates SSL server-side support. It expects // (HTTP) clients to connect to it, and will respond to HTTP // GET requests // // tabstops: 4 package org.mozilla.jss.ssl; import java.io.*; import java.util.*; import org.mozilla.jss.*; /** * Parameters supported by this socket test: * * filename file to be read from https server (default: /index.html) * port port to connect to (default: 443) * clientauth do client-auth or not (default: no client-auth) * * The following parameters are used for regression testing, so * we can print success or failure of the test. * * filesize size of file to be read * status security status of connection - this has to be an integer * */ public class SSLServer { boolean handshakeEventHappened = false; boolean doClientAuth = false; Hashtable args; PrintStream results; String versionStr; String argNames[] = { "filename", "port", "filesize", "clientauth", "nickname" }; String values[] = { "data1k.txt", // filename "2000", // port "1024", // filesize "false", // request client auth "SSLServer" // nickname of cert to use }; private static String htmlHeader = "SSL Server Tester"; private static String htmlTail = "\n"; /* simple helper functions */ private boolean isInvalid(String s) { return (s == null) || s.equals(""); } private String getArgument(String key) { return (String) args.get(key); } String okay = "okay"; String failed = "FAILED"; /* * return "okay" or "FAILED" based on equality of * the argument strings */ private String cmp(String s1, String s2) { if(s1 == s2) return okay; if(s1 == null) return failed; if(s1.equals(s2)) return okay; return failed; } private String cmp(String s1, int s2) { return cmp(s1, new Integer(s2).toString()); } public void run() { try { SSLServerSocket l; SSLSocket s; int port; String tmpStr; String portStr; String nickname; results.println(htmlHeader); portStr = getArgument("port"); if(isInvalid(portStr)) { port = 443; } else { port = Integer.valueOf(portStr).intValue(); } results.println("here"); tmpStr = getArgument("clientauth"); if(!isInvalid(tmpStr)) { tmpStr = tmpStr.toLowerCase(); doClientAuth = !(tmpStr.equals("off") || tmpStr.equals("false") || tmpStr.equals("0")); } l = new SSLServerSocket(port); results.println("Listening " + l.toString()); // select the server's cert/key nickname = getArgument("nickname"); results.println("Getting Cert:"+nickname+""); l.setServerCertNickname(nickname); if (doClientAuth) { l.setNeedClientAuth(true); } // wait for and accept a connection. s = (SSLSocket)l.accept(); results.println("Accepted."); handleConnection(s); // handleConnection will close s, as appropriate. s = null; l.close(); l = null; } catch(Exception e) { results.println("***** TEST FAILED *****"); e.printStackTrace(results); results.println( "If there is no stack trace, try disabling the JIT and trying again."); } results.println("END OF TEST"); } public void handleConnection(SSLSocket s) throws Exception { SSLHandshakeCompletedListener listener = null; listener = new ServerHandshakeCB(this); s.addHandshakeCompletedListener(listener); results.println("Connected to " + s.toString()); InputStream in = s.getInputStream(); byte[] bytes = new byte[4096]; int totalBytes = 0; int numReads = 0; // now try to read data from the SSL connection try { boolean endFound = false; while(! endFound && totalBytes < bytes.length) { results.println("Calling Read."); int n = in.read(bytes, totalBytes, bytes.length - totalBytes); if(n == -1) { results.println("EOF found."); break; } if(n == 0) { results.println("Zero bytes read?"); break; } numReads++; results.println("Read " + n + " bytes of data"); totalBytes += n; for (int i = 0; i + 3 < bytes.length; ++i) { if (bytes[i] == 0x0D && bytes[i+1] == 0x0A && bytes[i+2] == 0x0D && bytes[i+3] == 0x0A ) { results.println("Empty line found."); endFound = true; break; } } } } catch (IOException e) { results.println( "IOException while reading from pipe? Actually got " + totalBytes + " bytes total"); e.printStackTrace(results); results.println(""); throw e; } results.println("Number of read() calls: " + numReads ); results.println("Total bytes read: " + totalBytes ); String msg = null; if (totalBytes > 0) { msg = new String(bytes, 0, totalBytes, "8859_1"); results.println("Request received:"); results.println(msg); results.println(""); } SSLSecurityStatus status = s.getStatus(); results.println("Security status of session:"); results.println(status.toString()); results.println("Handshake callback event happened: " + ((handshakeEventHappened) ? okay : failed)); OutputStream os = s.getOutputStream(); PrintOutputStreamWriter out = new PrintOutputStreamWriter(os); os = null; // don't keep this reference lying around String reply = "HTTP/1.0 200 OK\r\n" + "Server: Netscape-Enterprise/2.0a\r\n" + "Date: Tue, 01 Apr 1998 22:10:05 GMT\r\n" + "Content-type: text/plain\r\n" + "\r\n" + msg; out.println(reply); // Got here, so no exception thrown above. // Try to clean up. in.close(); in = null; if (listener != null) { s.removeHandshakeCompletedListener(listener); listener = null; } out.close(); out = null; s.close(); s = null; } /** * given an input string, convert less-than, greater-than, and ampersand * from raw characters to escaped characters * (< becomes `&lt;', etc.) */ private String escapeHTML(String s) { StringBuffer result = new StringBuffer(); // this is inefficient, but I don't care for(int i=0; i': result.append(">"); break; case '&': result.append("&"); break; default: result.append(c); break; } } return result.toString(); } public SSLServer( PrintStream ps, String verStr) { this.args = new Hashtable(); this.results = ps; this.versionStr = verStr; for(int i=0; i #include #include #include #include #include #include #include #include #include #include "jssl.h" #ifdef WINNT #include #endif JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_socketListen (JNIEnv *env, jobject self, jint backlog) { JSSL_SocketData *sock; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; if( PR_Listen(sock->fd, backlog) != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "Failed to set listen backlog on socket"); goto finish; } finish: return; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_socketAccept (JNIEnv *env, jobject self, jobject newSock, jint timeout, jboolean handshakeAsClient) { JSSL_SocketData *sock; PRNetAddr addr; PRFileDesc *newFD=NULL; PRIntervalTime ivtimeout; JSSL_SocketData *newSD=NULL; jbyteArray sdArray = NULL; SECStatus status; PRThread *me; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout) : PR_INTERVAL_NO_TIMEOUT; if( handshakeAsClient ) { status = SSL_OptionSet(sock->fd, SSL_HANDSHAKE_AS_CLIENT, PR_TRUE); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Failed to set option to handshake as client"); goto finish; } } /* Set the current thread doing the accept. */ me = PR_GetCurrentThread(); PR_Lock(sock->lock); if ( sock->closePending ) { PR_Unlock(sock->lock); JSSL_throwSSLSocketException(env, "Accept operation failed: socket is closing"); goto finish; } PR_ASSERT(sock->accepter == NULL); sock->accepter = me; PR_Unlock(sock->lock); newFD = PR_Accept(sock->fd, &addr, ivtimeout); PR_Lock(sock->lock); PR_ASSERT(sock->accepter == me); sock->accepter = NULL; PR_Unlock(sock->lock); if( newFD == NULL ) { PRErrorCode err = PR_GetError(); if( err == PR_PENDING_INTERRUPT_ERROR ) { #ifdef WINNT /* Clean up after PR_interrupt. */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Accept operation interrupted"); } else if( err == PR_IO_TIMEOUT_ERROR ) { #ifdef WINNT PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Accept operation timed out"); } else if( err == PR_IO_ERROR ) { JSSL_throwSSLSocketException(env, "Accept operation received IO error"); } else { JSSL_throwSSLSocketException(env, "Accept operation failed"); } goto finish; } newSD = JSSL_CreateSocketData(env, newSock, newFD, NULL /* priv */); if( newSD == NULL ) { goto finish; } newFD = NULL; /* setup the handshake callback */ status = SSL_HandshakeCallback(newSD->fd, JSSL_HandshakeCallback, newSD); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install handshake callback"); goto finish; } /* pass the pointer back to Java */ sdArray = JSS_ptrToByteArray(env, (void*) newSD); if( sdArray == NULL ) { /* exception was thrown */ goto finish; } finish: if( (*env)->ExceptionOccurred(env) != NULL ) { if( newSD != NULL ) { JSSL_DestroySocketData(env, newSD); } if( newFD != NULL ) { PR_Close(newFD); } } return sdArray; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_abortAccept( JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; /* * The java layer prevents I/O once close has been * called but if an accept is in progress then abort it. * For WINNT the accept method must check for * PR_PENDING_INTERRUPT_ERROR and call PR_NT_CancelIo. */ PR_Lock(sock->lock); if ( sock->accepter ) { PR_Interrupt(sock->accepter); } sock->closePending = PR_TRUE; /* socket is to be closed */ PR_Unlock(sock->lock); finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_clearSessionCache( JNIEnv *env, jclass clazz) { SSL_ClearSessionCache(); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_configServerSessionIDCache( JNIEnv *env, jclass myClass, jint maxEntries, jint ssl2Timeout, jint ssl3Timeout, jstring nameString) { const char* dirName = NULL; SECStatus status; if (nameString != NULL) { dirName = (*env)->GetStringUTFChars(env, nameString, NULL); } status = SSL_ConfigServerSessionIDCache( maxEntries, ssl2Timeout, ssl3Timeout, dirName); if (status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to configure server session ID cache"); goto finish; } finish: if(dirName != NULL) { (*env)->ReleaseStringUTFChars(env, nameString, dirName); } } /* * This is here for backwards binary compatibility: I didn't want to remove * the symbol from the DLL. This would only get called if someone were using * a pre-3.2 version of the JSS classes with this post-3.2 library. Using * different versions of the classes and the C code is not supported. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCertNickname( JNIEnv *env, jobject self, jstring nick) { PR_ASSERT(0); JSS_throwMsg(env, SOCKET_EXCEPTION, "JSS JAR/DLL version mismatch"); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCert( JNIEnv *env, jobject self, jobject certObj) { JSSL_SocketData *sock; CERTCertificate* cert=NULL; PK11SlotInfo* slot=NULL; SECKEYPrivateKey* privKey=NULL; SSLKEAType certKEA; SECStatus status; if( certObj == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; if( JSS_PK11_getCertPtr(env, certObj, &cert) != PR_SUCCESS ) { goto finish; } PR_ASSERT(cert!=NULL); /* shouldn't happen */ if( JSS_PK11_getCertSlotPtr(env, certObj, &slot) != PR_SUCCESS ) { goto finish; } PR_ASSERT(slot!=NULL); /* shouldn't happen */ privKey = PK11_FindPrivateKeyFromCert(slot, cert, NULL); if (privKey != NULL) { certKEA = NSS_FindCertKEAType(cert); status = SSL_ConfigSecureServer(sock->fd, cert, privKey, certKEA); if( status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to configure secure server certificate and key"); goto finish; } } else { JSSL_throwSSLSocketException(env, "Failed to locate private key"); goto finish; } finish: if(privKey!=NULL) { SECKEY_DestroyPrivateKey(privKey); } } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_setReuseAddress( JNIEnv *env, jobject self, jboolean reuse) { JSSL_SocketData *sock; PRStatus status; PRSocketOptionData sockOptData; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; sockOptData.option = PR_SockOpt_Reuseaddr; sockOptData.value.reuse_addr = ((reuse == JNI_TRUE) ? PR_TRUE : PR_FALSE ); status = PR_SetSocketOption(sock->fd, &sockOptData); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLServerSocket_getReuseAddress( JNIEnv *env, jobject self) { JSSL_SocketData *sock; PRStatus status; PRSocketOptionData sockOptData; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; sockOptData.option = PR_SockOpt_Reuseaddr; status = PR_GetSocketOption(sock->fd, &sockOptData); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: /* If we got here via failure, reuse_addr might be uninitialized. But in * that case we're throwing an exception, so the return value doesn't * matter. */ return ((sockOptData.value.reuse_addr == PR_TRUE) ? JNI_TRUE : JNI_FALSE); } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLServerSocket.java000066400000000000000000000466601326145000000226250ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.util.*; import java.net.InetAddress; import java.io.IOException; import java.net.Socket; import java.net.SocketException; import java.net.SocketTimeoutException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.TokenException; /** * SSL server socket. */ public class SSLServerSocket extends java.net.ServerSocket { /* * Locking rules of SSLServerSocket * * isClosed and inAccept must be accessed with the object locked. * * acceptLock must be locked throughout the accept method. It is * used to serialize accept calls on the object. */ private SocketProxy sockProxy = null; private boolean handshakeAsClient = false; private SocketBase base = new SocketBase(); private boolean isClosed = false; private boolean inAccept = false; private java.lang.Object acceptLock = new java.lang.Object(); /** * The default size of the listen queue. */ public static final int DEFAULT_BACKLOG = 50; /** * Creates a server socket listening on the given port. * The listen queue will be of size DEFAULT_BACKLOG. */ public SSLServerSocket(int port) throws IOException { this(port, DEFAULT_BACKLOG, null); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. */ public SSLServerSocket(int port, int backlog) throws IOException { this(port, backlog, null); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. * @param bindAddr The local address to which to bind. If null, an * unspecified local address will be bound to. */ public SSLServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException { this(port, backlog, bindAddr, null); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. * @param bindAddr The local address to which to bind. If null, an * unspecified local address will be bound to. * @param certApprovalCallback Will get called to approve any certificate * presented by the client. */ public SSLServerSocket(int port, int backlog, InetAddress bindAddr, SSLCertificateApprovalCallback certApprovalCallback) throws IOException { this(port,backlog, bindAddr, certApprovalCallback, false); } /** * Creates a server socket listening on the given port. * @param backlog The size of the socket's listen queue. * @param bindAddr The local address to which to bind. If null, an * unspecified local address will be bound to. * @param certApprovalCallback Will get called to approve any certificate * presented by the client. * @param reuseAddr Reuse the local bind port; this parameter sets * the SO_REUSEADDR option on the socket before calling * bind(). The default is false for backward * compatibility. */ public SSLServerSocket(int port, int backlog, InetAddress bindAddr, SSLCertificateApprovalCallback certApprovalCallback, boolean reuseAddr) throws IOException { // Dance the dance of fools. The superclass doesn't have a default // constructor, so we have to trick it here. This is an example // of WHY WE SHOULDN'T BE EXTENDING SERVERSOCKET. super(0); super.close(); // create the socket int socketFamily = SocketBase.SSL_AF_INET; if(SocketBase.supportsIPV6()) { socketFamily = SocketBase.SSL_AF_INET6; } sockProxy = new SocketProxy( base.socketCreate(this, certApprovalCallback, null,socketFamily) ); base.setProxy(sockProxy); setReuseAddress(reuseAddr); byte[] bindAddrBA = null; if( bindAddr != null ) { bindAddrBA = bindAddr.getAddress(); } base.socketBind(bindAddrBA, port); String hostName = null; if(bindAddr != null) { hostName = bindAddr.getCanonicalHostName(); } socketListen(backlog); } private native void socketListen(int backlog) throws SocketException; /** * Accepts a connection. This call will block until a connection is made * or the timeout is reached. * * @return java.net.Socket Local socket for client communication * * @throws IOException If an input or output exception occurred * @throws SocketTimeoutException If the socket times out trying to connect * @throws SSLSocketException JSS subclass of java.net.SocketException */ public Socket accept() throws IOException { synchronized (acceptLock) { synchronized (this) { if (isClosed) { throw new IOException( "SSLServerSocket has been closed, and cannot be reused."); } inAccept = true; } SSLSocket s = new SSLSocket(); try { /* * socketAccept can throw an exception for timeouts, * IO errors, or PR_Interrupt called by abortAccept. * So first get a socket pointer, and if successful * create the SocketProxy. */ byte[] socketPointer = null; socketPointer = socketAccept(s, base.getTimeout(), handshakeAsClient); SocketProxy sp = new SocketProxy(socketPointer); s.setSockProxy(sp); } finally { synchronized (this) { inAccept=false; } } return s; } } /** * Sets the SO_TIMEOUT socket option. * @param timeout The timeout time in milliseconds. */ public void setSoTimeout(int timeout) { base.setTimeout(timeout); } /** * Returns the current value of the SO_TIMEOUT socket option. * @return The timeout time in milliseconds. */ public int getSoTimeout() { return base.getTimeout(); } public native void setReuseAddress(boolean reuse) throws SocketException; public native boolean getReuseAddress() throws SocketException; private native void abortAccept() throws SocketException; private native byte[] socketAccept(SSLSocket s, int timeout, boolean handshakeAsClient) throws SocketException, SocketTimeoutException; /** * Empties the SSL client session ID cache. */ public static native void clearSessionCache(); protected void finalize() throws Throwable { close(); /* in case user never called close */ } /** * @return The local port. */ public int getLocalPort() { return base.getLocalPort(); } /** * Closes this socket. */ public void close() throws IOException { synchronized (this) { if( isClosed ) { /* finalize calls close or user calls close more than once */ return; } isClosed = true; if( sockProxy == null ) { /* nothing to do */ return; } if( inAccept ) { abortAccept(); } } /* Lock acceptLock to ensure that accept has been aborted. */ synchronized (acceptLock) { base.close(); sockProxy = null; base.setProxy(null); } } // This directory is used as the default for the Session ID cache private final static String UNIX_TEMP_DIR = "/tmp"; private final static String WINDOWS_TEMP_DIR = "\\temp"; /** * Configures the session ID cache. * @param maxSidEntries The maximum number of entries in the cache. If * 0 is passed, the default of 10,000 is used. * @param ssl2EntryTimeout The lifetime in seconds of an SSL2 session. * The minimum timeout value is 5 seconds and the maximum is 24 hours. * Values outside this range are replaced by the server default value * of 100 seconds. * @param ssl3EntryTimeout The lifetime in seconds of an SSL3 session. * The minimum timeout value is 5 seconds and the maximum is 24 hours. * Values outside this range are replaced by the server default value * of 100 seconds. * @param cacheFileDirectory The pathname of the directory that * will contain the session cache. If null is passed, the server default * is used: /tmp on Unix and \\temp on Windows. */ public static native void configServerSessionIDCache(int maxSidEntries, int ssl2EntryTimeout, int ssl3EntryTimeout, String cacheFileDirectory) throws SocketException; /** * Sets the certificate to use for server authentication. */ public void setServerCertNickname(String nick) throws SocketException { try { setServerCert( CryptoManager.getInstance().findCertByNickname(nick) ); } catch(CryptoManager.NotInitializedException nie) { throw new SocketException("CryptoManager not initialized"); } catch(ObjectNotFoundException onfe) { throw new SocketException("Object not found: " + onfe); } catch(TokenException te) { throw new SocketException("Token Exception: " + te); } } /** * Sets the certificate to use for server authentication. */ public native void setServerCert( org.mozilla.jss.crypto.X509Certificate certnickname) throws SocketException; /** * Enables/disables the request of client authentication. This is only * meaningful for the server end of the SSL connection. During the next * handshake, the remote peer will be asked to authenticate itself. * @see org.mozilla.jss.ssl.SSLServerSocket#requireClientAuth */ public void requestClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuth instead. */ public void setNeedClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * Enables/disables the request of client authentication. This is only * meaningful for the server end of the SSL connection. During the next * handshake, the remote peer will be asked to authenticate itself. *

In addition, the client certificate's expiration will not * prevent it from being accepted. * @see org.mozilla.jss.ssl.SSLServerSocket#requireClientAuth public void requestClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuthNoExpiryCheck instead. */ public void setNeedClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * Enables SSL v2 on this socket. It is enabled by default, unless the * default has been changed with SSLSocket.enableSSL2Default. */ public void enableSSL2(boolean enable) throws SocketException { base.enableSSL2(enable); } /** * Enables SSL v3 on this socket. It is enabled by default, unless the * default has been changed with SSLSocket.enableSSL3Default. */ public void enableSSL3(boolean enable) throws SocketException { base.enableSSL3(enable); } /** * Enables TLS on this socket. It is enabled by default, unless the * default has been changed with SSLSocket.enableTLSDefault. */ public void enableTLS(boolean enable) throws SocketException { base.enableTLS(enable); } /** * Enables Session tickets on this socket. It is disabled by default, * unless the default has been changed with * SSLSocket.enableSessionTicketsDefault. */ public void enableSessionTickets(boolean enable) throws SocketException { base.enableSessionTickets(enable); } /** * Enables the mode of renegotiation that the peer must use. * The default is never renegotiate at all unless the default * has been changed with SSLSocket.enableRenegotiationDefault. * * @param mode One of: * SSLSocket.SSL_RENEGOTIATE_NEVER - Never renegotiate at all. * * SSLSocket.SSL_RENEGOTIATE_UNRESTRICTED - Renegotiate without * restriction, whether or not the peer's hello bears the TLS * renegotiation info extension. Vulnerable, as in the past. * * SSLSocket.SSL_RENEGOTIATE_REQUIRES_XTN - Only renegotiate if the * peer's hello bears the TLS renegotiation_info extension. This is * safe renegotiation. * * SSLSocket.SSL_RENEGOTIATE_TRANSITIONAL - Disallow unsafe * renegotiation in server sockets only, but allow clients * to continue to renegotiate with vulnerable servers. * This value should only be used during the transition period * when few servers have been upgraded. */ public void enableRenegotiation(int mode) throws SocketException { if (mode >= SocketBase.SSL_RENEGOTIATE_NEVER && mode <= SocketBase.SSL_RENEGOTIATE_TRANSITIONAL) { base.enableRenegotiation(mode); } else { throw new SocketException("Incorrect input value."); } } /** * For this socket require that the peer must send * Signaling Cipher Suite Value (SCSV) or Renegotiation Info (RI) * extension in ALL handshakes. It is disabled by default, * unless the default has been changed with * SSLSocket.enableRequireSafeNegotiationDefault. */ public void enableRequireSafeNegotiation(boolean enable) throws SocketException { base.enableRequireSafeNegotiation(enable); } /** * Enable rollback detection for this socket. * It is enabled by default, unless the default has been changed * with SSLSocket.enableRollbackDetectionDefault. */ public void enableRollbackDetection(boolean enable) throws SocketException { base.enableRollbackDetection(enable); } /** * This option, enableStepDown, is concerned with the generation * of step-down keys which are used with export suites. * If the server cert's public key is 512 bits or less, * this option is ignored because step-down keys don't * need to be generated. * If the server cert's public key is more than 512 bits, * this option has the following effect: * enable=true: generate step-down keys * enable=false: don't generate step-down keys; disable * export cipher suites * * This option is enabled by default; unless the default has * been changed with SSLSocket.enableStepDownDefault. */ public void enableStepDown(boolean enable) throws SocketException { base.enableStepDown(enable); } /** * Enable simultaneous read/write by separate read and write threads * (full duplex) for this socket. * It is disabled by default, unless the default has been changed * with SSLSocket.enableFDXDefault. */ public void enableFDX(boolean enable) throws SocketException { base.enableFDX(enable); } /** * Enable sending v3 client hello in v2 format for this socket. * It is enabled by default, unless the default has been changed * with SSLSocket.enableV2CompatibleHelloDefault. */ public void enableV2CompatibleHello(boolean enable) throws SocketException { base.enableV2CompatibleHello(enable); } /** * @return a String listing the current SSLOptions for this socket. */ public String getSSLOptions() { return base.getSSLOptions(); } /** * @return the local address of this server socket. */ public InetAddress getInetAddress() { return base.getLocalAddress(); } /** * Sets whether the socket requires client authentication from the remote * peer. If requestClientAuth() has not already been called, this * method will tell the socket to request client auth as well as requiring * it. * @deprecated use requireClientAuth(int) */ public void requireClientAuth(boolean require, boolean onRedo) throws SocketException { base.requireClientAuth(require, onRedo); } /** * Sets whether the socket requires client authentication from the remote * peer. If requestClientAuth() has not already been called, this * method will tell the socket to request client auth as well as requiring * it. * @param mode One of: SSLSocket.SSL_REQUIRE_NEVER, * SSLSocket.SSL_REQUIRE_ALWAYS, * SSLSocket.SSL_REQUIRE_FIRST_HANDSHAKE, * SSLSocket.SSL_REQUIRE_NO_ERROR */ public void requireClientAuth(int mode) throws SocketException { if (mode >= SocketBase.SSL_REQUIRE_NEVER && mode <= SocketBase.SSL_REQUIRE_NO_ERROR) { base.requireClientAuth(mode); } else { throw new SocketException("Incorrect input value."); } } /** * Sets the nickname of the certificate to use for client authentication. */ public void setClientCertNickname(String nick) throws SocketException { base.setClientCertNickname(nick); } /** * Sets the certificate to use for client authentication. */ public void setClientCert(org.mozilla.jss.crypto.X509Certificate cert) throws SocketException { base.setClientCert(cert); } /** * Determines whether this end of the socket is the client or the server * for purposes of the SSL protocol. By default, it is the server. * @param b true if this end of the socket is the SSL slient, false * if it is the SSL server. */ public void setUseClientMode(boolean b) { handshakeAsClient = b; } /** * Enables/disables the session cache. By default, the session cache * is enabled. */ public void useCache(boolean b) throws SocketException { base.useCache(b); } /** * Returns the addresses and ports of this socket * or an error message if the socket is not in a valid state. */ public String toString() { try { InetAddress inetAddr = getInetAddress(); int localPort = getLocalPort(); StringBuffer buf = new StringBuffer(); buf.append("SSLServerSocket[addr="); buf.append(inetAddr); buf.append(",localport="); buf.append(localPort); buf.append("]"); return buf.toString(); } catch (Exception e) { return "Exception caught in toString(): " + e.getMessage(); } } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLSocket.c000066400000000000000000000771441326145000000207400ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include "_jni/org_mozilla_jss_ssl_SSLSocket.h" #include "jssl.h" #ifdef WINNT #include #define AF_INET6 23 #endif #ifdef WIN32 #include #define AF_INET6 23 #endif /* * support TLS v1.1 and v1.2 * sets default SSL version range for sockets created after this call */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSSLVersionRangeDefault(JNIEnv *env, jclass clazz, jint ssl_variant, jint min, jint max) { SECStatus status; SSLVersionRange vrange; SSLVersionRange supported_range; if (ssl_variant <0 || ssl_variant >= JSSL_enums_size|| min <0 || min >= JSSL_enums_size || max <0 || max >= JSSL_enums_size) { char buf[128]; PR_snprintf(buf, 128, "JSS setSSLVersionRangeDefault(): for variant=%d min=%d max=%d failed - out of range for array JSSL_enums size: %d", JSSL_enums[ssl_variant], min, max, JSSL_enums_size); JSSL_throwSSLSocketException(env, buf); goto finish; } vrange.min = JSSL_enums[min]; vrange.max = JSSL_enums[max]; /* get supported range */ status = SSL_VersionRangeGetSupported(JSSL_enums[ssl_variant], &supported_range); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "SSL_VersionRangeGetSupported() for variant=%d failed: %d", JSSL_enums[ssl_variant], PR_GetError()); JSSL_throwSSLSocketException(env, buf); goto finish; } /* now check the min and max */ if (vrange.min < supported_range.min || vrange.max > supported_range.max) { char buf[128]; PR_snprintf(buf, 128, "SSL_VersionRangeSetDefault() for variant=%d with min=%d max=%d out of range (%d:%d): %d", JSSL_enums[ssl_variant], vrange.min, vrange.max, supported_range.min, supported_range.max, PR_GetError()); JSSL_throwSSLSocketException(env, buf); goto finish; } /* set the default SSL Version Range */ status = SSL_VersionRangeSetDefault(JSSL_enums[ssl_variant], &vrange); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "SSL_VersionRangeSetDefault() for variant=%d with min=%d max=%d failed: %d", JSSL_enums[ssl_variant], vrange.min, vrange.max, PR_GetError()); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: return; } /* * support TLS v1.1 and v1.2 * sets SSL version range for this socket */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setSSLVersionRange (JNIEnv *env, jobject self, jint min, jint max) { SECStatus status; JSSL_SocketData *sock = NULL; SSLVersionRange vrange; if ( min <0 || min >= JSSL_enums_size || max <0 || max >= JSSL_enums_size) { char buf[128]; PR_snprintf(buf, 128, "JSS setSSLVersionRange(): for max=%d failed - out of range for array JSSL_enums size: %d", min, max, JSSL_enums_size); JSSL_throwSSLSocketException(env, buf); goto finish; } /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } vrange.min = JSSL_enums[min]; vrange.max = JSSL_enums[max]; /* * set the SSL Version Range * The validity of the range will be checked by this NSS call */ status = SSL_VersionRangeSet(sock->fd, &vrange); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_VersionRangeSet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOption(JNIEnv *env, jclass clazz, jint joption, jint on) { SECStatus status; /* set the option */ status = SSL_OptionSetDefault(JSSL_enums[joption], on); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOptionMode(JNIEnv *env, jclass clazz, jint joption, jint mode) { SECStatus status; /* set the option */ status = SSL_OptionSetDefault(JSSL_enums[joption], JSSL_enums[mode]); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_isFipsCipherSuiteNative(JNIEnv *env, jobject self, jint suite) { SECStatus status; PRBool bOption = PR_FALSE; SSLCipherSuiteInfo info; status = SSL_GetCipherSuiteInfo(suite, &info, sizeof info); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "ciphersuite invalid"); } if (info.isFIPS == 1) bOption = PR_TRUE; return bOption; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getSSLDefaultOption(JNIEnv *env, jobject self, jint joption) { SECStatus status; PRBool bOption; /* get the Default option */ status = SSL_OptionGetDefault(JSSL_enums[joption], &bOption); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionGetDefault failed"); } return bOption; } #if 0 #define EXCEPTION_CHECK(env, sock) \ if( sock != NULL && sock->jsockPriv!=NULL) { \ JSS_SSL_processExceptions(env, sock->jsockPriv); \ } #endif JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_forceHandshake(JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; int rv; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) goto finish; /* do the work */ rv = SSL_ForceHandshake(sock->fd); if( rv != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_ForceHandshake failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } /* * linger * The linger time, in seconds. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSoLinger(JNIEnv *env, jobject self, jboolean on, jint linger) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Linger; sockOptions.value.linger.polarity = on; if(on) { sockOptions.value.linger.linger = PR_SecondsToInterval(linger); } status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getTcpNoDelay(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_NoDelay; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.no_delay; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setTcpNoDelay(JNIEnv *env, jobject self, jboolean on) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_NoDelay; sockOptions.value.no_delay = on; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getSendBufferSize(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_SendBufferSize; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.send_buffer_size; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setSendBufferSize(JNIEnv *env, jobject self, jint size) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_SendBufferSize; sockOptions.value.send_buffer_size = size; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getKeepAlive(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Keepalive; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.keep_alive; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getReceiveBufferSize( JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_RecvBufferSize; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return sockOptions.value.recv_buffer_size; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setReceiveBufferSize( JNIEnv *env, jobject self, jint size) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_RecvBufferSize; sockOptions.value.recv_buffer_size = size; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setKeepAlive(JNIEnv *env, jobject self, jboolean on) { PRSocketOptionData sockOptions; PRStatus status; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Keepalive; sockOptions.value.keep_alive = on; status = PR_SetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_SetSocketOption failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getSoLinger(JNIEnv *env, jobject self) { PRSocketOptionData sockOptions; JSSL_SocketData *sock = NULL; jint retval=-1; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } sockOptions.option = PR_SockOpt_Linger; status = PR_GetSocketOption(sock->fd, &sockOptions); if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSocketOption failed"); goto finish; } if( sockOptions.value.linger.polarity == PR_TRUE ) { retval = PR_IntervalToSeconds(sockOptions.value.linger.linger); } else { retval = -1; } finish: EXCEPTION_CHECK(env, sock) return retval; } /* * This function is only here for binary compatibility. See * http://bugzilla.mozilla.org/show_bug.cgi?id=143254 */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getLocalAddressNative(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) == PR_SUCCESS ) { return ntohl(addr.inet.ip); } else { return 0; } } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getPort(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, PEER_SOCK) == PR_SUCCESS ) { return ntohs(addr.inet.port); } else { return 0; } } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketConnect (JNIEnv *env, jobject self, jbyteArray addrBA, jstring hostname, jint port) { JSSL_SocketData *sock; PRNetAddr addr; jbyte *addrBAelems = NULL; int addrBALen = 0; PRStatus status; int stat; const char *hostnameStr=NULL; jmethodID supportsIPV6ID; jclass socketBaseClass; jboolean supportsIPV6 = 0; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* * setup the PRNetAddr structure */ socketBaseClass = (*env)->FindClass(env, SOCKET_BASE_NAME); if( socketBaseClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6ID = (*env)->GetStaticMethodID(env, socketBaseClass, SUPPORTS_IPV6_NAME, SUPPORTS_IPV6_SIG); if( supportsIPV6ID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6 = (*env)->CallStaticBooleanMethod(env, socketBaseClass, supportsIPV6ID); addrBAelems = (*env)->GetByteArrayElements(env, addrBA, NULL); addrBALen = (*env)->GetArrayLength(env, addrBA); PR_ASSERT(addrBALen != 0); if( addrBAelems == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* * Tell SSL the URL we think we want to connect to. * This prevents man-in-the-middle attacks. */ hostnameStr = (*env)->GetStringUTFChars(env, hostname, NULL); if( hostnameStr == NULL ) goto finish; stat = SSL_SetURL(sock->fd, (char*)hostnameStr); if( stat != 0 ) { JSSL_throwSSLSocketException(env, "Failed to set the SSL URL"); goto finish; } if(addrBALen != 4 && addrBALen != 16) { JSSL_throwSSLSocketException(env, "Invalid address in connect!"); goto finish; } if( addrBALen == 4) { addr.inet.family = AF_INET; addr.inet.port = PR_htons(port); memcpy(&addr.inet.ip, addrBAelems, 4); if(supportsIPV6) { addr.ipv6.family = AF_INET6; addr.ipv6.port = PR_htons(port); PR_ConvertIPv4AddrToIPv6(addr.inet.ip,&addr.ipv6.ip); } } else { /* Must be 16 and ipv6 */ if(supportsIPV6) { addr.ipv6.family = AF_INET6; addr.ipv6.port = PR_htons(port); memcpy(&addr.ipv6.ip,addrBAelems, 16); } else { JSSL_throwSSLSocketException(env, "Invalid address in connect!"); goto finish; } } /* * make the connect call */ status = PR_Connect(sock->fd, &addr, PR_INTERVAL_NO_TIMEOUT); if( status != PR_SUCCESS) { JSSL_throwSSLSocketException(env, "Unable to connect"); goto finish; } finish: /* This method should never be called on a Java socket wrapper. */ PR_ASSERT( sock==NULL || sock->jsockPriv==NULL); if( hostnameStr != NULL ) { (*env)->ReleaseStringUTFChars(env, hostname, hostnameStr); } if( addrBAelems != NULL ) { (*env)->ReleaseByteArrayElements(env, addrBA, addrBAelems, JNI_ABORT); } } JNIEXPORT jobject JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getStatus (JNIEnv *env, jobject self) { SECStatus secstatus; JSSL_SocketData *sock=NULL; int on; char *cipher=NULL; jobject cipherString; jint keySize; jint secretKeySize; char *issuer=NULL; jobject issuerString; char *subject=NULL; jobject subjectString; jobject statusObj = NULL; jclass statusClass; jmethodID statusCons; CERTCertificate *peerCert=NULL; jobject peerCertObj = NULL; char *serialNum = NULL; jobject serialNumObj = NULL; /* get the fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* get the status */ secstatus = SSL_SecurityStatus( sock->fd, &on, &cipher, (int*)&keySize, (int*)&secretKeySize, &issuer, &subject); if(secstatus != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to retrieve socket security status"); goto finish; } /* * get the peer certificate */ peerCert = SSL_PeerCertificate(sock->fd); if( peerCert != NULL ) { /* the peer cert might be null, for example if this is the server * side and the client didn't auth. */ serialNum = CERT_Hexify(&peerCert->serialNumber, PR_FALSE /*do_colon*/); PR_ASSERT(serialNum != NULL); serialNumObj = (*env)->NewStringUTF(env, serialNum); if( serialNumObj == NULL ) { goto finish; } /* this call will wipe out peerCert */ peerCertObj = JSS_PK11_wrapCert(env, &peerCert); if( peerCertObj == NULL) { goto finish; } } /* * convert char*s to Java Strings */ cipherString = issuerString = subjectString = NULL; if( cipher != NULL ) cipherString = (*env)->NewStringUTF(env, cipher); if( issuer != NULL ) issuerString = (*env)->NewStringUTF(env, issuer); if( subject != NULL ) subjectString = (*env)->NewStringUTF(env, subject); /* * package the status into a new SSLSecurityStatus object */ statusClass = (*env)->FindClass(env, SSL_SECURITY_STATUS_CLASS_NAME); PR_ASSERT(statusClass != NULL); if( statusClass == NULL ) { /* exception was thrown */ goto finish; } statusCons = (*env)->GetMethodID(env, statusClass, SSL_SECURITY_STATUS_CONSTRUCTOR_NAME, SSL_SECURITY_STATUS_CONSTRUCTOR_SIG); PR_ASSERT(statusCons != NULL); if(statusCons == NULL ) { /* exception was thrown */ goto finish; } statusObj = (*env)->NewObject(env, statusClass, statusCons, on, cipherString, keySize, secretKeySize, issuerString, subjectString, serialNumObj, peerCertObj); finish: if( cipher != NULL ) { PR_Free(cipher); } if( issuer != NULL ) { PORT_Free(issuer); } if ( subject != NULL) { PORT_Free(subject); } if( peerCert != NULL ) { CERT_DestroyCertificate(peerCert); } if( serialNum != NULL ) { PR_Free(serialNum); } EXCEPTION_CHECK(env, sock) return statusObj; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreference( JNIEnv *env, jobject sockObj, jint cipher, jboolean enable) { JSSL_SocketData *sock=NULL; SECStatus status; /* get the fd */ if( JSSL_getSockData(env, sockObj, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } status = SSL_CipherPrefSet(sock->fd, cipher, enable); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "Failed to %s cipher 0x%lx\n", (enable ? "enable" : "disable"), cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: EXCEPTION_CHECK(env, sock); } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreference( JNIEnv *env, jobject sockObj, jint cipher) { JSSL_SocketData *sock=NULL; SECStatus status; PRBool enabled = PR_FAILURE; /* get the fd */ if( JSSL_getSockData(env, sockObj, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } status = SSL_CipherPrefGet(sock->fd, cipher, &enabled); if( status != SECSuccess ) { char buf[128]; PR_snprintf(buf, 128, "Failed to get preference for cipher 0x%lx\n", cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: EXCEPTION_CHECK(env, sock); return enabled; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreferenceDefault( JNIEnv *env, jclass clazz, jint cipher, jboolean enable) { SECStatus status; /* set the preference */ status = SSL_CipherPrefSetDefault(cipher, enable); if(status != SECSuccess) { char buf[128]; PR_snprintf(buf, 128, "Failed to %s cipher 0x%lx\n", (enable ? "enable" : "disable"), cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: return; } JNIEXPORT jboolean JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreferenceDefault( JNIEnv *env, jclass clazz, jint cipher) { SECStatus status; PRBool enabled; /* get the preference */ status = SSL_CipherPrefGetDefault(cipher, &enabled); if(status != SECSuccess) { char buf[128]; PR_snprintf(buf, 128, "Failed to get default preference for " "cipher 0x%lx\n", cipher); JSSL_throwSSLSocketException(env, buf); goto finish; } finish: return enabled; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketRead(JNIEnv *env, jobject self, jbyteArray bufBA, jint off, jint len, jint timeout) { JSSL_SocketData *sock = NULL; jbyte *buf = NULL; jint size; PRIntervalTime ivtimeout; PRThread *me; jint nread = -1; size = (*env)->GetArrayLength(env, bufBA); if( off < 0 || len < 0 || (off+len) > size) { JSS_throw(env, INDEX_OUT_OF_BOUNDS_EXCEPTION); goto finish; } buf = (*env)->GetByteArrayElements(env, bufBA, NULL); if( buf == NULL ) { goto finish; } ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout) : PR_INTERVAL_NO_TIMEOUT; /* get the socket */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the current thread doing the read */ me = PR_GetCurrentThread(); PR_Lock(sock->lock); if ( sock->closePending ) { PR_Unlock(sock->lock); JSSL_throwSSLSocketException(env, "Read operation interrupted"); goto finish; } PR_ASSERT(sock->reader == NULL); sock->reader = me; PR_Unlock(sock->lock); nread = PR_Recv(sock->fd, buf+off, len, 0 /*flags*/, ivtimeout); PR_Lock(sock->lock); PR_ASSERT(sock->reader == me); sock->reader = NULL; PR_Unlock(sock->lock); if( nread < 0 ) { PRErrorCode err = PR_GetError(); if( err == PR_PENDING_INTERRUPT_ERROR ) { #ifdef WINNT /* Clean up after PR_interrupt called by abortReadWrite. */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Read operation interrupted"); } else if( err == PR_IO_TIMEOUT_ERROR ) { #ifdef WINNT /* * if timeout was set, and the PR_Recv timed out, * then cancel the I/O on the socket, otherwise PR_Recv() * will always return PR_IO_PENDING_ERROR on subsequent * calls */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Operation timed out"); } else { JSSL_throwSSLSocketException(env, "Error reading from socket"); } goto finish; } if( nread == 0 ) { /* EOF in Java is -1 */ nread = -1; } finish: EXCEPTION_CHECK(env, sock) (*env)->ReleaseByteArrayElements(env, bufBA, buf, (nread>0) ? 0 /*copy and free*/ : JNI_ABORT /*free, no copy*/); return nread; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketAvailable( JNIEnv *env, jobject self) { jint available=0; JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } available = SSL_DataPending(sock->fd); PR_ASSERT(available >= 0); finish: EXCEPTION_CHECK(env, sock) return available; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_socketWrite(JNIEnv *env, jobject self, jbyteArray bufBA, jint off, jint len, jint timeout) { JSSL_SocketData *sock = NULL; jbyte *buf = NULL; jint size; PRIntervalTime ivtimeout; PRThread *me; PRInt32 numwrit; if( bufBA == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } size = (*env)->GetArrayLength(env, bufBA); if( off < 0 || len < 0 || (off+len) > size ) { JSS_throw(env, INDEX_OUT_OF_BOUNDS_EXCEPTION); goto finish; } buf = (*env)->GetByteArrayElements(env, bufBA, NULL); if( buf == NULL ) { goto finish; } ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout) : PR_INTERVAL_NO_TIMEOUT; /* get the socket */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the current thread doing the write */ me = PR_GetCurrentThread(); PR_Lock(sock->lock); if ( sock->closePending ) { PR_Unlock(sock->lock); JSSL_throwSSLSocketException(env, "Write operation interrupted"); goto finish; } PR_ASSERT(sock->writer == NULL); sock->writer = me; PR_Unlock(sock->lock); numwrit = PR_Send(sock->fd, buf+off, len, 0 /*flags*/, ivtimeout); PR_Lock(sock->lock); PR_ASSERT(sock->writer == me); sock->writer = NULL; PR_Unlock(sock->lock); if( numwrit < 0 ) { PRErrorCode err = PR_GetError(); if( err == PR_PENDING_INTERRUPT_ERROR ) { #ifdef WINNT /* clean up after PR_Interrupt called by abortReadWrite. */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Write operation interrupted"); } else if( err == PR_IO_TIMEOUT_ERROR ) { #ifdef WINNT /* * if timeout was set, and the PR_Send() timed out, * then cancel the I/O on the socket, otherwise PR_Send() * will always return PR_IO_PENDING_ERROR on subsequent * calls */ PR_NT_CancelIo(sock->fd); #endif JSSL_throwSSLSocketException(env, "Operation timed out"); } else { JSSL_throwSSLSocketException(env, "Failed to write to socket"); } goto finish; } /* PR_Send is supposed to block until it sends everything */ PR_ASSERT(numwrit == len); finish: if( buf != NULL ) { (*env)->ReleaseByteArrayElements(env, bufBA, buf, JNI_ABORT); } EXCEPTION_CHECK(env, sock) } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_abortReadWrite( JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) goto finish; /* * The java layer prevents I/O once close has been * called but if an I/O operation is in progress then abort it. * For WINNT the read and write methods must check for the * PR_PENDING_INTERRUPT_ERROR and call PR_NT_CancelIo. */ PR_Lock(sock->lock); if ( sock->reader ) { PR_Interrupt(sock->reader); } if ( sock->writer ) { PR_Interrupt(sock->writer); } sock->closePending = PR_TRUE; /* socket is to be closed */ PR_Unlock(sock->lock); finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_shutdownNative( JNIEnv *env, jobject self, jint how) { JSSL_SocketData *sock = NULL; PRStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = PR_Shutdown(sock->fd, JSSL_enums[how]); if( status != PR_SUCCESS) { JSSL_throwSSLSocketException(env, "Failed to shutdown socket"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_invalidateSession(JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = SSL_InvalidateSession(sock->fd); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to invalidate session"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_redoHandshake( JNIEnv *env, jobject self, jboolean flushCache) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = SSL_ReHandshake(sock->fd, flushCache); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to redo handshake"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_resetHandshakeNative( JNIEnv *env, jobject self, jboolean asClient) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; status = SSL_ResetHandshake(sock->fd, !asClient); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to redo handshake"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SSLSocket_setCipherPolicyNative( JNIEnv *env, jobject self, jint policyEnum) { SECStatus status; switch(policyEnum) { case SSL_POLICY_DOMESTIC: status = NSS_SetDomesticPolicy(); break; case SSL_POLICY_EXPORT: status = NSS_SetExportPolicy(); break; case SSL_POLICY_FRANCE: status = NSS_SetFrancePolicy(); break; default: PR_ASSERT(PR_FALSE); status = SECFailure; } if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Failed to set cipher policy"); goto finish; } finish: return; } JNIEXPORT jintArray JNICALL Java_org_mozilla_jss_ssl_SSLSocket_getImplementedCipherSuites (JNIEnv *env, jclass clazz) { jintArray ciphArray = NULL; jint* arrayRegion = NULL; int i; ciphArray = (*env)->NewIntArray(env, SSL_NumImplementedCiphers); if( ciphArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } arrayRegion = (*env)->GetIntArrayElements(env, ciphArray, NULL/*isCopy*/); if( arrayRegion == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } for( i=0; i < SSL_NumImplementedCiphers; ++i) { arrayRegion[i] = SSL_ImplementedCiphers[i]; } finish: if( arrayRegion != NULL ) { (*env)->ReleaseIntArrayElements(env, ciphArray, arrayRegion, 0); } return ciphArray; } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLSocket.java000066400000000000000000001673531326145000000214410ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.InetAddress; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; /** * SSL client socket. */ public class SSLSocket extends java.net.Socket { /** * * Note the following cipher-suites constants are not all implemented. * You need to call getImplementedCiphersuites. * */ public final static int SSL2_RC4_128_WITH_MD5 = 0xFF01; public final static int SSL2_RC4_128_EXPORT40_WITH_MD5 = 0xFF02; public final static int SSL2_RC2_128_CBC_WITH_MD5 = 0xFF03; public final static int SSL2_RC2_128_CBC_EXPORT40_WITH_MD5 = 0xFF04; public final static int SSL2_IDEA_128_CBC_WITH_MD5 = 0xFF05; public final static int SSL2_DES_64_CBC_WITH_MD5 = 0xFF06; public final static int SSL2_DES_192_EDE3_CBC_WITH_MD5 = 0xFF07; /** * @deprecated Replaced with TLS_RSA_WITH_NULL_MD5. */ @Deprecated public final static int SSL3_RSA_WITH_NULL_MD5 = 0x0001; public final static int TLS_RSA_WITH_NULL_MD5 = 0x0001; /** * @deprecated Replaced with TLS_RSA_WITH_NULL_SHA. */ @Deprecated public final static int SSL3_RSA_WITH_NULL_SHA = 0x0002; public final static int TLS_RSA_WITH_NULL_SHA = 0x0002; public final static int SSL3_RSA_EXPORT_WITH_RC4_40_MD5 = 0x0003; /** * @deprecated Replaced with TLS_RSA_WITH_RC4_128_MD5. */ @Deprecated public final static int SSL3_RSA_WITH_RC4_128_MD5 = 0x0004; public final static int TLS_RSA_WITH_RC4_128_MD5 = 0x0004; /** * @deprecated Replaced with TLS_RSA_WITH_RC4_128_SHA. */ @Deprecated public final static int SSL3_RSA_WITH_RC4_128_SHA = 0x0005; public final static int TLS_RSA_WITH_RC4_128_SHA = 0x0005; public final static int SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = 0x0006; /** * @deprecated Replaced with TLS_RSA_WITH_IDEA_CBC_SHA. */ @Deprecated public final static int SSL3_RSA_WITH_IDEA_CBC_SHA = 0x0007; public final static int TLS_RSA_WITH_IDEA_CBC_SHA = 0x0007; public final static int SSL3_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0008; /** * @deprecated Replaced with TLS_RSA_WITH_DES_CBC_SHA. */ @Deprecated public final static int SSL3_RSA_WITH_DES_CBC_SHA = 0x0009; public final static int TLS_RSA_WITH_DES_CBC_SHA = 0x0009; /** * @deprecated Replaced with TLS_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated public final static int SSL3_RSA_WITH_3DES_EDE_CBC_SHA = 0x000a; public final static int TLS_RSA_WITH_3DES_EDE_CBC_SHA = 0x000a; public final static int SSL3_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x000b; /** * @deprecated Replaced with TLS_DH_DSS_WITH_DES_CBC_SHA. */ @Deprecated public final static int SSL3_DH_DSS_WITH_DES_CBC_SHA = 0x000c; public final static int TLS_DH_DSS_WITH_DES_CBC_SHA = 0x000c; /** * @deprecated Replaced with TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA. */ @Deprecated public final static int SSL3_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000d; public final static int TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000d; public final static int SSL3_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x000e; /** * @deprecated Replaced with TLS_DH_RSA_WITH_DES_CBC_SHA. */ @Deprecated public final static int SSL3_DH_RSA_WITH_DES_CBC_SHA = 0x000f; public final static int TLS_DH_RSA_WITH_DES_CBC_SHA = 0x000f; /** * @deprecated Replaced with TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated public final static int SSL3_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; public final static int TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010; public final static int SSL3_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = 0x0011; /** * @deprecated Replaced with TLS_DHE_DSS_WITH_DES_CBC_SHA. */ @Deprecated public final static int SSL3_DHE_DSS_WITH_DES_CBC_SHA = 0x0012; public final static int TLS_DHE_DSS_WITH_DES_CBC_SHA = 0x0012; /** * @deprecated Replaced with TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA. */ @Deprecated public final static int SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; public final static int TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013; public final static int SSL3_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = 0x0014; /** * @deprecated Replaced with TLS_DHE_RSA_WITH_DES_CBC_SHA. */ @Deprecated public final static int SSL3_DHE_RSA_WITH_DES_CBC_SHA = 0x0015; public final static int TLS_DHE_RSA_WITH_DES_CBC_SHA = 0x0015; /** * @deprecated Replaced with TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA. */ @Deprecated public final static int SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; public final static int TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016; public final static int SSL3_DH_ANON_EXPORT_WITH_RC4_40_MD5 = 0x0017; /** * @deprecated Replaced with TLS_DH_anon_WITH_RC4_128_MD5. */ @Deprecated public final static int SSL3_DH_ANON_WITH_RC4_128_MD5 = 0x0018; public final static int TLS_DH_anon_WITH_RC4_128_MD5 = 0x0018; public final static int SSL3_DH_ANON_EXPORT_WITH_DES40_CBC_SHA = 0x0019; /** * @deprecated Replaced with TLS_DH_anon_WITH_DES_CBC_SHA. */ @Deprecated public final static int SSL3_DH_ANON_WITH_DES_CBC_SHA = 0x001a; public final static int TLS_DH_anon_WITH_DES_CBC_SHA = 0x001a; /** * @deprecated Replaced with TLS_DH_anon_WITH_3DES_EDE_CBC_SHA. */ @Deprecated public final static int SSL3_DH_ANON_WITH_3DES_EDE_CBC_SHA = 0x001b; public final static int TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001b; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated public final static int SSL3_FORTEZZA_DMS_WITH_NULL_SHA = 0x001c; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated public final static int SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA = 0x001d; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. */ @Deprecated public final static int SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA = 0x001e; public final static int SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA = 0xfeff; public final static int SSL_RSA_FIPS_WITH_DES_CBC_SHA = 0xfefe; public final static int TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA = 0x0062; public final static int TLS_RSA_EXPORT1024_WITH_RC4_56_SHA = 0x0064; public final static int TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA = 0x0063; public final static int TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA = 0x0065; public final static int TLS_DHE_DSS_WITH_RC4_128_SHA = 0x0066; public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067; public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B; // New TLS cipher suites in NSS 3.4 public final static int TLS_RSA_WITH_AES_128_CBC_SHA = 0x002F; public final static int TLS_DH_DSS_WITH_AES_128_CBC_SHA = 0x0030; public final static int TLS_DH_RSA_WITH_AES_128_CBC_SHA = 0x0031; public final static int TLS_DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032; public final static int TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033; /** * @deprecated Replaced with TLS_DH_anon_WITH_AES_128_CBC_SHA. */ @Deprecated public final static int TLS_DH_ANON_WITH_AES_128_CBC_SHA = 0x0034; public final static int TLS_DH_anon_WITH_AES_128_CBC_SHA = 0x0034; public final static int TLS_RSA_WITH_AES_256_CBC_SHA = 0x0035; public final static int TLS_DH_DSS_WITH_AES_256_CBC_SHA = 0x0036; public final static int TLS_DH_RSA_WITH_AES_256_CBC_SHA = 0x0037; public final static int TLS_DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038; public final static int TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039; /** * @deprecated Replaced with TLS_DH_anon_WITH_AES_256_CBC_SHA. */ @Deprecated public final static int TLS_DH_ANON_WITH_AES_256_CBC_SHA = 0x003A; public final static int TLS_DH_anon_WITH_AES_256_CBC_SHA = 0x003A; public final static int TLS_RSA_WITH_NULL_SHA256 = 0x003B; public final static int TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x003C; public final static int TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x003D; public final static int TLS_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0041; public final static int TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0042; public final static int TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0043; public final static int TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA = 0x0044; public final static int TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA = 0x0045; /** * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA. */ @Deprecated public final static int TLS_DH_ANON_WITH_CAMELLIA_128_CBC_SHA = 0x0046; public final static int TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA = 0x0046; public final static int TLS_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0084; public final static int TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0085; public final static int TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0086; public final static int TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA = 0x0087; public final static int TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA = 0x0088; /** * @deprecated Replaced with TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA. */ @Deprecated public final static int TLS_DH_ANON_WITH_CAMELLIA_256_CBC_SHA = 0x0089; public final static int TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA = 0x0089; public final static int TLS_RSA_WITH_SEED_CBC_SHA = 0x0096; public final static int TLS_RSA_WITH_AES_128_GCM_SHA256 = 0x009C; public final static int TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E; public final static int TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2; public final static int TLS_ECDH_ECDSA_WITH_NULL_SHA = 0xc001; public final static int TLS_ECDH_ECDSA_WITH_RC4_128_SHA = 0xc002; public final static int TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xc003; public final static int TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xc004; public final static int TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xc005; public final static int TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0xc006; public final static int TLS_ECDHE_ECDSA_WITH_RC4_128_SHA = 0xc007; public final static int TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xc008; public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xc009; public final static int TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xc00a; public final static int TLS_ECDH_RSA_WITH_NULL_SHA = 0xc00b; public final static int TLS_ECDH_RSA_WITH_RC4_128_SHA = 0xc00c; public final static int TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xc00d; public final static int TLS_ECDH_RSA_WITH_AES_128_CBC_SHA = 0xc00e; public final static int TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0xc00f; public final static int TLS_ECDHE_RSA_WITH_NULL_SHA = 0xc010; public final static int TLS_ECDHE_RSA_WITH_RC4_128_SHA = 0xc011; public final static int TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xc012; public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xc013; public final static int TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xc014; public final static int TLS_ECDH_anon_WITH_NULL_SHA = 0xc015; public final static int TLS_ECDH_anon_WITH_RC4_128_SHA = 0xc016; public final static int TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xc017; public final static int TLS_ECDH_anon_WITH_AES_128_CBC_SHA = 0xc018; public final static int TLS_ECDH_anon_WITH_AES_256_CBC_SHA = 0xc019; public final static int TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xc023; public final static int TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xc027; public final static int TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xc02B; public final static int TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xc02D; public final static int TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xc02F; public final static int TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xc031; /* * Locking strategy of SSLSocket * * isClosed, inRead, and inWrite must be accessed with the object * locked. * * readLock must be locked throughout the read method. It is used * to serialize read calls. * * writeLock must be locked throughout the write method. It is used * to serialize write calls. */ private java.lang.Object readLock = new java.lang.Object(); private java.lang.Object writeLock = new java.lang.Object(); private boolean isClosed = false; private boolean inRead = false; private boolean inWrite = false; private InetAddress inetAddress; private int port; private SocketProxy sockProxy = null; private boolean open = false; private boolean handshakeAsClient = true; private SocketBase base = new SocketBase(); static final public int SSL_REQUIRE_NEVER = org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_NEVER; static final public int SSL_REQUIRE_ALWAYS = org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_ALWAYS; static final public int SSL_REQUIRE_FIRST_HANDSHAKE = org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_FIRST_HANDSHAKE; static final public int SSL_REQUIRE_NO_ERROR = org.mozilla.jss.ssl.SocketBase.SSL_REQUIRE_NO_ERROR; static final public int SSL_RENEGOTIATE_NEVER = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_NEVER; static final public int SSL_RENEGOTIATE_REQUIRES_XTN = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_REQUIRES_XTN; static final public int SSL_RENEGOTIATE_UNRESTRICTED = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_UNRESTRICTED; static final public int SSL_RENEGOTIATE_TRANSITIONAL = org.mozilla.jss.ssl.SocketBase.SSL_RENEGOTIATE_TRANSITIONAL; private Collection socketListeners = new ArrayList<>(); private Collection handshakeCompletedListeners = new ArrayList<>(); /** * For sockets that get created by accept(). */ SSLSocket() throws IOException { } /** * Should only be called by SSLServerSocket after a successful * accept(). */ void setSockProxy(SocketProxy sp) { sockProxy = sp; base.setProxy(sp); } /** * Creates an SSL client socket and connects to the specified host and * port. * * @param host The hostname to connect to. * @param port The port to connect to. */ public SSLSocket(String host, int port) throws UnknownHostException, IOException { this(InetAddress.getByName(host), port, null, 0); } /** * Creates an SSL client socket and connects to the specified address and * port. * * @param address The IP address to connect to. * @param port The port to connect to. */ public SSLSocket(InetAddress address, int port) throws IOException { this(address, port, null, 0); } /** * Creates an SSL client socket and connects to the specified host and * port. Binds to the given local address and port. * * @param host The hostname to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. */ public SSLSocket(String host, int port, InetAddress localAddr, int localPort) throws IOException { this(InetAddress.getByName(host), port, localAddr, localPort); } /** * Creates an SSL client socket and connects to the specified address and * port. Binds to the given local address and port. * * @param address The IP address to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. */ public SSLSocket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException { this(address, port, localAddr, localPort, null, null); } /** * Creates an SSL client socket and connects to the specified host and * port. Binds to the given local address and port. Installs the given * callbacks for certificate approval and client certificate selection. * * @param host The hostname to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. */ public SSLSocket(String host, int port, InetAddress localAddr, int localPort, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { this(InetAddress.getByName(host), port, localAddr, localPort, certApprovalCallback, clientCertSelectionCallback); } /** * Creates an SSL client socket and connects to the specified address and * port. Binds to the given local address and port. Installs the given * callbacks for certificate approval and client certificate selection. * * @param address The IP address to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. * @param stream This parameter is ignored. All SSLSockets are stream * sockets. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. * @deprecated As of JSS 3.0. The stream parameter is ignored, because * only stream sockets are supported. */ public SSLSocket(InetAddress address, int port, InetAddress localAddr, int localPort, boolean stream, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { this(address, port, localAddr, localPort, certApprovalCallback, clientCertSelectionCallback); } /** * Creates an SSL client socket and connects to the specified address and * port. Binds to the given local address and port. Installs the given * callbacks for certificate approval and client certificate selection. * * @param address The IP address to connect to. * @param port The port to connect to. * @param localAddr The local address to bind to. It can be null, in which * case an unspecified local address will be chosen. * @param localPort The local port to bind to. If 0, a random port will be * assigned to the socket. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. */ public SSLSocket(InetAddress address, int port, InetAddress localAddr, int localPort, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { this(address, address.getHostName(), port, localAddr, localPort, certApprovalCallback, clientCertSelectionCallback); } private SSLSocket(InetAddress address, String hostname, int port, InetAddress localAddr, int localPort, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { int socketFamily = SocketBase.SSL_AF_INET; if(SocketBase.supportsIPV6()) { socketFamily = SocketBase.SSL_AF_INET6; } // create the socket sockProxy = new SocketProxy( base.socketCreate( this, certApprovalCallback, clientCertSelectionCallback,socketFamily) ); base.setProxy(sockProxy); // bind it to local address and port if( localAddr != null || localPort > 0 ) { // bind because they specified a local address byte[] addrBA = null; if( localAddr != null ) { addrBA = localAddr.getAddress(); } base.socketBind(addrBA, localPort); } /* connect to the remote socket */ socketConnect(address.getAddress(), hostname, port); } /** * Creates an SSL client socket using the given Java socket for underlying * I/O. Installs the given callbacks for certificate approval and * client certificate selection. * * @param s The Java socket to use for underlying I/O. * @param host The hostname of the remote side of the connection. * This name is used to verify the server's certificate. * @param certApprovalCallback A callback that can be used to override * approval of the peer's certificate. * @param clientCertSelectionCallback A callback to select the client * certificate to present to the peer. */ public SSLSocket(java.net.Socket s, String host, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback) throws IOException { // create the socket sockProxy = new SocketProxy( base.socketCreate( this, certApprovalCallback, clientCertSelectionCallback, s, host,SocketBase.SSL_AF_INET ) ); base.setProxy(sockProxy); resetHandshake(); } /** * @return The remote peer's IP address or null if the SSLSocket is closed. */ public InetAddress getInetAddress() { synchronized (this) { if( isClosed ) { return null; } else return base.getInetAddress(); } } /** * @return The local IP address or null if the SSLSocket is closed. */ public InetAddress getLocalAddress() { synchronized (this) { if( isClosed ) { return null; } else return base.getLocalAddress(); } } /** * @return The local port or -1 if the SSLSocket is closed. */ public int getLocalPort() { synchronized (this) { if( isClosed ) { return -1; } else return base.getLocalPort(); } } /** * @return The remote port. */ public native int getPort(); /** * Returns the input stream for reading from this socket. */ public InputStream getInputStream() throws IOException { return new SSLInputStream(this); } /** * Returns the output stream for writing to this socket. */ public OutputStream getOutputStream() throws IOException { return new SSLOutputStream(this); } /** * Enables or disables the TCP_NO_DELAY socket option. Enabling this * option will disable the Nagle algorithm. */ public native void setTcpNoDelay(boolean on) throws SocketException; /** * Returns the current setting of the TCP_NO_DELAY socket option. */ public native boolean getTcpNoDelay() throws SocketException; /** * Enables or disables the SO_KEEPALIVE socket option. */ public native void setKeepAlive(boolean on) throws SocketException; /** * Returns the current setting of the SO_KEEPALIVE socket option. */ public native boolean getKeepAlive() throws SocketException; /** * Shuts down the input side of the socket. */ public void shutdownInput() throws IOException { shutdownNative(SocketBase.PR_SHUTDOWN_RCV); } /** * Shuts down the output side of the socket. */ public void shutdownOutput() throws IOException { shutdownNative(SocketBase.PR_SHUTDOWN_SEND); } private native void shutdownNative(int how) throws IOException; private native void abortReadWrite() throws IOException; /** * Sets the SO_LINGER socket option. * param linger The time (in seconds) to linger for. */ public native void setSoLinger(boolean on, int linger) throws SocketException; /** * Returns the current value of the SO_LINGER socket option. */ public native int getSoLinger() throws SocketException; /** * Sets the SO_TIMEOUT socket option. * @param timeout The timeout time in milliseconds. */ public void setSoTimeout(int timeout) throws SocketException { base.setTimeout(timeout); } /** * Returns the current value of the SO_TIMEOUT socket option. * @return The timeout time in milliseconds. */ public int getSoTimeout() throws SocketException { return base.getTimeout(); } /** * Sets the size (in bytes) of the send buffer. */ public native void setSendBufferSize(int size) throws SocketException; /** * Returns the size (in bytes) of the send buffer. */ public native int getSendBufferSize() throws SocketException; /** * Sets the size (in bytes) of the receive buffer. */ public native void setReceiveBufferSize(int size) throws SocketException; /** * Returnst he size (in bytes) of the receive buffer. */ public native int getReceiveBufferSize() throws SocketException; /** * Closes this socket. */ public void close() throws IOException { synchronized (this) { if( isClosed ) { /* finalize calls close or user calls close more than once */ return; } isClosed = true; if( sockProxy == null ) { /* nothing to do */ return; } /* * If a read or write is occurring, abort the I/O. Any * further attempts to read/write will fail since isClosed * is true */ if ( inRead || inWrite ) { abortReadWrite(); } } /* * Lock readLock and writeLock to ensure that read and write * have been aborted. */ synchronized (readLock) { synchronized (writeLock) { base.close(); sockProxy = null; base.setProxy(null); } } } private native void socketConnect(byte[] addr, String hostname, int port) throws SocketException; //////////////////////////////////////////////////////////////////// // SSL-specific stuff //////////////////////////////////////////////////////////////////// public void addSocketListener(SSLSocketListener listener) { socketListeners.add(listener); addHandshakeCompletedListener(listener); } public void removeSocketListener(SSLSocketListener listener) { socketListeners.remove(listener); removeHandshakeCompletedListener(listener); } private void fireAlertReceivedEvent(SSLAlertEvent event) { for (SSLSocketListener listener : socketListeners) { listener.alertReceived(event); } } private void fireAlertSentEvent(SSLAlertEvent event) { for (SSLSocketListener listener : socketListeners) { listener.alertSent(event); } } /** * Adds a listener to be notified when an SSL handshake completes. */ public void addHandshakeCompletedListener(SSLHandshakeCompletedListener listener) { handshakeCompletedListeners.add(listener); } /** * Removes a previously registered listener for handshake completion. */ public void removeHandshakeCompletedListener(SSLHandshakeCompletedListener listener) { handshakeCompletedListeners.remove(listener); } private void notifyAllHandshakeListeners() { SSLHandshakeCompletedEvent event = new SSLHandshakeCompletedEvent(this); for (SSLHandshakeCompletedListener listener : handshakeCompletedListeners) { listener.handshakeCompleted(event); } } /** * Enables SSL v2 on this socket. It is enabled by default, unless the * default has been changed with enableSSL2Default. */ public void enableSSL2(boolean enable) throws SocketException { base.enableSSL2(enable); } /** * Sets the default for SSL v2 for all new sockets. */ static public void enableSSL2Default(boolean enable) throws SocketException{ setSSLDefaultOption(SocketBase.SSL_ENABLE_SSL2, enable); } /** * Enables SSL v3 on this socket. It is enabled by default, unless the * default has been changed with enableSSL3Default. */ public void enableSSL3(boolean enable) throws SocketException { base.enableSSL3(enable); } /** * Sets the default for SSL v3 for all new sockets. */ static public void enableSSL3Default(boolean enable) throws SocketException{ setSSLDefaultOption(SocketBase.SSL_ENABLE_SSL3, enable); } /** * Enables TLS on this socket. It is enabled by default, unless the * default has been changed with enableTLSDefault. */ public void enableTLS(boolean enable) throws SocketException { base.enableTLS(enable); } /** * Sets the default for TLS for all new sockets. */ static public void enableTLSDefault(boolean enable) throws SocketException{ setSSLDefaultOption(SocketBase.SSL_ENABLE_TLS, enable); } /** * Enables Session tickets on this socket. It is disabled by default, * unless the default has been changed with * enableSessionTicketsDefault. */ public void enableSessionTickets(boolean enable) throws SocketException { base.enableSessionTickets(enable); } /** * Sets the default for Session Tickets for all new sockets. */ static public void enableSessionTicketsDefault(boolean enable) throws SocketException{ setSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS, enable); } /** * Enables the mode of renegotiation that the peer must use on this * socket. Default is never renegotiate at all. Unless the default has * been changed with SSLSocket.enableRenegotiationDefault. * * @param mode One of: * SSLSocket.SSL_RENEGOTIATE_NEVER - Never renegotiate at all. * * SSLSocket.SSL_RENEGOTIATE_UNRESTRICTED - Renegotiate without * restriction, whether or not the peer's hello bears the TLS * renegotiation info extension. Vulnerable, as in the past. * * SSLSocket.SSL_RENEGOTIATE_REQUIRES_XTN - Only renegotiate if the * peer's hello bears the TLS renegotiation_info extension. This is * safe renegotiation. * * SSLSocket.SSL_RENEGOTIATE_TRANSITIONAL - Disallow unsafe * renegotiation in server sockets only, but allow clients * to continue to renegotiate with vulnerable servers. * This value should only be used during the transition period * when few servers have been upgraded. */ public void enableRenegotiation(int mode) throws SocketException { if (mode >= SocketBase.SSL_RENEGOTIATE_NEVER && mode <= SocketBase.SSL_RENEGOTIATE_TRANSITIONAL) { base.enableRenegotiation(mode); } else { throw new SocketException("Incorrect input value."); } } /** * Set the mode of renegotiation that the peer must use for all new * sockets. The default is never renegotiate at all. * * @param mode One of: * SSLSocket.SSL_RENEGOTIATE_NEVER - Never renegotiate at all. * * SSLSocket.SSL_RENEGOTIATE_UNRESTRICTED - Renegotiate without * restriction, whether or not the peer's hello bears the TLS * renegotiation info extension. Vulnerable, as in the past. * * SSLSocket.SSL_RENEGOTIATE_REQUIRES_XTN - Only renegotiate if the * peer's hello bears the TLS renegotiation_info extension. This is * safe renegotiation. * * SSLSocket.SSL_RENEGOTIATE_TRANSITIONAL - Disallow unsafe * renegotiation in server sockets only, but allow clients * to continue to renegotiate with vulnerable servers. * This value should only be used during the transition period * when few servers have been upgraded. */ static public void enableRenegotiationDefault(int mode) throws SocketException { if (mode >= SocketBase.SSL_RENEGOTIATE_NEVER && mode <= SocketBase.SSL_RENEGOTIATE_TRANSITIONAL) { setSSLDefaultOptionMode(SocketBase.SSL_ENABLE_RENEGOTIATION, mode); } else { throw new SocketException("Incorrect input value."); } } /** * For this socket require that the peer must send * Signaling Cipher Suite Value (SCSV) or Renegotiation Info (RI) * extension in ALL handshakes. It is disabled by default, * unless the default has been changed with * SSLSocket.enableRequireSafeNegotiationDefault. */ public void enableRequireSafeNegotiation(boolean enable) throws SocketException { base.enableRequireSafeNegotiation(enable); } /** * For this socket require that the peer must send * Signaling Cipher Suite Value (SCSV) or Renegotiation Info (RI) * extension in ALL handshakes. It is disabled by default. */ static public void enableRequireSafeNegotiationDefault(boolean enable) throws SocketException { setSSLDefaultOption(SocketBase.SSL_REQUIRE_SAFE_NEGOTIATION, enable); } /** * Enable rollback detection for this socket. * It is enabled by default, unless the default has been changed * with enableRollbackDetectionDefault. */ public void enableRollbackDetection(boolean enable) throws SocketException { base.enableRollbackDetection(enable); } /** * Sets the default rollback detection for all new sockets. */ static void enableRollbackDetectionDefault(boolean enable) throws SocketException { setSSLDefaultOption(SocketBase.SSL_ROLLBACK_DETECTION, enable); } /** * This option, enableStepDown, is concerned with the generation * of step-down keys which are used with export suites. * If the server cert's public key is 512 bits or less * this option is ignored because step-down keys don't * need to be generated. * If the server cert's public key is more than 512 bits, * this option has the following effect: * enable=true: generate step-down keys * enable=false: don't generate step-down keys; disable * export cipher suites * * This option is enabled by default; unless the default has * been changed with SSLSocket.enableStepDownDefault. */ public void enableStepDown(boolean enable) throws SocketException { base.enableStepDown(enable); } /** * This option, enableStepDownDefault, is concerned with the * generation of step-down keys which are used with export suites. * This options will set the default for all sockets. * If the server cert's public key is 512 bits of less, * this option is ignored because step-down keys don't * need to be generated. * If the server cert's public key is more than 512 bits, * this option has the following effect: * enable=true: generate step-down keys * enable=false: don't generate step-down keys; disable * export cipher suites * * This option is enabled by default for all sockets. */ static void enableStepDownDefault(boolean enable) throws SocketException { setSSLDefaultOption(SocketBase.SSL_NO_STEP_DOWN, enable); } /** * Enable simultaneous read/write by separate read and write threads * (full duplex) for this socket. * It is disabled by default, unless the default has been changed * with enableFDXDefault. */ public void enableFDX(boolean enable) throws SocketException { base.enableFDX(enable); } /** * Sets the default to permit simultaneous read/write * by separate read and write threads (full duplex) * for all new sockets. */ static void enableFDXDefault(boolean enable) throws SocketException { setSSLDefaultOption(SocketBase.SSL_ENABLE_FDX, enable); } /** * Enable sending v3 client hello in v2 format for this socket. * It is enabled by default, unless the default has been changed * with enableV2CompatibleHelloDefault. */ public void enableV2CompatibleHello(boolean enable) throws SocketException { base.enableV2CompatibleHello(enable); } /** * Sets the default to send v3 client hello in v2 format * for all new sockets. */ static void enableV2CompatibleHelloDefault(boolean enable) throws SocketException { setSSLDefaultOption(SocketBase.SSL_V2_COMPATIBLE_HELLO, enable); } /** * @return a String listing the current SSLOptions for this SSLSocket. */ public String getSSLOptions() { return base.getSSLOptions(); } /** * * @param option * @return 0 for option disabled 1 for option enabled. */ static private native int getSSLDefaultOption(int option) throws SocketException; /** * * @return a String listing the Default SSLOptions for all SSLSockets. */ static public String getSSLDefaultOptions() { StringBuffer buf = new StringBuffer(); try { buf.append("Default Options configured for all SSLSockets: "); buf.append("\nSSL_ENABLE_SSL2" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SSL2) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SSL3" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SSL3) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_TLS" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_TLS) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SESSION_TICKETS" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS) != 0) ? "=on" : "=off")); buf.append("\nSSL_REQUIRE_CERTIFICATE"); switch (getSSLDefaultOption(SocketBase.SSL_REQUIRE_CERTIFICATE)) { case 0: buf.append("=Never"); break; case 1: buf.append("=Always"); break; case 2: buf.append("=First Handshake"); break; case 3: buf.append("=No Error"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUEST_CERTIFICATE" + ((getSSLDefaultOption(SocketBase.SSL_REQUEST_CERTIFICATE) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_CACHE" + ((getSSLDefaultOption(SocketBase.SSL_NO_CACHE) != 0) ? "=on" : "=off")); buf.append("\nSSL_ROLLBACK_DETECTION" + ((getSSLDefaultOption(SocketBase.SSL_ROLLBACK_DETECTION) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_STEP_DOWN" + ((getSSLDefaultOption(SocketBase.SSL_NO_STEP_DOWN) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_FDX" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_FDX) != 0) ? "=on" : "=off")); buf.append("\nSSL_V2_COMPATIBLE_HELLO" + ((getSSLDefaultOption(SocketBase.SSL_V2_COMPATIBLE_HELLO) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SESSION_TICKETS" + ((getSSLDefaultOption(SocketBase.SSL_ENABLE_SESSION_TICKETS) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_RENEGOTIATION"); switch (getSSLDefaultOption(SocketBase.SSL_ENABLE_RENEGOTIATION)) { case 0: buf.append("=SSL_RENEGOTIATE_NEVER"); break; case 1: buf.append("=SSL_RENEGOTIATE_UNRESTRICTED"); break; case 2: buf.append("=SSL_RENEGOTIATE_REQUIRES_XTN"); break; case 3: buf.append("=SSL_RENEGOTIATE_TRANSITIONAL"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUIRE_SAFE_NEGOTIATION" + ((getSSLDefaultOption(SocketBase.SSL_REQUIRE_SAFE_NEGOTIATION) != 0) ? "=on" : "=off")); } catch (SocketException e) { buf.append("\ngetSSLDefaultOptions exception " + e.getMessage()); } return buf.toString(); } /** * Sets whether the socket requires client authentication from the remote * peer. If requestClientAuth() has not already been called, this * method will tell the socket to request client auth as well as requiring * it. * @deprecated use requireClientAuth(int) */ public void requireClientAuth(boolean require, boolean onRedo) throws SocketException { base.requireClientAuth(require, onRedo); } /** * Sets whether the socket requires client authentication from the remote * peer. If requestClientAuth() has not already been called, this method * will tell the socket to request client auth as well as requiring it. * This is only meaningful for the server end of the SSL connection. * During the next handshake, the remote peer will be asked to * authenticate itself with the requirement that was set. * * @param mode One of: SSLSocket.SSL_REQUIRE_NEVER, * SSLSocket.SSL_REQUIRE_ALWAYS, * SSLSocket.SSL_REQUIRE_FIRST_HANDSHAKE, * SSLSocket.SSL_REQUIRE_NO_ERROR */ public void requireClientAuth(int mode) throws SocketException { if (mode >= SocketBase.SSL_REQUIRE_NEVER && mode <= SocketBase.SSL_REQUIRE_NO_ERROR) { base.requireClientAuth(mode); } else { throw new SocketException("Incorrect input value."); } } /** * Sets the default setting for requiring client authorization. * All subsequently created sockets will use this default setting. * @deprecated use requireClientAuthDefault(int) */ public void requireClientAuthDefault(boolean require, boolean onRedo) throws SocketException { setSSLDefaultOption(SocketBase.SSL_REQUIRE_CERTIFICATE, require ? (onRedo ? 1 : 2) : 0); } /** * Sets the default setting for requiring client authorization. * All subsequently created sockets will use this default setting * This is only meaningful for the server end of the SSL connection. * * @param mode One of: SSLSocket.SSL_REQUIRE_NEVER, * SSLSocket.SSL_REQUIRE_ALWAYS, * SSLSocket.SSL_REQUIRE_FIRST_HANDSHAKE, * SSLSocket.SSL_REQUIRE_NO_ERROR */ static public void requireClientAuthDefault(int mode) throws SocketException { if (mode >= SocketBase.SSL_REQUIRE_NEVER && mode <= SocketBase.SSL_REQUIRE_NO_ERROR) { setSSLDefaultOption(SocketBase.SSL_REQUEST_CERTIFICATE, true); setSSLDefaultOptionMode(SocketBase.SSL_REQUIRE_CERTIFICATE,mode); } else { throw new SocketException("Incorrect input value."); } } /** * Force an already started SSL handshake to complete. * This method should block until the handshake has completed. */ public native void forceHandshake() throws SocketException; /** * Determines whether this end of the socket is the client or the server * for purposes of the SSL protocol. By default, it is the client. * @param b true if this end of the socket is the SSL slient, false * if it is the SSL server. */ public void setUseClientMode(boolean b) { handshakeAsClient = b; } /** * @return true if this end of the socket is the SSL client, false * if it is the SSL server. */ public boolean getUseClientMode() { return handshakeAsClient; } /** * Resets the handshake state. */ public void resetHandshake() throws SocketException { resetHandshakeNative(handshakeAsClient); } private native void resetHandshakeNative(boolean asClient) throws SocketException; /** * Returns the security status of this socket. */ public native SSLSecurityStatus getStatus() throws SocketException; /** * Sets the nickname of the certificate to use for client authentication. * Alternately, you can specify an SSLClientCertificateSelectionCallback, * which will receive a list of certificates that are valid for client * authentication. * @see org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback */ public void setClientCertNickname(String nick) throws SocketException { base.setClientCertNickname(nick); } /** * Sets the certificate to use for client authentication. * Alternately, you can specify an SSLClientCertificateSelectionCallback, * which will receive a list of certificates that are valid for client * authentication. * @see org.mozilla.jss.ssl.SSLClientCertificateSelectionCallback */ public void setClientCert( org.mozilla.jss.crypto.X509Certificate cert) throws SocketException { base.setClientCert(cert); } /** * Enables/disables the request of client authentication. This is only * meaningful for the server end of the SSL connection. During the next * handshake, the remote peer will be asked to authenticate itself. * @see org.mozilla.jss.ssl.SSLSocket#requireClientAuth */ public void requestClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuth instead. */ public void setNeedClientAuth(boolean b) throws SocketException { base.requestClientAuth(b); } /** * Enables/disables the request of client authentication. This is only * meaningful for the server end of the SSL connection. During the next * handshake, the remote peer will be asked to authenticate itself. *

In addition, the client certificate's expiration will not * prevent it from being accepted. * @see org.mozilla.jss.ssl.SSLSocket#requireClientAuth public void requestClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * @deprecated As of JSS 3.0. This method is misnamed. Use * requestClientAuthNoExpiryCheck instead. */ public void setNeedClientAuthNoExpiryCheck(boolean b) throws SocketException { base.requestClientAuthNoExpiryCheck(b); } /** * Enables/disables the session cache. By default, the session cache * is enabled. */ public void useCache(boolean b) throws SocketException { base.useCache(b); } /** * Sets the default setting for use of the session cache. */ public void useCacheDefault(boolean b) throws SocketException { setSSLDefaultOption(SocketBase.SSL_NO_CACHE, !b); } /* * _min_enum and _max_enum should be one of the following: * SocketBase.SSL_LIBRARY_VERSION_3_0 * SocketBase.SSL_LIBRARY_VERSION_TLS_1_0 * SocketBase.SSL_LIBRARY_VERSION_TLS_1_1 * SocketBase.SSL_LIBRARY_VERSION_TLS_1_2 */ public static class SSLVersionRange { private int _min_enum; private int _max_enum; public static final int ssl3 = SocketBase.SSL_LIBRARY_VERSION_3_0; public static final int tls1_0 = SocketBase.SSL_LIBRARY_VERSION_TLS_1_0; public static final int tls1_1 = SocketBase.SSL_LIBRARY_VERSION_TLS_1_1; public static final int tls1_2 = SocketBase.SSL_LIBRARY_VERSION_TLS_1_2; public SSLVersionRange(int min_enum, int max_enum) throws IllegalArgumentException { if ((min_enum >= SocketBase.SSL_LIBRARY_VERSION_3_0) && (max_enum <= SocketBase.SSL_LIBRARY_VERSION_TLS_1_2) && (min_enum <= max_enum)) { _min_enum = min_enum; _max_enum = max_enum; } else { throw new IllegalArgumentException("JSS SSLSocket SSLVersionRange: arguments out of range"); } } int getMinEnum() { return _min_enum; } int getMaxEnum() { return _max_enum; } } public static class SSLProtocolVariant { private int _enum; private SSLProtocolVariant(int val) { _enum = val; } int getEnum() { return _enum; } public static final SSLProtocolVariant STREAM = new SSLProtocolVariant(SocketBase.SSL_Variant_Stream); public static final SSLProtocolVariant DATA_GRAM = new SSLProtocolVariant(SocketBase.SSL_Variant_Datagram); } public static void setSSLVersionRangeDefault(SSLProtocolVariant ssl_variant, SSLVersionRange range) throws SocketException { if (range == null) throw new SocketException("setSSLVersionRangeDefault: range null"); setSSLVersionRangeDefault(ssl_variant.getEnum(), range.getMinEnum(), range.getMaxEnum()); } /** * Sets SSL Version Range Default */ private static native void setSSLVersionRangeDefault(int ssl_variant, int min, int max) throws SocketException; private static void setSSLDefaultOption(int option, boolean on) throws SocketException { setSSLDefaultOption(option, on ? 1 : 0); } /** * Sets SSL Default options that have simple enable/disable values. */ private static native void setSSLDefaultOption(int option, int on) throws SocketException; /** * Set SSL default options that have more modes than enable/disable. */ private static native void setSSLDefaultOptionMode(int option, int mode) throws SocketException; /** * Enables/disables the cipher on this socket. */ public native void setCipherPreference(int cipher, boolean enable) throws SocketException; /** * Returns whether this cipher is enabled or disabled on this socket. */ public native boolean getCipherPreference( int cipher) throws SocketException; /** * Sets the default for whether this cipher is enabled or disabled. */ public static native void setCipherPreferenceDefault(int cipher, boolean enable) throws SocketException; /** * Returns the default for whether this cipher is enabled or disabled. */ public static native boolean getCipherPreferenceDefault(int cipher) throws SocketException; native int socketAvailable() throws IOException; int read(byte[] b, int off, int len) throws IOException, SocketTimeoutException { synchronized (readLock) { synchronized (this) { if ( isClosed ) { /* abort read if socket is closed */ throw new IOException( "Socket has been closed, and cannot be reused."); } inRead = true; } int iRet; try { iRet = socketRead(b, off, len, base.getTimeout()); } catch (SocketTimeoutException ste) { throw new SocketTimeoutException( "SocketTimeoutException cannot read on socket"); } catch (IOException ioe) { throw new IOException( "SocketException cannot read on socket"); } finally { synchronized (this) { inRead = false; } } return iRet; } } void write(byte[] b, int off, int len) throws IOException, SocketTimeoutException { synchronized (writeLock) { synchronized (this) { if ( isClosed ) { /* abort write if socket is closed */ throw new IOException( "Socket has been closed, and cannot be reused."); } inWrite = true; } try { socketWrite(b, off, len, base.getTimeout()); } catch (SocketTimeoutException ste) { throw new SocketTimeoutException( "SocketTimeoutException cannot write on socket"); } catch (IOException ioe) { throw new IOException( "SocketException cannot write on socket"); } finally { synchronized (this) { inWrite = false; } } } } private native int socketRead(byte[] b, int off, int len, int timeout) throws IOException; private native void socketWrite(byte[] b, int off, int len, int timeout) throws IOException; /** * Removes the current session from the session cache. */ public native void invalidateSession() throws SocketException; /** * Causes SSL to begin a full, new SSL 3.0 handshake from scratch * on a connection that has already completed one handshake. *

Does not flush the SSL3 cache entry first, so a full handshake * will not take place. Instead only the symmetric session keys will * be regenerated. */ public void redoHandshake() throws SocketException { redoHandshake(false); } /** * Causes SSL to begin a full, new SSL 3.0 handshake from scratch * on a connection that has already completed one handshake. * @param flushCache If true, this session will be flushed from the cache. * This will force a complete SSL handshake with a private key operation. * If false, only the session key will be regenerated. */ public native void redoHandshake(boolean flushCache) throws SocketException; protected void finalize() throws Throwable { close(); /* in case user did not call close */ } public static class CipherPolicy { private int _enum; private CipherPolicy(int _enum) { } int getEnum() { return _enum; } public static final CipherPolicy DOMESTIC = new CipherPolicy(SocketBase.SSL_POLICY_DOMESTIC); public static final CipherPolicy EXPORT = new CipherPolicy(SocketBase.SSL_POLICY_EXPORT); public static final CipherPolicy FRANCE = new CipherPolicy(SocketBase.SSL_POLICY_FRANCE); } /** * Sets the SSL cipher policy. This must be called before creating any * SSL sockets. */ public static void setCipherPolicy(CipherPolicy cp) throws SocketException { setCipherPolicyNative(cp.getEnum()); } private static native void setCipherPolicyNative(int policyEnum) throws SocketException; /** * Returns the addresses and ports of this socket * or an error message if the socket is not in a valid state. */ public String toString() { try { InetAddress inetAddr = getInetAddress(); InetAddress localAddr = getLocalAddress(); int port = getPort(); int localPort = getLocalPort(); StringBuffer buf = new StringBuffer(); buf.append("SSLSocket[addr="); buf.append(inetAddr); buf.append(",localaddr="); buf.append(localAddr); buf.append(",port="); buf.append(port); buf.append(",localport="); buf.append(localPort); buf.append("]"); return buf.toString(); } catch (Exception e) { return "Exception caught in toString(): " + e.getMessage(); } } /** * isFipsCipherSuite * *@return true if the ciphersuite isFIPS, false otherwise */ public static boolean isFipsCipherSuite(int ciphersuite) throws SocketException { return isFipsCipherSuiteNative(ciphersuite); } private static native boolean isFipsCipherSuiteNative(int ciphersuite) throws SocketException; /** * Returns a list of cipher suites that are implemented by NSS. * Each element in the array will be one of the cipher suite constants * defined in this class (for example, * TLS_RSA_WITH_AES_128_CBC_SHA). */ public static native int[] getImplementedCipherSuites(); } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLSocketException.java000066400000000000000000000020441326145000000233010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; /** * A subclass of java.net.SocketException that contains an error code * from the native (NSS/NSPR) code. These error codes are defined in the * class org.mozilla.jss.util.NativeErrcodes. * @see org.mozilla.jss.util.NativeErrcodes */ public class SSLSocketException extends java.net.SocketException { private int errcode = -1; public SSLSocketException() { super(); } public SSLSocketException(String msg) { super(msg); } public SSLSocketException(String msg, int errcode) { super(msg); this.errcode = errcode; } /** * Returns an error code, as defined in class * org.mozilla.jss.util.NativeErrcodes. * @see org.mozilla.jss.util.NativeErrcodes */ public int getErrcode() { return errcode; } } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLSocketListener.java000066400000000000000000000006361326145000000231350ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; public interface SSLSocketListener extends SSLHandshakeCompletedListener { public void alertReceived(SSLAlertEvent event); public void alertSent(SSLAlertEvent event); } jss-4.4.3/jss/org/mozilla/jss/ssl/SSLTest.java000066400000000000000000000062131326145000000211130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.net.*; import java.io.*; import org.mozilla.jss.CryptoManager; import java.util.*; public class SSLTest { public static void main(String[] args) { new SSLTest(args); } private Hashtable params = new Hashtable(); private String[] defaults = { "port", "443", "host", "www.amazon.com", "remotehost", "www.amazon.com" }; private void initParams() { processArgs(defaults); } private void processArgs(String[] args) { int i; for(i=0; i < args.length; i+=2) { System.out.flush(); params.put(args[i], args[i+1]); } } private void dumpParams() { Enumeration _enum = params.keys(); System.out.println("Parameters:"); while (_enum.hasMoreElements() ) { String key = (String) _enum.nextElement(); System.out.println(key + "=" + (String)params.get(key)); } } public SSLTest(String[] args) { try { initParams(); processArgs(args); dumpParams(); CryptoManager.initialize("."); int port = (new Integer( (String) params.get("port") )).intValue(); Socket s = new Socket((String)params.get("host"), port); SSLSocket ss = new SSLSocket(s, (String)params.get("remotehost"), null, null); ss.setSoTimeout(5000); OutputStream os = ss.getOutputStream(); String writeString = "GET / HTTP/1.0\n\n"; byte[] writeBytes = writeString.getBytes("8859_1"); os.write(writeBytes); InputStream is = ss.getInputStream(); int numRead = 0; byte[] inbuf = new byte[256]; while( (numRead = is.read(inbuf)) != -1 ) { System.out.print( new String(inbuf, 0, numRead, "UTF-8")); } ss.setKeepAlive(true); ss.setReceiveBufferSize(32000); ss.setSendBufferSize(8000); ss.setSoLinger(true, 10); ss.setTcpNoDelay(true); System.out.println("remote addr is " + ss.getInetAddress().toString()); System.out.println("remote port is " + ss.getPort()); System.out.println("local addr is " + ss.getLocalAddress().toString()); System.out.println("local port is " + ss.getLocalPort()); System.out.println("keepalive is " + ss.getKeepAlive()); System.out.println("receive buffer size is " + ss.getReceiveBufferSize()); System.out.println("send buffer size is " + ss.getSendBufferSize()); System.out.println("solinger is " + ss.getSoLinger()); System.out.println("sotimeout is " + ss.getSoTimeout()); System.out.println("tcpNoDelay is " + ss.getTcpNoDelay()); ss.shutdownInput(); ss.shutdownOutput(); ss.close(); } catch(Exception e) { e.printStackTrace(); } try { Runtime.getRuntime().gc(); }catch(Exception e) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/ssl/SocketBase.java000066400000000000000000000405541326145000000216430ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.io.IOException; import java.lang.reflect.Constructor; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Enumeration; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.ObjectNotFoundException; import org.mozilla.jss.crypto.TokenException; import org.mozilla.jss.crypto.X509Certificate; import org.mozilla.jss.util.Assert; class SocketBase { // This is just another reference to the same proxy object // that is held by the SSLSocket or SSLServerSocket. private SocketProxy sockProxy; private int timeout; int getTimeout() { return timeout; } void setTimeout(int timeout) { this.timeout = timeout; } void setProxy(SocketProxy sockProxy) { this.sockProxy = sockProxy; } native byte[] socketCreate(Object socketObject, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback, java.net.Socket javaSock, String host, int family) throws SocketException; byte[] socketCreate(Object socketObject, SSLCertificateApprovalCallback certApprovalCallback, SSLClientCertificateSelectionCallback clientCertSelectionCallback, int family) throws SocketException { return socketCreate(socketObject, certApprovalCallback, clientCertSelectionCallback, null, null, family); } native void socketBind(byte[] addrBA, int port) throws SocketException; /** * Enums. These must match the enums table in common.c. This is * safer than copying the values of the C constants, which are subject * to change, into Java code. * Note to developer these constants are not all related! i.e. you cannot * pass in PR_SHUTDOWN_RCV to setSSLOption etc! Check their usage * in NSS and NSPR before using. */ static final int SSL_ENABLE_SSL2 = 0; static final int SSL_ENABLE_SSL3 = 1; static final int SSL_ENABLE_TLS = 2; static final int TCP_NODELAY = 3; static final int SO_KEEPALIVE = 4; static final int PR_SHUTDOWN_RCV = 5; static final int PR_SHUTDOWN_SEND = 6; static final int SSL_REQUIRE_CERTIFICATE = 7; static final int SSL_REQUEST_CERTIFICATE = 8; static final int SSL_NO_CACHE = 9; static final int SSL_POLICY_DOMESTIC = 10; static final int SSL_POLICY_EXPORT = 11; static final int SSL_POLICY_FRANCE = 12; static final int SSL_ROLLBACK_DETECTION = 13; static final int SSL_NO_STEP_DOWN = 14; static final int SSL_ENABLE_FDX = 15; static final int SSL_V2_COMPATIBLE_HELLO = 16; static final int SSL_REQUIRE_NEVER = 17; static final int SSL_REQUIRE_ALWAYS = 18; static final int SSL_REQUIRE_FIRST_HANDSHAKE = 19; static final int SSL_REQUIRE_NO_ERROR = 20; static final int SSL_ENABLE_SESSION_TICKETS = 21; static final int SSL_ENABLE_RENEGOTIATION = 22; static final int SSL_RENEGOTIATE_NEVER = 23; static final int SSL_RENEGOTIATE_UNRESTRICTED = 24; static final int SSL_RENEGOTIATE_REQUIRES_XTN = 25; static final int SSL_RENEGOTIATE_TRANSITIONAL = 26; static final int SSL_REQUIRE_SAFE_NEGOTIATION = 27; /* ssl/sslproto.h for supporting SSLVersionRange */ static final int SSL_LIBRARY_VERSION_2 = 28; static final int SSL_LIBRARY_VERSION_3_0 = 29; static final int SSL_LIBRARY_VERSION_TLS_1_0 = 30; static final int SSL_LIBRARY_VERSION_TLS_1_1 = 31; static final int SSL_LIBRARY_VERSION_TLS_1_2 = 32; /* ssl/sslt.h */ static final int SSL_Variant_Stream = 33; static final int SSL_Variant_Datagram = 34; static final int SSL_AF_INET = 50; static final int SSL_AF_INET6 = 51; void close() throws IOException { socketClose(); } // SSLServerSocket and SSLSocket close methods // have their own synchronization control that // protects SocketBase.socketClose. native void socketClose() throws IOException; private boolean requestingClientAuth = false; void requestClientAuth(boolean b) throws SocketException { requestingClientAuth = b; setSSLOption(SSL_REQUEST_CERTIFICATE, b); } public void requestClientAuthNoExpiryCheck(boolean b) throws SocketException { requestingClientAuth = b; requestClientAuthNoExpiryCheckNative(b); } private native void requestClientAuthNoExpiryCheckNative(boolean b) throws SocketException; void enableSSL2(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_SSL2, enable); } void enableSSL3(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_SSL3, enable); } void enableTLS(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_TLS, enable); } void enableSessionTickets(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_SESSION_TICKETS, enable); } void enableRenegotiation(int mode) throws SocketException { setSSLOptionMode(SocketBase.SSL_ENABLE_RENEGOTIATION, mode); } void enableRequireSafeNegotiation(boolean enable) throws SocketException { setSSLOption(SSL_REQUIRE_SAFE_NEGOTIATION, enable); } void enableRollbackDetection(boolean enable) throws SocketException { setSSLOption(SSL_ROLLBACK_DETECTION, enable); } void enableStepDown(boolean enable) throws SocketException { setSSLOption(SSL_NO_STEP_DOWN, enable); } void enableFDX(boolean enable) throws SocketException { setSSLOption(SSL_ENABLE_FDX, enable); } void enableV2CompatibleHello(boolean enable) throws SocketException { setSSLOption(SSL_V2_COMPATIBLE_HELLO, enable); } void setSSLOption(int option, boolean on) throws SocketException { setSSLOption(option, on ? 1 : 0); } /** * Sets SSL options for this socket that have simple * enable/disable values. */ native void setSSLOption(int option, int on) throws SocketException; void setSSLVersionRange(org.mozilla.jss.ssl.SSLSocket.SSLVersionRange range) throws SocketException { setSSLVersionRange(range.getMinEnum(), range.getMaxEnum()); } /** * Sets SSL Version Range for this socket to support TLS v1.1 and v1.2 */ native void setSSLVersionRange(int min, int max) throws SocketException; /** * Sets the SSL option setting mode value use for options * that have more values than just enable/disable. */ native void setSSLOptionMode(int option, int option2) throws SocketException; /* return 0 for option disabled 1 for option enabled. */ native int getSSLOption(int option) throws SocketException; public String getSSLOptions() { StringBuffer buf = new StringBuffer(); try { buf.append("SSL Options configured for this SSLSocket:"); buf.append("\nSSL_ENABLE_SSL2" + ((getSSLOption(SocketBase.SSL_ENABLE_SSL2) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SSL3" + ((getSSLOption(SocketBase.SSL_ENABLE_SSL3) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_TLS" + ((getSSLOption(SocketBase.SSL_ENABLE_TLS) != 0) ? "=on" : "=off")); buf.append("\nSSL_REQUIRE_CERTIFICATE"); switch (getSSLOption(SocketBase.SSL_REQUIRE_CERTIFICATE)) { case 0: buf.append("=Never"); break; case 1: buf.append("=Always"); break; case 2: buf.append("=First Handshake"); break; case 3: buf.append("=No Error"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUEST_CERTIFICATE" + ((getSSLOption(SocketBase.SSL_REQUEST_CERTIFICATE) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_CACHE" + ((getSSLOption(SocketBase.SSL_NO_CACHE) != 0) ? "=on" : "=off")); buf.append("\nSSL_ROLLBACK_DETECTION" + ((getSSLOption(SocketBase.SSL_ROLLBACK_DETECTION) != 0) ? "=on" : "=off")); buf.append("\nSSL_NO_STEP_DOWN" + ((getSSLOption(SocketBase.SSL_NO_STEP_DOWN) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_FDX" + ((getSSLOption(SocketBase.SSL_ENABLE_FDX) != 0) ? "=on" : "=off")); buf.append("\nSSL_V2_COMPATIBLE_HELLO" + ((getSSLOption(SocketBase.SSL_V2_COMPATIBLE_HELLO) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_SESSION_TICKETS" + ((getSSLOption(SocketBase.SSL_ENABLE_SESSION_TICKETS) != 0) ? "=on" : "=off")); buf.append("\nSSL_ENABLE_RENEGOTIATION"); switch (getSSLOption(SocketBase.SSL_ENABLE_RENEGOTIATION)) { case 0: buf.append("=SSL_RENEGOTIATE_NEVER"); break; case 1: buf.append("=SSL_RENEGOTIATE_UNRESTRICTED"); break; case 2: buf.append("=SSL_RENEGOTIATE_REQUIRES_XTN"); break; case 3: buf.append("=SSL_RENEGOTIATE_TRANSITIONAL"); break; default: buf.append("=Report JSS Bug this option has a status."); break; } //end switch buf.append("\nSSL_REQUIRE_SAFE_NEGOTIATION" + ((getSSLOption(SocketBase.SSL_REQUIRE_SAFE_NEGOTIATION) != 0) ? "=on" : "=off")); } catch (SocketException e) { buf.append("\ngetSSLOptions exception " + e.getMessage()); } return buf.toString(); } /** * Converts a host-ordered 4-byte internet address into an InetAddress. * Unfortunately InetAddress provides no more efficient means * of construction than getByName(), and it is final. * * @return The InetAddress corresponding to the given integer, * or null if the InetAddress could not be constructed. */ private static InetAddress convertIntToInetAddress(int intAddr) { InetAddress in; int[] addr = new int[4]; addr[0] = ((intAddr >>> 24) & 0xff); addr[1] = ((intAddr >>> 16) & 0xff); addr[2] = ((intAddr >>> 8) & 0xff); addr[3] = ((intAddr) & 0xff); try { in = InetAddress.getByName( addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3]); } catch (java.net.UnknownHostException e) { in = null; } return in; } private native byte[] getLocalAddressByteArrayNative() throws SocketException; private native byte[] getPeerAddressByteArrayNative() throws SocketException; /** * @return the InetAddress of the peer end of the socket. */ InetAddress getInetAddress() { try { byte[] address = getPeerAddressByteArrayNative(); InetAddress iAddr = null; try { iAddr = InetAddress.getByAddress(address); } catch (UnknownHostException e) { } return iAddr; } catch (SocketException e) { return null; } } private native int getPeerAddressNative() throws SocketException; /** * @return The local IP address. */ InetAddress getLocalAddress() { try { byte[] address = getLocalAddressByteArrayNative(); InetAddress lAddr = null; try { lAddr = InetAddress.getByAddress(address); } catch (UnknownHostException e) { } return lAddr; } catch (SocketException e) { return null; } } private native int getLocalAddressNative() throws SocketException; public int getLocalPort() { try { return getLocalPortNative(); } catch (SocketException e) { return 0; } } private native int getLocalPortNative() throws SocketException; void requireClientAuth(boolean require, boolean onRedo) throws SocketException { if (require && !requestingClientAuth) { requestClientAuth(true); } setSSLOption(SSL_REQUIRE_CERTIFICATE, require ? (onRedo ? 1 : 2) : 0); } void requireClientAuth(int mode) throws SocketException { if (mode > 0 && !requestingClientAuth) { requestClientAuth(true); } setSSLOptionMode(SocketBase.SSL_REQUIRE_CERTIFICATE, mode); } /** * Sets the nickname of the certificate to use for client authentication. */ public void setClientCertNickname(String nick) throws SocketException { try { CryptoManager cm = CryptoManager.getInstance(); X509Certificate cert = cm.findCertByNickname(nick); setClientCert(cert); } catch (CryptoManager.NotInitializedException nie) { throw new RuntimeException(nie); } catch (ObjectNotFoundException onfe) { throw new RuntimeException(onfe); } catch (TokenException te) { throw new RuntimeException(te); } } native void setClientCert(org.mozilla.jss.crypto.X509Certificate cert) throws SocketException; void useCache(boolean b) throws SocketException { setSSLOption(SSL_NO_CACHE, !b); } static Throwable processExceptions(Throwable topException, Throwable bottomException) { try { StringBuffer strBuf; strBuf = new StringBuffer(topException.toString()); if (bottomException != null) { strBuf.append(" --> "); strBuf.append(bottomException.toString()); } Class excepClass = topException.getClass(); Class stringClass = java.lang.String.class; Constructor cons = excepClass.getConstructor(new Class[] { stringClass }); return (Throwable) cons.newInstance(new Object[] { strBuf.toString() }); } catch (Exception e) { Assert.notReached("Problem constructing exception container"); return topException; } } static private int supportsIPV6 = -1; static boolean supportsIPV6() { if (supportsIPV6 >= 0) { if (supportsIPV6 > 0) { return true; } else { return false; } } Enumeration netInter; try { netInter = NetworkInterface.getNetworkInterfaces(); } catch (SocketException e) { return false; } while (netInter.hasMoreElements()) { NetworkInterface ni = (NetworkInterface) netInter.nextElement(); Enumeration addrs = ni.getInetAddresses(); while (addrs.hasMoreElements()) { Object o = addrs.nextElement(); if (o.getClass() == InetAddress.class || o.getClass() == Inet4Address.class || o.getClass() == Inet6Address.class) { InetAddress iaddr = (InetAddress) o; if (o.getClass() == Inet6Address.class) { supportsIPV6 = 1; return true; } } } } supportsIPV6 = 0; return false; } } jss-4.4.3/jss/org/mozilla/jss/ssl/SocketProxy.java000066400000000000000000000007721326145000000221100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; class SocketProxy extends org.mozilla.jss.util.NativeProxy { public SocketProxy(byte[] pointer) { super(pointer); } protected native void releaseNativeResources(); protected void finalize() throws Throwable { super.finalize(); } } jss-4.4.3/jss/org/mozilla/jss/ssl/TestCertApprovalCallback.java000066400000000000000000000046731326145000000245010ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.io.IOException; import java.io.InterruptedIOException; import java.net.*; import java.util.*; import org.mozilla.jss.crypto.*; /** * This is a test implementation of the certificate approval callback which * gets invoked when the server presents a certificate which is not * trusted by the client */ public class TestCertApprovalCallback implements SSLCertificateApprovalCallback { public boolean approve( org.mozilla.jss.crypto.X509Certificate servercert, SSLCertificateApprovalCallback.ValidityStatus status) { SSLCertificateApprovalCallback.ValidityItem item; System.out.println("in TestCertApprovalCallback.approve()"); /* dump out server cert details */ System.out.println("Peer cert details: "+ "\n subject: "+servercert.getSubjectDN().toString()+ "\n issuer: "+servercert.getIssuerDN().toString()+ "\n serial: "+servercert.getSerialNumber().toString() ); /* iterate through all the problems */ boolean trust_the_server_cert=false; Enumeration errors = status.getReasons(); int i=0; while (errors.hasMoreElements()) { i++; item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement(); System.out.println("item "+i+ " reason="+item.getReason()+ " depth="+item.getDepth()); org.mozilla.jss.crypto.X509Certificate cert = item.getCert(); if (item.getReason() == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) { trust_the_server_cert = true; } System.out.println(" cert details: "+ "\n subject: "+cert.getSubjectDN().toString()+ "\n issuer: "+cert.getIssuerDN().toString()+ "\n serial: "+cert.getSerialNumber().toString() ); } if (trust_the_server_cert) { System.out.println("importing certificate."); try { InternalCertificate newcert = org.mozilla.jss.CryptoManager.getInstance(). importCertToPerm(servercert,"testnick"); newcert.setSSLTrust(InternalCertificate.TRUSTED_PEER | InternalCertificate.VALID_PEER); } catch (Exception e) { System.out.println("thrown exception: "+e); } } /* allow the connection to continue. returning false here would abort the connection */ return true; } } jss-4.4.3/jss/org/mozilla/jss/ssl/TestClientCertificateSelectionCallback.java000066400000000000000000000033421326145000000273160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.ssl; import java.io.IOException; import java.io.InterruptedIOException; import java.net.*; import java.util.*; /** * This interface is what you should implement if you want to * be able to decide whether or not you want to approve the peer's cert, * instead of having NSS do that. */ public class TestClientCertificateSelectionCallback implements SSLClientCertificateSelectionCallback { /** * this method will be called form the native callback code * when a certificate is requested. You must return a String * which is the nickname of the certificate you wish to present. * * @param nicknames A Vector of Strings. These strings are an * aid to the user to select the correct nickname. This list is * made from the list of all certs which are valid, match the * CA's trusted by the server, and which you have the private * key of. If nicknames.length is 0, you should present an * error to the user saying 'you do not have any unexpired * certificates'. * @return You must return the nickname of the certificate you * wish to use. You can return null if you do not wish to send * a certificate. */ public String select(Vector nicknames) { Enumeration e = nicknames.elements(); String s="",first=null; System.out.println("in TestClientCertificateSelectionCallback.select() "+s); while (e.hasMoreElements()) { s = (String)e.nextElement(); if (first == null) { first = s; } System.out.println(" "+s); } return first; } } jss-4.4.3/jss/org/mozilla/jss/ssl/callbacks.c000066400000000000000000000557131326145000000210430ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include #include "jssl.h" #include #include #include #include static SECStatus secCmpCertChainWCANames(CERTCertificate *cert, CERTDistNames *caNames) { SECItem * caname; CERTCertificate * curcert; CERTCertificate * oldcert; PRUint32 contentlen; int j; int headerlen; int depth; SECStatus rv; SECItem issuerName; SECItem compatIssuerName; depth=0; curcert = CERT_DupCertificate(cert); while( curcert ) { issuerName = curcert->derIssuer; /* compute an alternate issuer name for compatibility with 2.0 * enterprise server, which send the CA names without * the outer layer of DER header */ rv = DER_Lengths(&issuerName, &headerlen, &contentlen); if ( rv == SECSuccess ) { compatIssuerName.data = &issuerName.data[headerlen]; compatIssuerName.len = issuerName.len - headerlen; } else { compatIssuerName.data = NULL; compatIssuerName.len = 0; } for (j = 0; j < caNames->nnames; j++) { caname = &caNames->names[j]; if (SECITEM_CompareItem(&issuerName, caname) == SECEqual) { rv = SECSuccess; CERT_DestroyCertificate(curcert); goto done; } else if (SECITEM_CompareItem(&compatIssuerName, caname) == SECEqual) { rv = SECSuccess; CERT_DestroyCertificate(curcert); goto done; } } if ( ( depth <= 20 ) && ( SECITEM_CompareItem(&curcert->derIssuer, &curcert->derSubject) != SECEqual ) ) { oldcert = curcert; curcert = CERT_FindCertByName(curcert->dbhandle, &curcert->derIssuer); CERT_DestroyCertificate(oldcert); depth++; } else { CERT_DestroyCertificate(curcert); curcert = NULL; } } rv = SECFailure; done: return rv; } /* * This callback is called when the peer has request you to send you * client-auth certificate. You get to pick which one you want * to send. * * Expected return values: * 0 SECSuccess * -1 SECFailure - No suitable certificate found. * -2 SECWouldBlock (we're waiting while we ask the user). */ SECStatus JSSL_CallCertSelectionCallback( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey) { CERTCertificate * cert; PK11SlotInfo * slot; SECKEYPrivateKey * privkey; jobject nicknamecallback = (jobject)arg; SECStatus rv = SECFailure; CERTCertNicknames * names; int i; int count =0; jclass vectorclass; jmethodID vectorcons; jobject vector; jmethodID vector_add; jstring nickname_string; jstring chosen_nickname; char *chosen_nickname_for_c; jboolean chosen_nickname_cleanup; jclass clientcertselectionclass; jmethodID clientcertselectionclass_select; JNIEnv *env; int debug_cc=0; if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto loser; } PR_ASSERT(env != NULL); clientcertselectionclass = (*env)->GetObjectClass(env,nicknamecallback); clientcertselectionclass_select = (*env)->GetMethodID( env, clientcertselectionclass, "select", "(Ljava/util/Vector;)Ljava/lang/String;" ); /* get java bits and piece ready to create a new vector */ vectorclass = (*env)->FindClass( env, "java/util/Vector"); if (debug_cc) { PR_fprintf(PR_STDOUT," got vectorclass: %lx\n",vectorclass); } vectorcons = (*env)->GetMethodID( env, vectorclass,"","()V"); if (debug_cc) { PR_fprintf(PR_STDOUT," got vectorcons: %lx\n",vectorcons); } vector_add = (*env)->GetMethodID( env, vectorclass, "addElement", "(Ljava/lang/Object;)V"); if (debug_cc) { PR_fprintf(PR_STDOUT," got vectoradd: %lx\n",vector_add); } /* create new vector */ vector = (*env)->NewObject( env, vectorclass, vectorcons); if (debug_cc) { PR_fprintf(PR_STDOUT," got new vector: %lx\n",vector); } /* next, get a list of all the valid nicknames */ names = CERT_GetCertNicknames(CERT_GetDefaultCertDB(), SEC_CERT_NICKNAMES_USER, NULL /*pinarg*/); if (names != NULL) { for (i = 0; i < names->numnicknames; i++) { if (debug_cc) { PR_fprintf(PR_STDOUT,"checking nn: %s\n",names->nicknames[i]); } cert = JSS_PK11_findCertAndSlotFromNickname( names->nicknames[i], NULL /*pinarg*/, &slot); if ( !cert ) continue; /* Only check unexpired certs */ if ( CERT_CheckCertValidTimes(cert, PR_Now(), PR_TRUE /*allowOverride*/) != secCertTimeValid ) { if (debug_cc) { PR_fprintf(PR_STDOUT," not valid\n"); } CERT_DestroyCertificate(cert); PK11_FreeSlot(slot); continue; } rv = secCmpCertChainWCANames(cert, caNames); if ( rv == SECSuccess ) { if (debug_cc) { PR_fprintf(PR_STDOUT," matches ca name\n"); } privkey = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*pinarg*/); /* just test if we have the private key */ if ( privkey ) { count++; if (debug_cc) { PR_fprintf(PR_STDOUT," found privkey\n"); } SECKEY_DestroyPrivateKey(privkey); /* if we have, then this nickname has passed all the tests necessary to put it in the list */ nickname_string = (*env)->NewStringUTF(env, names->nicknames[i]); if (debug_cc) { PR_fprintf(PR_STDOUT," calling vector_add\n"); } (*env)->CallVoidMethod(env,vector,vector_add, nickname_string ); if (debug_cc) { PR_fprintf(PR_STDOUT," back from vector_add\n"); } } } CERT_DestroyCertificate(cert); PK11_FreeSlot(slot); } CERT_FreeNicknames(names); } /* okay - so we made a vector of the certs - now call the java class to figure out which one to send */ chosen_nickname = (*env)->CallObjectMethod(env,nicknamecallback, clientcertselectionclass_select, vector ); if (chosen_nickname == NULL) { rv = SECFailure; goto loser; } chosen_nickname_for_c = (char*)(*env)->GetStringUTFChars(env, chosen_nickname, &chosen_nickname_cleanup); if (debug_cc) { PR_fprintf(PR_STDOUT," chosen nickname: %s\n",chosen_nickname_for_c); } cert = JSS_PK11_findCertAndSlotFromNickname(chosen_nickname_for_c, NULL /*pinarg*/, &slot); if (debug_cc) { PR_fprintf(PR_STDOUT," found certificate\n"); } if (chosen_nickname_cleanup == JNI_TRUE) { (*env)->ReleaseStringUTFChars(env, chosen_nickname, chosen_nickname_for_c); } if (cert == NULL) { rv = SECFailure; goto loser; } privkey = PK11_FindPrivateKeyFromCert(slot, cert, NULL /*pinarg*/); PK11_FreeSlot(slot); if ( privkey == NULL ) { CERT_DestroyCertificate(cert); rv = SECFailure; goto loser; } if (debug_cc) { PR_fprintf(PR_STDOUT," found privkey. returning\n"); } *pRetCert = cert; *pRetKey = privkey; rv = SECSuccess; loser: return rv; } void JSSL_AlertReceivedCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert) { JSSL_SocketData *socket = (JSSL_SocketData*) arg; jint rc; JNIEnv *env; jclass socketClass, eventClass; jmethodID eventConstructor, eventSetLevel, eventSetDescription; jobject event; jmethodID fireEvent; PR_ASSERT(socket != NULL); PR_ASSERT(socket->socketObject != NULL); rc = (*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL); PR_ASSERT(rc == JNI_OK); PR_ASSERT(env != NULL); /* SSLAlertEvent event = new SSLAlertEvent(socket); */ socketClass = (*env)->FindClass(env, SSLSOCKET_CLASS); PR_ASSERT(socketClass != NULL); eventClass = (*env)->FindClass(env, SSL_ALERT_EVENT_CLASS); PR_ASSERT(eventClass != NULL); eventConstructor = (*env)->GetMethodID(env, eventClass, "", "(L" SSLSOCKET_CLASS ";)V"); PR_ASSERT(eventConstructor != NULL); event = (*env)->NewObject(env, eventClass, eventConstructor, socket->socketObject); PR_ASSERT(event != NULL); /* event.setLevel(level); */ eventSetLevel = (*env)->GetMethodID(env, eventClass, "setLevel", "(I)V"); PR_ASSERT(eventSetLevel != NULL); (*env)->CallVoidMethod(env, event, eventSetLevel, (int)alert->level); /* event.setDescription(description); */ eventSetDescription = (*env)->GetMethodID(env, eventClass, "setDescription", "(I)V"); PR_ASSERT(eventSetDescription != NULL); (*env)->CallVoidMethod(env, event, eventSetDescription, alert->description); /* socket.fireAlertReceivedEvent(event); */ fireEvent = (*env)->GetMethodID(env, socketClass, "fireAlertReceivedEvent", "(L" SSL_ALERT_EVENT_CLASS ";)V"); PR_ASSERT(fireEvent != NULL); (*env)->CallVoidMethod(env, socket->socketObject, fireEvent, event); (*JSS_javaVM)->DetachCurrentThread(JSS_javaVM); } void JSSL_AlertSentCallback(const PRFileDesc *fd, void *arg, const SSLAlert *alert) { JSSL_SocketData *socket = (JSSL_SocketData*) arg; jint rc; JNIEnv *env; jclass socketClass, eventClass; jmethodID eventConstructor, eventSetLevel, eventSetDescription; jobject event; jmethodID fireEvent; PR_ASSERT(socket != NULL); PR_ASSERT(socket->socketObject != NULL); rc = (*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL); PR_ASSERT(rc == JNI_OK); PR_ASSERT(env != NULL); /* SSLAlertEvent event = new SSLAlertEvent(socket); */ socketClass = (*env)->FindClass(env, SSLSOCKET_CLASS); PR_ASSERT(socketClass != NULL); eventClass = (*env)->FindClass(env, SSL_ALERT_EVENT_CLASS); PR_ASSERT(eventClass != NULL); eventConstructor = (*env)->GetMethodID(env, eventClass, "", "(L" SSLSOCKET_CLASS ";)V"); PR_ASSERT(eventConstructor != NULL); event = (*env)->NewObject(env, eventClass, eventConstructor, socket->socketObject); PR_ASSERT(event != NULL); /* event.setLevel(level); */ eventSetLevel = (*env)->GetMethodID(env, eventClass, "setLevel", "(I)V"); PR_ASSERT(eventSetLevel != NULL); (*env)->CallVoidMethod(env, event, eventSetLevel, (int)alert->level); /* event.setDescription(description); */ eventSetDescription = (*env)->GetMethodID(env, eventClass, "setDescription", "(I)V"); PR_ASSERT(eventSetDescription != NULL); (*env)->CallVoidMethod(env, event, eventSetDescription, alert->description); /* socket.fireAlertSentEvent(event); */ fireEvent = (*env)->GetMethodID(env, socketClass, "fireAlertSentEvent", "(L" SSL_ALERT_EVENT_CLASS ";)V"); PR_ASSERT(fireEvent != NULL); (*env)->CallVoidMethod(env, socket->socketObject, fireEvent, event); (*JSS_javaVM)->DetachCurrentThread(JSS_javaVM); } void JSSL_HandshakeCallback(PRFileDesc *fd, void *arg) { JSSL_SocketData *sock = (JSSL_SocketData*) arg; jclass sockClass; jmethodID notifierID; JNIEnv *env; PR_ASSERT(sock!=NULL); /* get the JNI environment */ if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto finish; } PR_ASSERT(env != NULL); /* get the handshake notification method ID */ PR_ASSERT(sock->socketObject!=NULL); sockClass = (*env)->GetObjectClass(env, sock->socketObject); notifierID = (*env)->GetMethodID(env, sockClass, SSLSOCKET_HANDSHAKE_NOTIFIER_NAME, SSLSOCKET_HANDSHAKE_NOTIFIER_SIG); if(notifierID == NULL) goto finish; /* call the handshake notification method */ (*env)->CallVoidMethod(env, sock->socketObject, notifierID); finish: return; } /* * Callback from SSL for checking certificate the peer (other end of * the socket) presents. */ SECStatus JSSL_DefaultCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) { char * hostname = NULL; SECStatus rv = SECFailure; SECCertUsage certUsage; CERTCertificate *peerCert=NULL; certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; /* SSL_PeerCertificate() returns a shallow copy of the cert, so we must destroy it before we exit this function */ peerCert = SSL_PeerCertificate(fd); if (peerCert) { rv = CERT_VerifyCertNow(CERT_GetDefaultCertDB(), peerCert, checkSig, certUsage, NULL /*pinarg*/); } /* if we're a server, then we don't need to check the CN of the certificate, so we can just return whatever returncode we have now */ if ( rv != SECSuccess || isServer ) { if (peerCert) CERT_DestroyCertificate(peerCert); return (int)rv; } /* cert is OK. This is the client side of an SSL connection. * Now check the name field in the cert against the desired hostname. * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! */ hostname = SSL_RevealURL(fd); /* really is a hostname, not a URL */ if (hostname && hostname[0]) { rv = CERT_VerifyCertName(peerCert, hostname); PORT_Free(hostname); } else rv = SECFailure; if (peerCert) CERT_DestroyCertificate(peerCert); return rv; } static void addToVerifyLog(JNIEnv *env, CERTVerifyLog *log, CERTCertificate *cert, unsigned long error, unsigned int depth) { CERTVerifyLogNode *node, *tnode; PR_ASSERT(log != NULL); PL_ARENA_ALLOCATE(node, log->arena, sizeof(CERTVerifyLogNode)); if ( node == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); return; } node->cert = CERT_DupCertificate(cert); node->error = error; node->depth = depth; node->arg = NULL; if ( log->tail == NULL ) { /* empty list */ log->head = log->tail = node; node->prev = NULL; node->next = NULL; } else if ( depth >= log->tail->depth ) { /* add to tail */ node->prev = log->tail; log->tail->next = node; log->tail = node; node->next = NULL; } else if ( depth < log->head->depth ) { /* add at head */ node->prev = NULL; node->next = log->head; log->head->prev = node; log->head = node; } else { /* add in middle */ tnode = log->tail; while ( tnode != NULL ) { if ( depth >= tnode->depth ) { /* insert after tnode */ node->prev = tnode; node->next = tnode->next; tnode->next->prev = node; tnode->next = node; break; } tnode = tnode->prev; } } log->count++; } /* * Callback from SSL for checking a (possibly) expired * certificate the peer presents. * * obj - a jobject -> instance of a class implementing * the SSLCertificateApprovalCallback interface */ SECStatus JSSL_JavaCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) { CERTCertificate *peerCert=NULL; CERTVerifyLog log; JNIEnv *env; jobject validityStatus; jmethodID addReasonMethod; int certUsage; int checkcn_rv; jmethodID approveMethod; jboolean result; char *hostname=NULL; SECStatus retval = SECFailure; SECStatus verificationResult; PR_ASSERT(arg != NULL); PR_ASSERT(fd != NULL); /* initialize logging structures */ log.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if( log.arena == NULL ) return SECFailure; log.head = NULL; log.tail = NULL; log.count = 0; /* get the JNI environment */ if((*JSS_javaVM)->AttachCurrentThread(JSS_javaVM, (void**)&env, NULL) != 0){ PR_ASSERT(PR_FALSE); goto finish; } /* First, get a handle on the cert that the peer presented */ peerCert = SSL_PeerCertificate(fd); /* if peer didn't present a cert, why am I called? */ if (peerCert == NULL) goto finish; certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; /* * verify it against current time - (can't use * CERT_VerifyCertNow() since it doesn't allow passing of * logging parameter) */ verificationResult = CERT_VerifyCert( CERT_GetDefaultCertDB(), peerCert, checkSig, certUsage, PR_Now(), NULL /*pinarg*/, &log); if (verificationResult == SECSuccess && log.count > 0) { verificationResult = SECFailure; } /* * Verify the domain name of the cert. */ hostname = SSL_RevealURL(fd); /* really is a hostname, not a URL */ if (hostname && hostname[0]) { checkcn_rv = CERT_VerifyCertName(peerCert, hostname); PORT_Free(hostname); } else { checkcn_rv = SECFailure; } if (checkcn_rv != SECSuccess) { addToVerifyLog(env, &log,peerCert,SSL_ERROR_BAD_CERT_DOMAIN,0); if((*env)->ExceptionOccurred(env) != NULL) goto finish; verificationResult = SECFailure; } /* * create a new ValidityStatus object */ { jclass clazz; jmethodID cons; clazz = (*env)->FindClass(env, SSLCERT_APP_CB_VALIDITY_STATUS_CLASS); if( clazz == NULL ) goto finish; cons = (*env)->GetMethodID(env, clazz, PLAIN_CONSTRUCTOR, PLAIN_CONSTRUCTOR_SIG); if( cons == NULL ) goto finish; validityStatus = (*env)->NewObject(env, clazz, cons); if( validityStatus == NULL ) { goto finish; } /* get the addReason methodID while we're at it */ addReasonMethod = (*env)->GetMethodID(env, clazz, SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_NAME, SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_SIG); if( addReasonMethod == NULL ) { goto finish; } } /* * Load up the ValidityStatus object with all the reasons for failure */ if (verificationResult == SECFailure) { CERTVerifyLogNode *node; int error; CERTCertificate *errorcert=NULL; int depth; jobject ninjacert; node = log.head; while (node) { error = node->error; errorcert = node->cert; node->cert = NULL; depth = node->depth; ninjacert = JSS_PK11_wrapCert(env,&errorcert); (*env)->CallVoidMethod(env, validityStatus, addReasonMethod, error, ninjacert, depth ); node = node->next; } } /* * Call the approval callback */ { jobject approvalCallbackObj; jclass approvalCallbackClass; jobject peerninjacert; approvalCallbackObj = (jobject) arg; approvalCallbackClass = (*env)->GetObjectClass(env,approvalCallbackObj); approveMethod = (*env)->GetMethodID( env, approvalCallbackClass, SSLCERT_APP_CB_APPROVE_NAME, SSLCERT_APP_CB_APPROVE_SIG); if( approveMethod == NULL ) { PR_ASSERT(PR_FALSE); goto finish; } peerninjacert = JSS_PK11_wrapCert(env,&peerCert); if( peerninjacert == NULL) { PR_ASSERT(PR_FALSE); goto finish; } result = (*env)->CallBooleanMethod(env, approvalCallbackObj, approveMethod, peerninjacert, validityStatus); if( result == JNI_TRUE ) { retval = SECSuccess; } } finish: if( peerCert != NULL ) { CERT_DestroyCertificate(peerCert); } PORT_FreeArena(log.arena, PR_FALSE); return retval; } SECStatus JSSL_GetClientAuthData( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey) { SECKEYPrivateKey * privkey; JSSL_SocketData * sock; SECStatus rv = SECFailure; PR_ASSERT(arg != NULL); sock = (JSSL_SocketData*) arg; if (sock->clientCert) { privkey = PK11_FindPrivateKeyFromCert(sock->clientCertSlot, sock->clientCert, NULL /*pinarg*/); if ( privkey ) { rv = SECSuccess; *pRetCert = CERT_DupCertificate(sock->clientCert); *pRetKey = privkey; } } return rv; } /* * Callback from SSL for checking a (possibly) expired * certificate the peer presents. */ SECStatus JSSL_ConfirmExpiredPeerCert(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer) { SECStatus rv=SECFailure; SECCertUsage certUsage; CERTCertificate* peerCert=NULL; int64 notAfter, notBefore; certUsage = isServer ? certUsageSSLClient : certUsageSSLServer; peerCert = SSL_PeerCertificate(fd); if (peerCert) { rv = CERT_GetCertTimes(peerCert, ¬Before, ¬After); if (rv != SECSuccess) goto finish; /* * Verify the certificate based on it's expiry date. This should * always succeed, if the cert is trusted. It doesn't care if * the cert has expired. */ rv = CERT_VerifyCert(CERT_GetDefaultCertDB(), peerCert, checkSig, certUsage, notAfter, NULL /*pinarg*/, NULL /* log */); } if ( rv != SECSuccess ) goto finish; if( ! isServer ) { /* This is the client side of an SSL connection. * Now check the name field in the cert against the desired hostname. * NB: This is our only defense against Man-In-The-Middle (MITM) attacks! */ char* hostname = NULL; hostname = SSL_RevealURL(fd); /* really is a hostname, not a URL */ if (hostname && hostname[0]) { rv = CERT_VerifyCertName(peerCert, hostname); PORT_Free(hostname); } else { rv = SECFailure; } } finish: if (peerCert!=NULL) CERT_DestroyCertificate(peerCert); return rv; } jss-4.4.3/jss/org/mozilla/jss/ssl/common.c000066400000000000000000000631651326145000000204140ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include "_jni/org_mozilla_jss_ssl_SSLSocket.h" #include "jssl.h" #ifdef WIN32 #include #endif #define SSL_AF_INET 50 #define SSL_AF_INET6 51 void JSSL_throwSSLSocketException(JNIEnv *env, char *message) { const char *errStr; PRErrorCode nativeErrcode; char *msg = NULL; int msgLen; jclass excepClass; jmethodID excepCons; jobject excepObj; jstring msgString; jint VARIABLE_MAY_NOT_BE_USED result; /* * get the error code and error string */ nativeErrcode = PR_GetError(); errStr = JSS_strerror(nativeErrcode); if( errStr == NULL ) { errStr = "Unknown error"; } /* * construct the message */ msgLen = strlen(message) + strlen(errStr) + 40; msg = PR_Malloc(msgLen); if( msg == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } PR_snprintf(msg, msgLen, "%s: (%ld) %s", message, nativeErrcode, errStr); /* * turn the message into a Java string */ msgString = (*env)->NewStringUTF(env, msg); if( msgString == NULL ) goto finish; /* * Create the exception object. Use java.net.SocketTimeoutException * for timeouts, org.mozilla.jss.ssl.SSLSocketException for everything * else. */ switch (nativeErrcode) { case PR_PENDING_INTERRUPT_ERROR : excepClass = (*env)->FindClass(env, INTERRUPTED_IO_EXCEPTION); break; case PR_IO_ERROR : excepClass = (*env)->FindClass(env, IO_EXCEPTION); break; case PR_IO_TIMEOUT_ERROR : case PR_CONNECT_TIMEOUT_ERROR : excepClass = (*env)->FindClass(env, SOCKET_TIMEOUT_EXCEPTION); break; default : /* for all other PR_ERRORs throw SocketException */ excepClass = (*env)->FindClass(env, SSLSOCKET_EXCEPTION); break; } PR_ASSERT(excepClass != NULL); if( excepClass == NULL ) goto finish; excepCons = (*env)->GetMethodID(env, excepClass, "", "(Ljava/lang/String;)V"); PR_ASSERT( excepCons != NULL ); if( excepCons == NULL ) goto finish; excepObj = (*env)->NewObject(env, excepClass, excepCons, msgString); PR_ASSERT(excepObj != NULL); if( excepObj == NULL ) goto finish; /* * throw the exception */ result = (*env)->Throw(env, excepObj); PR_ASSERT(result == 0); finish: if( msg != NULL ) { PR_Free(msg); } } /* * This is done for regular sockets that we connect() and server sockets, * but not for sockets that come from accept. */ JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SocketBase_socketCreate(JNIEnv *env, jobject self, jobject sockObj, jobject certApprovalCallback, jobject clientCertSelectionCallback, jobject javaSock, jstring host,jint family) { jbyteArray sdArray = NULL; JSSL_SocketData *sockdata = NULL; SECStatus status; PRFileDesc *newFD = NULL; PRFileDesc *tmpFD = NULL; PRFilePrivate *priv = NULL; int socketFamily = 0; if (family != SSL_AF_INET6 && family != SSL_AF_INET) { JSSL_throwSSLSocketException(env, "socketCreate() Invalid family!"); goto finish; } if( family == SSL_AF_INET) socketFamily = PR_AF_INET; else socketFamily = PR_AF_INET6; if( javaSock == NULL ) { /* create a TCP socket */ newFD = PR_OpenTCPSocket(socketFamily); if( newFD == NULL ) { JSSL_throwSSLSocketException(env, "PR_NewTCPSocket() returned NULL"); goto finish; } } else { newFD = JSS_SSL_javasockToPRFD(env, javaSock); if( newFD == NULL ) { JSS_throwMsg(env, SOCKET_EXCEPTION, "failed to construct NSPR wrapper around java socket"); goto finish; } priv = newFD->secret; } /* enable SSL on the socket */ tmpFD = SSL_ImportFD(NULL, newFD); if( tmpFD == NULL ) { JSSL_throwSSLSocketException(env, "SSL_ImportFD() returned NULL"); goto finish; } newFD = tmpFD; sockdata = JSSL_CreateSocketData(env, sockObj, newFD, priv); if( sockdata == NULL ) { goto finish; } newFD = NULL; if( host != NULL ) { const char *chars; int retval; PR_ASSERT( javaSock != NULL ); chars = (*env)->GetStringUTFChars(env, host, NULL); retval = SSL_SetURL(sockdata->fd, chars); (*env)->ReleaseStringUTFChars(env, host, chars); if( retval ) { JSSL_throwSSLSocketException(env, "Failed to set SSL domain name"); goto finish; } } status = SSL_OptionSet(sockdata->fd, SSL_SECURITY, PR_TRUE); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to enable SSL security on socket"); goto finish; } /* setup the handshake callback */ status = SSL_HandshakeCallback(sockdata->fd, JSSL_HandshakeCallback, sockdata); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install handshake callback"); goto finish; } /* setup the cert authentication callback */ if( certApprovalCallback != NULL ) { /* create global reference to the callback object */ sockdata->certApprovalCallback = (*env)->NewGlobalRef(env, certApprovalCallback); if( sockdata->certApprovalCallback == NULL ) goto finish; /* install the Java callback */ status = SSL_AuthCertificateHook( sockdata->fd, JSSL_JavaCertAuthCallback, (void*) sockdata->certApprovalCallback); } else { /* install the default callback */ status = SSL_AuthCertificateHook( sockdata->fd, JSSL_DefaultCertAuthCallback, NULL); } if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install certificate authentication callback"); goto finish; } /* setup the client cert selection callback */ if( clientCertSelectionCallback != NULL ) { /* create a new global ref */ sockdata->clientCertSelectionCallback = (*env)->NewGlobalRef(env, clientCertSelectionCallback); if(sockdata->clientCertSelectionCallback == NULL) goto finish; /* install the Java callback */ status = SSL_GetClientAuthDataHook( sockdata->fd, JSSL_CallCertSelectionCallback, (void*) sockdata->clientCertSelectionCallback); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Unable to install client certificate selection callback"); goto finish; } } /* pass the pointer back to Java */ sdArray = JSS_ptrToByteArray(env, (void*) sockdata); if( sdArray == NULL ) { /* exception was thrown */ goto finish; } finish: if( (*env)->ExceptionOccurred(env) != NULL ) { if( sockdata != NULL ) { JSSL_DestroySocketData(env, sockdata); } if( newFD != NULL ) { PR_Close(newFD); } } else { PR_ASSERT( sdArray != NULL ); } return sdArray; } JSSL_SocketData* JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD, PRFilePrivate *priv) { SECStatus status; JSSL_SocketData *sockdata = NULL; /* make a JSSL_SocketData structure */ sockdata = PR_Malloc( sizeof(JSSL_SocketData) ); if( sockdata == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } sockdata->fd = newFD; sockdata->socketObject = NULL; sockdata->certApprovalCallback = NULL; sockdata->clientCertSelectionCallback = NULL; sockdata->clientCert = NULL; sockdata->clientCertSlot = NULL; sockdata->jsockPriv = priv; sockdata->lock = NULL; sockdata->reader = NULL; sockdata->writer = NULL; sockdata->accepter = NULL; sockdata->closePending = PR_FALSE; sockdata->lock = PR_NewLock(); if( sockdata->lock == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* * Make a global ref to the socket. Since it is a weak reference, it will * get garbage collected if this is the only reference that remains. * We do this so that sockets will get closed when they go out of scope * in the Java layer. */ sockdata->socketObject = NEW_WEAK_GLOBAL_REF(env, sockObj); if( sockdata->socketObject == NULL ) goto finish; /* registering alert received callback */ status = SSL_AlertReceivedCallback(sockdata->fd, JSSL_AlertReceivedCallback, sockdata); if (status != SECSuccess) { JSSL_throwSSLSocketException(env, "Unable to install alert received callback"); goto finish; } /* registering alert sent callback */ status = SSL_AlertSentCallback(sockdata->fd, JSSL_AlertSentCallback, sockdata); if (status != SECSuccess) { JSSL_throwSSLSocketException(env, "Unable to install alert sent callback"); goto finish; } finish: if( (*env)->ExceptionOccurred(env) != NULL ) { if( sockdata != NULL ) { JSSL_DestroySocketData(env, sockdata); sockdata = NULL; } } return sockdata; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketProxy_releaseNativeResources (JNIEnv *env, jobject this) { /* SSLSocket.close and SSLServerSocket.close call */ /* SocketBase.close to destroy all native Resources */ /* attached to the socket. There is no native resource */ /* to release after close has been called. This method */ /* remains because SocketProxy extends org.mozilla.jss.util.NativeProxy*/ /* which defines releaseNativeResources as abstract and */ /* therefore must be implemented by SocketProxy */ } void JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd) { PR_ASSERT(sd != NULL); PR_Close(sd->fd); if( sd->socketObject != NULL ) { DELETE_WEAK_GLOBAL_REF(env, sd->socketObject ); } if( sd->certApprovalCallback != NULL ) { (*env)->DeleteGlobalRef(env, sd->certApprovalCallback); } if( sd->clientCertSelectionCallback != NULL ) { (*env)->DeleteGlobalRef(env, sd->clientCertSelectionCallback); } if( sd->clientCert != NULL ) { CERT_DestroyCertificate(sd->clientCert); } if( sd->clientCertSlot != NULL ) { PK11_FreeSlot(sd->clientCertSlot); } if( sd->lock != NULL ) { PR_DestroyLock(sd->lock); } PR_Free(sd); } /* * These must match up with the constants defined in SocketBase.java. * Note to developer these constants are not all related! i.e. you cannot * pass in PR_SHUTDOWN_RCV to setSSLOption etc! Check their usage * in NSS and NSPR before using. */ PRInt32 JSSL_enums[] = { SSL_ENABLE_SSL2, /* 0 */ /* ssl.h */ SSL_ENABLE_SSL3, /* 1 */ /* ssl.h */ SSL_ENABLE_TLS, /* 2 */ /* ssl.h */ PR_SockOpt_NoDelay, /* 3 */ /* prio.h */ PR_SockOpt_Keepalive, /* 4 */ /* prio.h */ PR_SHUTDOWN_RCV, /* 5 */ /* prio.h */ PR_SHUTDOWN_SEND, /* 6 */ /* prio.h */ SSL_REQUIRE_CERTIFICATE, /* 7 */ /* ssl.h */ SSL_REQUEST_CERTIFICATE, /* 8 */ /* ssl.h */ SSL_NO_CACHE, /* 9 */ /* ssl.h */ SSL_POLICY_DOMESTIC, /* 10 */ /* ssl.h */ SSL_POLICY_EXPORT, /* 11 */ /* ssl.h */ SSL_POLICY_FRANCE, /* 12 */ /* ssl.h */ SSL_ROLLBACK_DETECTION, /* 13 */ /* ssl.h */ SSL_NO_STEP_DOWN, /* 14 */ /* ssl.h */ SSL_ENABLE_FDX, /* 15 */ /* ssl.h */ SSL_V2_COMPATIBLE_HELLO, /* 16 */ /* ssl.h */ SSL_REQUIRE_NEVER, /* 17 */ /* ssl.h */ SSL_REQUIRE_ALWAYS, /* 18 */ /* ssl.h */ SSL_REQUIRE_FIRST_HANDSHAKE,/* 19 */ /* ssl.h */ SSL_REQUIRE_NO_ERROR, /* 20 */ /* ssl.h */ SSL_ENABLE_SESSION_TICKETS, /* 21 */ /* ssl.h */ SSL_ENABLE_RENEGOTIATION, /* 22 */ /* ssl.h */ SSL_RENEGOTIATE_NEVER, /* 23 */ /* ssl.h */ SSL_RENEGOTIATE_UNRESTRICTED, /* 24 */ /* ssl.h */ SSL_RENEGOTIATE_REQUIRES_XTN, /* 25 */ /* ssl.h */ SSL_RENEGOTIATE_TRANSITIONAL, /* 26 */ /* ssl.h */ SSL_REQUIRE_SAFE_NEGOTIATION, /* 27 */ /* ssl.h */ SSL_LIBRARY_VERSION_2, /* 28 */ /* sslproto.h */ SSL_LIBRARY_VERSION_3_0, /* 29 */ /* sslproto.h */ SSL_LIBRARY_VERSION_TLS_1_0, /* 30 */ /* sslproto.h */ SSL_LIBRARY_VERSION_TLS_1_1, /* 31 */ /* sslproto.h */ SSL_LIBRARY_VERSION_TLS_1_2, /* 32 */ /* sslproto.h */ ssl_variant_stream, /* 33 */ /* sslt.h */ ssl_variant_datagram, /* 34 */ /* sslt.h */ 0 }; JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_socketBind (JNIEnv *env, jobject self, jbyteArray addrBA, jint port) { JSSL_SocketData *sock; PRNetAddr addr; jbyte *addrBAelems = NULL; int addrBALen = 0; PRStatus status; jmethodID supportsIPV6ID; jclass socketBaseClass; jboolean supportsIPV6 = 0; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ goto finish; } /* * setup the PRNetAddr structure */ /* * Do we support IPV6? */ socketBaseClass = (*env)->FindClass(env, SOCKET_BASE_NAME); if( socketBaseClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6ID = (*env)->GetStaticMethodID(env, socketBaseClass, SUPPORTS_IPV6_NAME, SUPPORTS_IPV6_SIG); if( supportsIPV6ID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } supportsIPV6 = (*env)->CallStaticBooleanMethod(env, socketBaseClass, supportsIPV6ID); memset( &addr, 0, sizeof( PRNetAddr )); if( addrBA != NULL ) { addrBAelems = (*env)->GetByteArrayElements(env, addrBA, NULL); addrBALen = (*env)->GetArrayLength(env, addrBA); if( addrBAelems == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if(addrBALen != 4 && addrBALen != 16) { JSS_throwMsgPrErr(env, BIND_EXCEPTION, "Invalid address in bind!"); goto finish; } if( addrBALen == 4) { addr.inet.family = PR_AF_INET; addr.inet.port = PR_htons(port); memcpy(&addr.inet.ip, addrBAelems, 4); if(supportsIPV6) { addr.inet.family = PR_AF_INET6; addr.ipv6.port = PR_htons(port); PR_ConvertIPv4AddrToIPv6(addr.inet.ip,&addr.ipv6.ip); } } else { /* Must be 16 and ipv6 */ if(supportsIPV6) { addr.ipv6.family = PR_AF_INET6; addr.ipv6.port = PR_htons(port); memcpy(&addr.ipv6.ip,addrBAelems, 16); } else { JSS_throwMsgPrErr(env, BIND_EXCEPTION, "Invalid address in bind!"); goto finish; } } } else { if(supportsIPV6) { status = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET6, port, &addr); } else { status = PR_SetNetAddr(PR_IpAddrAny, PR_AF_INET, port, &addr); } } /* do the bind() call */ status = PR_Bind(sock->fd, &addr); if( status != PR_SUCCESS ) { JSS_throwMsgPrErr(env, BIND_EXCEPTION, "Could not bind to address"); goto finish; } finish: if( addrBAelems != NULL ) { (*env)->ReleaseByteArrayElements(env, addrBA, addrBAelems, JNI_ABORT); } } /* * SSLServerSocket and SSLSocket have their own synchronization * that protects SocketBase.socketClose. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_socketClose(JNIEnv *env, jobject self) { JSSL_SocketData *sock = NULL; /* get the FD */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) { /* exception was thrown */ return; } JSSL_DestroySocketData(env, sock); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_requestClientAuthNoExpiryCheckNative (JNIEnv *env, jobject self, jboolean b) { JSSL_SocketData *sock = NULL; SECStatus status; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; /* * Set the option on the socket */ status = SSL_OptionSet(sock->fd, SSL_REQUEST_CERTIFICATE, b); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Failed to set REQUEST_CERTIFICATE option on socket"); goto finish; } if(b) { /* * Set the callback function */ status = SSL_AuthCertificateHook(sock->fd, JSSL_ConfirmExpiredPeerCert, NULL /*cx*/); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "Failed to set certificate authentication callback"); goto finish; } } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setSSLOption (JNIEnv *env, jobject self, jint option, jint on) { SECStatus status; JSSL_SocketData *sock = NULL; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the option */ status = SSL_OptionSet(sock->fd, JSSL_enums[option], on); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setSSLOptionMode (JNIEnv *env, jobject self, jint option, jint mode) { SECStatus status; JSSL_SocketData *sock = NULL; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* set the option */ status = SSL_OptionSet(sock->fd, JSSL_enums[option], JSSL_enums[mode]); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionSet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return; } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getSSLOption(JNIEnv *env, jobject self, jint option) { JSSL_SocketData *sock = NULL; SECStatus status = SECSuccess; PRBool bOption = PR_FALSE; if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* get the option */ status = SSL_OptionGet(sock->fd, JSSL_enums[option], &bOption); if( status != SECSuccess ) { JSSL_throwSSLSocketException(env, "SSL_OptionGet failed"); goto finish; } finish: EXCEPTION_CHECK(env, sock) return bOption; } PRStatus JSSL_getSockAddr (JNIEnv *env, jobject self, PRNetAddr *addr, LocalOrPeer localOrPeer) { JSSL_SocketData *sock = NULL; PRStatus status=PR_FAILURE; /* get my fd */ if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) { goto finish; } /* get the port */ if( localOrPeer == LOCAL_SOCK ) { status = PR_GetSockName(sock->fd, addr); } else { PR_ASSERT( localOrPeer == PEER_SOCK ); status = PR_GetPeerName(sock->fd, addr); } if( status != PR_SUCCESS ) { JSSL_throwSSLSocketException(env, "PR_GetSockName failed"); } finish: EXCEPTION_CHECK(env, sock) return status; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressByteArrayNative (JNIEnv *env, jobject self) { jbyteArray byteArray=NULL; PRNetAddr addr; jbyte *address=NULL; int size=4; if( JSSL_getSockAddr(env, self, &addr, PEER_SOCK) != PR_SUCCESS) { goto finish; } if( PR_NetAddrFamily(&addr) == PR_AF_INET6) { size = 16; address = (jbyte *) &addr.ipv6.ip; } else { address = (jbyte *) &addr.inet.ip; } byteArray = (*env)->NewByteArray(env,size); if(byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, byteArray, 0,size ,address); if( (*env)->ExceptionOccurred(env) != NULL) { PR_ASSERT(PR_FALSE); goto finish; } finish: return byteArray; } JNIEXPORT jbyteArray JNICALL Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressByteArrayNative (JNIEnv *env, jobject self) { jbyteArray byteArray=NULL; PRNetAddr addr; jbyte *address=NULL; int size=4; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) != PR_SUCCESS) { goto finish; } if( PR_NetAddrFamily(&addr) == PR_AF_INET6) { size = 16; address = (jbyte *) &addr.ipv6.ip; } else { address = (jbyte *) &addr.inet.ip; } byteArray = (*env)->NewByteArray(env,size); if(byteArray == NULL) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, byteArray, 0,size,address); if( (*env)->ExceptionOccurred(env) != NULL) { PR_ASSERT(PR_FALSE); goto finish; } finish: return byteArray; } /* Leave the original versions of these functions for compatibility */ JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getPeerAddressNative (JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, PEER_SOCK) == PR_SUCCESS) { return ntohl(addr.inet.ip); } else { return 0; } } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getLocalAddressNative(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) == PR_SUCCESS ) { return ntohl(addr.inet.ip); } else { return 0; } } JNIEXPORT jint JNICALL Java_org_mozilla_jss_ssl_SocketBase_getLocalPortNative(JNIEnv *env, jobject self) { PRNetAddr addr; if( JSSL_getSockAddr(env, self, &addr, LOCAL_SOCK) == PR_SUCCESS ) { return ntohs(addr.inet.port); } else { return 0; } } /* * This is here for backwards binary compatibility: I didn't want to remove * the symbol from the DLL. This would only get called if someone were using * a pre-3.2 version of the JSS classes with this post-3.2 library. Using * different versions of the classes and the C code is not supported. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setClientCertNicknameNative( JNIEnv *env, jobject self, jstring nick) { PR_ASSERT(0); JSS_throwMsg(env, SOCKET_EXCEPTION, "JSS JAR/DLL mismatch"); } JNIEXPORT void JNICALL Java_org_mozilla_jss_ssl_SocketBase_setClientCert( JNIEnv *env, jobject self, jobject certObj) { JSSL_SocketData *sock = NULL; SECStatus status; CERTCertificate *cert = NULL; PK11SlotInfo *slot = NULL; if( certObj == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); goto finish; } if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish; /* * Store the cert and slot in the SocketData. */ if( JSS_PK11_getCertPtr(env, certObj, &cert) != PR_SUCCESS ) { goto finish; } if( JSS_PK11_getCertSlotPtr(env, certObj, &slot) != PR_SUCCESS ) { goto finish; } if( sock->clientCert != NULL ) { CERT_DestroyCertificate(sock->clientCert); } if( sock->clientCertSlot != NULL ) { PK11_FreeSlot(sock->clientCertSlot); } sock->clientCert = CERT_DupCertificate(cert); sock->clientCertSlot = PK11_ReferenceSlot(slot); /* * Install the callback. */ status = SSL_GetClientAuthDataHook(sock->fd, JSSL_GetClientAuthData, (void*)sock); if(status != SECSuccess) { JSSL_throwSSLSocketException(env, "Unable to set client auth data hook"); goto finish; } finish: EXCEPTION_CHECK(env, sock) } void JSS_SSL_processExceptions(JNIEnv *env, PRFilePrivate *priv) { jthrowable currentExcep; if( priv == NULL ) { return; } currentExcep = (*env)->ExceptionOccurred(env); (*env)->ExceptionClear(env); if( currentExcep != NULL ) { jmethodID processExcepsID; jclass socketBaseClass; jthrowable newException; socketBaseClass = (*env)->FindClass(env, SOCKET_BASE_NAME); if( socketBaseClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } processExcepsID = (*env)->GetStaticMethodID(env, socketBaseClass, PROCESS_EXCEPTIONS_NAME, PROCESS_EXCEPTIONS_SIG); if( processExcepsID == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } newException = (*env)->CallStaticObjectMethod(env, socketBaseClass, processExcepsID, currentExcep, JSS_SSL_getException(priv)); if( newException == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } currentExcep = newException; } else { jthrowable excep = JSS_SSL_getException(priv); PR_ASSERT( excep == NULL ); if( excep != NULL ) { (*env)->DeleteGlobalRef(env, excep); } } finish: if( currentExcep != NULL && (*env)->ExceptionOccurred(env) == NULL) { int VARIABLE_MAY_NOT_BE_USED ret = (*env)->Throw(env, currentExcep); PR_ASSERT(ret == 0); } } jss-4.4.3/jss/org/mozilla/jss/ssl/config.mk000066400000000000000000000010361326145000000205430ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # Adjust specific variables for specific platforms # ####################################################################### ifeq ($(OS_ARCH), HP-UX) DEFINES += -D_ILP32 endif TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/ssl/javasock.c000066400000000000000000000624771326145000000207320ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include #include #include #include #include #include static PRIntn invalidInt() { PR_ASSERT(!"invalidInt called"); return -1; } struct PRFilePrivate { JavaVM *javaVM; jobject sockGlobalRef; jthrowable exception; PRIntervalTime timeout; }; /* * exception should be a global ref */ void setException(JNIEnv *env, PRFilePrivate *priv, jthrowable excep) { PR_ASSERT(priv->exception == NULL); if( priv->exception != NULL) { (*env)->DeleteGlobalRef(env, priv->exception); } priv->exception = excep; } jthrowable JSS_SSL_getException(PRFilePrivate *priv) { jobject retval = priv->exception; priv->exception = NULL; return retval; } #define GET_ENV(vm, env) \ ( ((*(vm))->AttachCurrentThread((vm), (void**)&(env), NULL) == 0) ? 0 : 1 ) static PRInt32 writebuf(JNIEnv *env, PRFileDesc *fd, jobject sockObj, jbyteArray byteArray) { jmethodID getOutputStream, writeMethod; jclass sockClass, osClass; jobject outputStream; jint arrayLen=-1; PRInt32 retval; if( env == NULL ) { goto finish; } /* * get the OutputStream */ sockClass = (*env)->GetObjectClass(env, sockObj); PR_ASSERT(sockClass != NULL); getOutputStream = (*env)->GetMethodID(env, sockClass, SOCKET_GET_OUTPUT_STREAM_NAME, SOCKET_GET_OUTPUT_STREAM_SIG); if(getOutputStream == NULL) { ASSERT_OUTOFMEM(env); goto finish; } outputStream = (*env)->CallObjectMethod(env, sockObj, getOutputStream); if( outputStream == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* * get OutputStream.write */ osClass = (*env)->GetObjectClass(env, outputStream); writeMethod = (*env)->GetMethodID(env, osClass, OSTREAM_WRITE_NAME, OSTREAM_WRITE_SIG); if( writeMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } arrayLen = (*env)->GetArrayLength(env, byteArray); /* * Write bytes */ (*env)->CallVoidMethod(env, outputStream, writeMethod, byteArray, 0, arrayLen); /* this may have thrown an IO Exception */ finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } else { retval = arrayLen; } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus processTimeout(JNIEnv *env, PRFileDesc *fd, jobject sockObj, PRIntervalTime timeout) { jclass socketClass; jmethodID setSoTimeoutMethod; jint javaTimeout; if( timeout == fd->secret->timeout ) { /* no need to change it */ goto finish; } /* * Call setSoTimeout on the Java socket */ socketClass = (*env)->GetObjectClass(env, sockObj); if( socketClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } setSoTimeoutMethod = (*env)->GetMethodID(env, socketClass, SET_SO_TIMEOUT_NAME, SET_SO_TIMEOUT_SIG); if( setSoTimeoutMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if( timeout == PR_INTERVAL_NO_TIMEOUT ) { javaTimeout = 0; /* 0 means no timeout in Java */ } else if( timeout == PR_INTERVAL_NO_WAIT ) { PR_ASSERT(!"PR_INTERVAL_NO_WAIT not supported"); javaTimeout = 1; /* approximate with 1ms wait */ } else { javaTimeout = PR_IntervalToMilliseconds(timeout); } (*env)->CallVoidMethod(env, sockObj, setSoTimeoutMethod, javaTimeout); /* This may have thrown an exception */ fd->secret->timeout = timeout; finish: if( (*env)->ExceptionOccurred(env) ) { return PR_FAILURE; } else { return PR_SUCCESS; } } static PRInt32 jsock_write(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout) { jobject sockObj; JNIEnv *env; jbyteArray outbufArray; PRInt32 retval=-1; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); if( processTimeout(env, fd, sockObj, timeout) != PR_SUCCESS ) goto finish; /* * convert iov to java byte array */ { int iovi; jbyte *bytes; int outbufLen; for( iovi = 0, outbufLen = 0; iovi < iov_size; ++iovi) { outbufLen += iov[iovi].iov_len; } PR_ASSERT(outbufLen >= 0); outbufArray = (*env)->NewByteArray(env, outbufLen); if( outbufArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } bytes = (*env)->GetByteArrayElements(env, outbufArray, NULL); if( bytes == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } for( iovi = 0, outbufLen = 0; iovi < iov_size; ++iovi) { memcpy(bytes+outbufLen,iov[iovi].iov_base, iov[iovi].iov_len); outbufLen += iov[iovi].iov_len; } PR_ASSERT(outbufLen == (*env)->GetArrayLength(env, outbufArray)); (*env)->ReleaseByteArrayElements(env, outbufArray, bytes, 0); } /* * Write bytes */ retval = writebuf(env, fd, sockObj, outbufArray); finish: /* nothing to free, nothing to return */ if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } typedef enum { LOCAL_NAME, PEER_NAME } LocalOrPeer; static PRStatus getInetAddress(PRFileDesc *fd, PRNetAddr *addr, LocalOrPeer localOrPeer) { PRStatus status = PR_FAILURE; jobject sockObj; JNIEnv *env; jobject inetAddress; jbyteArray addrByteArray; jint port; int addrBALen = 0; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); /* * get the InetAddress and port */ { jclass sockClass = (*env)->GetObjectClass(env, sockObj); jmethodID getInetAddrMethod; jmethodID getPortMethod; const char *getAddrMethodName; const char *getPortMethodName; if( localOrPeer == LOCAL_NAME ) { getAddrMethodName = GET_LOCAL_ADDR_NAME; getPortMethodName = GET_LOCAL_PORT_NAME; } else { PR_ASSERT(localOrPeer == PEER_NAME); getAddrMethodName = GET_INET_ADDR_NAME; getPortMethodName = GET_PORT_NAME; } PR_ASSERT( sockClass != NULL ); getInetAddrMethod = (*env)->GetMethodID(env, sockClass, getAddrMethodName, GET_INET_ADDR_SIG); if( getInetAddrMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } inetAddress = (*env)->CallObjectMethod(env, sockObj, getInetAddrMethod); if( inetAddress == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } if( (*env)->ExceptionOccurred(env) ) goto finish; getPortMethod = (*env)->GetMethodID(env, sockClass, getPortMethodName, GET_PORT_SIG); if( getPortMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } port = (*env)->CallIntMethod(env, sockObj, getPortMethod); if( (*env)->ExceptionOccurred(env) ) goto finish; } /* * get the address as a byte array */ { jclass inetAddrClass = (*env)->GetObjectClass(env, inetAddress); jmethodID getAddressMethod; PR_ASSERT(inetAddrClass != NULL); getAddressMethod = (*env)->GetMethodID(env, inetAddrClass, GET_ADDR_NAME, GET_ADDR_SIG); if( getAddressMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } addrByteArray = (*env)->CallObjectMethod(env, inetAddress, getAddressMethod); if( addrByteArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } } /* * convert to a PRNetAddr */ { jbyte *addrBytes; memset(addr, 0, sizeof(PRNetAddr)); addrBALen = (*env)->GetArrayLength(env, addrByteArray); PR_ASSERT( (addrBALen == 4) || (addrBALen == 16 ) ); /* make sure you release them later */ addrBytes = (*env)->GetByteArrayElements(env, addrByteArray, NULL); if( addrBytes == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* ip field is in network byte order */ if (addrBALen == 4) { memcpy( (void*) &addr->inet.ip, addrBytes, 4); addr->inet.family = PR_AF_INET; addr->inet.port = port; } else { memcpy( (void*) &addr->ipv6.ip,addrBytes, 16); addr->inet.family = PR_AF_INET6; addr->inet.port = port; } (*env)->ReleaseByteArrayElements(env, addrByteArray, addrBytes, JNI_ABORT); } status = PR_SUCCESS; finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); status = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { status = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return status; } static PRStatus jsock_getPeerName(PRFileDesc *fd, PRNetAddr *addr) { return getInetAddress(fd, addr, PEER_NAME); } static PRStatus jsock_getSockName(PRFileDesc *fd, PRNetAddr *addr) { return getInetAddress(fd, addr, LOCAL_NAME); } static PRInt32 jsock_send(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { JNIEnv *env; jobject sockObj; jbyteArray byteArray; PRInt32 retval = -1;; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); if( processTimeout(env, fd, sockObj, timeout) != PR_SUCCESS ) goto finish; /* * Turn buf into byte array */ { jbyte *bytes; byteArray = (*env)->NewByteArray(env, amount); if( byteArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } bytes = (*env)->GetByteArrayElements(env, byteArray, NULL); if( bytes == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } memcpy(bytes, buf, amount); (*env)->ReleaseByteArrayElements(env, byteArray, bytes, 0); } retval = writebuf(env, fd, sockObj, byteArray); finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRInt32 jsock_recv(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, PRIntervalTime timeout) { PRInt32 retval=-1; JNIEnv *env; jobject sockObj; jbyteArray byteArray; jobject inputStream; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); if( processTimeout(env, fd, sockObj, timeout) != PR_SUCCESS ) goto finish; /* * get InputStream */ { jclass sockClass = (*env)->GetObjectClass(env, sockObj); jmethodID getInputStreamMethod; if( sockClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } getInputStreamMethod = (*env)->GetMethodID(env, sockClass, SOCKET_GET_INPUT_STREAM_NAME, SOCKET_GET_INPUT_STREAM_SIG); if( getInputStreamMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } inputStream = (*env)->CallObjectMethod(env, sockObj, getInputStreamMethod); if( inputStream == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } } /* create new, empty byte array */ byteArray = (*env)->NewByteArray(env, amount); if( byteArray == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* * call read() */ { jclass isClass = (*env)->GetObjectClass(env, inputStream); jmethodID readMethod; if( isClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } readMethod = (*env)->GetMethodID(env, isClass, ISTREAM_READ_NAME, ISTREAM_READ_SIG); if( readMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } retval = (*env)->CallIntMethod(env, inputStream, readMethod, byteArray); if( (*env)->ExceptionOccurred(env) ) { goto finish; } else if( retval == -1 ) { /* Java EOF == -1, NSPR EOF == 0 */ retval = 0; } else if( retval == 0 ) { /* timeout */ PR_ASSERT( fd->secret->timeout != PR_INTERVAL_NO_TIMEOUT ); PR_SetError(PR_IO_TIMEOUT_ERROR, 0); retval = -1; } PR_ASSERT(retval <= amount); } /* * copy byte array to buf */ if( retval > 0 ) { jbyte *bytes; bytes = (*env)->GetByteArrayElements(env, byteArray, NULL); memcpy(buf, bytes, retval); (*env)->ReleaseByteArrayElements(env, byteArray, bytes, JNI_ABORT); } finish: if( env ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, excep); (*env)->ExceptionClear(env); retval = -1; PR_SetError(PR_IO_ERROR, 0); } } else { retval = -1; PR_SetError(PR_IO_ERROR, 0); } return retval; } static jboolean getBooleanProperty(JNIEnv *env, jobject sock, const char* methodName) { jclass sockClass; jmethodID method; jboolean retval = JNI_FALSE; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "()Z"); if( method == NULL ) goto finish; retval = (*env)->CallBooleanMethod(env, sock, method); finish: return retval; } static jint getIntProperty(JNIEnv *env, jobject sock, const char* methodName) { jclass sockClass; jmethodID method; jint retval=0; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "()I"); if( method == NULL ) goto finish; retval = (*env)->CallIntMethod(env, sock, method); finish: return retval; } static void setBooleanProperty(JNIEnv *env, jobject sock, const char* methodName, jboolean value) { jclass sockClass; jmethodID method; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "(Z)V"); if( method == NULL ) goto finish; (*env)->CallVoidMethod(env, sock, method, value); finish: return; } static void setIntProperty(JNIEnv *env, jobject sock, const char* methodName, jint value) { jclass sockClass; jmethodID method; sockClass = (*env)->GetObjectClass(env, sock); if( sockClass == NULL ) goto finish; method = (*env)->GetMethodID(env, sockClass, methodName, "(I)V"); if( method == NULL ) goto finish; (*env)->CallVoidMethod(env, sock, method, value); finish: return; } static void getSoLinger(JNIEnv *env, jobject sock, PRLinger *linger) { jint lingSecs; lingSecs = getIntProperty(env, sock, "getSoLinger"); if( (*env)->ExceptionOccurred(env) ) goto finish; if( lingSecs == -1 ) { linger->polarity = PR_FALSE; } else { linger->polarity = PR_TRUE; linger->linger = PR_SecondsToInterval(lingSecs); } finish: return; } static void setSoLinger(JNIEnv *env, jobject sock, PRLinger *linger) { jint lingSecs; jclass clazz; jmethodID methodID; jboolean onoff; if( linger->polarity == PR_FALSE ) { onoff = JNI_FALSE; lingSecs = 0; /* this should be ignored */ } else { onoff = JNI_TRUE; lingSecs = PR_IntervalToSeconds(linger->linger); } clazz = (*env)->GetObjectClass(env, sock); if( clazz == NULL ) goto finish; methodID = (*env)->GetMethodID(env, clazz, "setSoLinger", "(ZI)V"); if( methodID == NULL) goto finish; (*env)->CallVoidMethod(env, sock, methodID, onoff, lingSecs); finish: return; } static PRStatus jsock_getSockOpt(PRFileDesc *fd, PRSocketOptionData *data) { PRStatus retval = PR_SUCCESS; JNIEnv *env; jobject sockObj; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); switch(data->option) { case PR_SockOpt_Nonblocking: data->value.non_blocking = PR_FALSE; break; case PR_SockOpt_Keepalive: data->value.keep_alive = getBooleanProperty(env, sockObj, "getKeepAlive") == JNI_TRUE ? PR_TRUE : PR_FALSE; break; case PR_SockOpt_RecvBufferSize: data->value.send_buffer_size = getIntProperty(env, sockObj, "getReceiveBufferSize"); break; case PR_SockOpt_SendBufferSize: data->value.recv_buffer_size = getIntProperty(env, sockObj, "getSendBufferSize"); break; case PR_SockOpt_Linger: getSoLinger( env, sockObj, & data->value.linger ); break; case PR_SockOpt_NoDelay: data->value.no_delay = getBooleanProperty(env, sockObj,"getTcpNoDelay"); break; default: retval = PR_FAILURE; break; } finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus jsock_setSockOpt(PRFileDesc *fd, PRSocketOptionData *data) { PRStatus retval = PR_SUCCESS; JNIEnv *env; jobject sockObj; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); switch(data->option) { case PR_SockOpt_Keepalive: setBooleanProperty(env, sockObj, "setKeepAlive",data->value.keep_alive); break; case PR_SockOpt_Linger: setSoLinger(env, sockObj, &data->value.linger); break; case PR_SockOpt_RecvBufferSize: setIntProperty(env, sockObj, "setReceiveBufferSize", data->value.recv_buffer_size); break; case PR_SockOpt_SendBufferSize: setIntProperty(env, sockObj, "setSendBufferSize", data->value.send_buffer_size); break; case PR_SockOpt_NoDelay: setBooleanProperty(env, sockObj, "setTcpNoDelay", data->value.no_delay); break; default: retval = PR_FAILURE; break; } finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus jsock_close(PRFileDesc *fd) { PRStatus retval = PR_FAILURE; JNIEnv *env; jobject sockObj; jclass sockClass; jmethodID closeMethod; jthrowable excep; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); /* * Get the close method */ sockClass = (*env)->GetObjectClass(env, sockObj); if( sockClass == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } closeMethod = (*env)->GetMethodID(env, sockClass, SOCKET_CLOSE_NAME, SOCKET_CLOSE_SIG); if( closeMethod == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } /* * call the close method */ (*env)->CallVoidMethod(env, sockObj, closeMethod); /* * Free the PRFilePrivate */ (*env)->DeleteGlobalRef(env, fd->secret->sockGlobalRef); if( (excep = JSS_SSL_getException(fd->secret)) != NULL ) { (*env)->DeleteGlobalRef(env, excep); } PR_Free(fd->secret); fd->secret = NULL; retval = PR_SUCCESS; finish: /* * If an exception was thrown, we can't put it in the fd because we * just deleted it. So instead, we're going to let it ride and check for * it up in socketClose(). */ if( env ) { if( (*env)->ExceptionOccurred(env) != NULL ) { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static PRStatus jsock_shutdown(PRFileDesc *fd, PRShutdownHow how) { PRStatus retval = PR_FAILURE; JNIEnv *env; jobject sockObj; jmethodID methodID; jclass clazz; if( GET_ENV(fd->secret->javaVM, env) ) goto finish; /* * get the socket */ sockObj = fd->secret->sockGlobalRef; PR_ASSERT(sockObj != NULL); clazz = (*env)->GetObjectClass(env, sockObj); if( clazz == NULL ) goto finish; if( how == PR_SHUTDOWN_SEND || how == PR_SHUTDOWN_BOTH ) { methodID = (*env)->GetMethodID(env, clazz, "shutdownOutput", "()V"); if( methodID == NULL ) goto finish; (*env)->CallVoidMethod(env, sockObj, methodID); } if( (*env)->ExceptionOccurred(env) ) goto finish; if( how == PR_SHUTDOWN_RCV || how == PR_SHUTDOWN_BOTH ) { methodID = (*env)->GetMethodID(env, clazz, "shutdownInput", "()V"); if( methodID == NULL ) goto finish; (*env)->CallVoidMethod(env, sockObj, methodID); } retval = PR_SUCCESS; finish: if( env != NULL ) { jthrowable excep = (*env)->ExceptionOccurred(env); if( excep != NULL ) { setException(env, fd->secret, (*env)->NewGlobalRef(env, excep)); (*env)->ExceptionClear(env); retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } } else { retval = PR_FAILURE; PR_SetError(PR_IO_ERROR, 0); } return retval; } static const PRIOMethods jsockMethods = { PR_DESC_SOCKET_TCP, (PRCloseFN) jsock_close, (PRReadFN) invalidInt, (PRWriteFN) invalidInt, (PRAvailableFN) invalidInt, (PRAvailable64FN) invalidInt, (PRFsyncFN) invalidInt, (PRSeekFN) invalidInt, (PRSeek64FN) invalidInt, (PRFileInfoFN) invalidInt, (PRFileInfo64FN) invalidInt, (PRWritevFN) jsock_write, (PRConnectFN) invalidInt, (PRAcceptFN) invalidInt, (PRBindFN) invalidInt, (PRListenFN) invalidInt, (PRShutdownFN) jsock_shutdown, (PRRecvFN) jsock_recv, (PRSendFN) jsock_send, (PRRecvfromFN) invalidInt, (PRSendtoFN) invalidInt, (PRPollFN) invalidInt, (PRAcceptreadFN) invalidInt, (PRTransmitfileFN) invalidInt, (PRGetsocknameFN) jsock_getSockName, (PRGetpeernameFN) jsock_getPeerName, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt, (PRGetsocketoptionFN) jsock_getSockOpt, (PRSetsocketoptionFN) jsock_setSockOpt, (PRSendfileFN) invalidInt, (PRConnectcontinueFN) invalidInt, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt, (PRReservedFN) invalidInt }; static void jsockDestructor(PRFileDesc *fd) { PR_ASSERT(!"This destructor shouldn't be called. close() does the work"); } PRFileDesc* JSS_SSL_javasockToPRFD(JNIEnv *env, jobject sockObj) { PRFileDesc *fd; JavaVM *vm; if( (*env)->GetJavaVM(env, &vm) != 0 ) { return NULL; } fd = PR_NEW(PRFileDesc); if( fd ) { fd->methods = &jsockMethods; fd->secret = PR_NEW(PRFilePrivate); fd->secret->sockGlobalRef = (*env)->NewGlobalRef(env, sockObj); fd->secret->javaVM = vm; fd->secret->exception = NULL; fd->secret->timeout = PR_INTERVAL_NO_TIMEOUT; fd->lower = fd->higher = NULL; fd->dtor = jsockDestructor; } else { /* OUT OF MEM */ } return fd; } jss-4.4.3/jss/org/mozilla/jss/ssl/jssl.h000066400000000000000000000066011326145000000200740ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef ORG_MOZILLA_JSS_SSL_JSSL_H #define ORG_MOZILLA_JSS_SSL_JSSL_H #include struct JSSL_SocketData { PRFileDesc *fd; jobject socketObject; /* weak global ref */ jobject certApprovalCallback; /* global ref */ jobject clientCertSelectionCallback; /* global ref */ CERTCertificate *clientCert; PK11SlotInfo *clientCertSlot; PRFilePrivate *jsockPriv; PRLock *lock; /* protects reader, writer, accepter, and closePending */ PRThread *reader; PRThread *writer; PRThread *accepter; PRBool closePending; }; typedef struct JSSL_SocketData JSSL_SocketData; SECStatus JSSL_JavaCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer); void JSSL_AlertReceivedCallback(const PRFileDesc *fd, void *client_data, const SSLAlert *alert); void JSSL_AlertSentCallback(const PRFileDesc *fd, void *client_data, const SSLAlert *alert); void JSSL_HandshakeCallback(PRFileDesc *fd, void *arg); SECStatus JSSL_DefaultCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer); SECStatus JSSL_CallCertSelectionCallback( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey); SECStatus JSSL_ConfirmExpiredPeerCert(void *arg, PRFileDesc *fd, PRBool checkSig, PRBool isServer); SECStatus JSSL_GetClientAuthData( void * arg, PRFileDesc * fd, CERTDistNames * caNames, CERTCertificate ** pRetCert, SECKEYPrivateKey ** pRetKey); #ifdef JDK1_2 /* JDK 1.2 and higher provide weak references in JNI. */ #define NEW_WEAK_GLOBAL_REF(env, obj) \ ((*env)->NewWeakGlobalRef((env), (obj))) #define DELETE_WEAK_GLOBAL_REF(env, obj) \ ((*env)->DeleteWeakGlobalRef((env), (obj))) #else /* JDK 1.1 doesn't have weak references, so we'll have to use regular ones */ #define NEW_WEAK_GLOBAL_REF(env, obj) \ ((*env)->NewGlobalRef((env), (obj))) #define DELETE_WEAK_GLOBAL_REF(env, obj) \ ((*env)->DeleteGlobalRef((env), (obj))) #endif #define JSSL_getSockData(env, sockObject, sdptr) \ JSS_getPtrFromProxyOwner(env, sockObject, SSLSOCKET_PROXY_FIELD, \ SSLSOCKET_PROXY_SIG, (void**)sdptr) void JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd); extern PRInt32 JSSL_enums[]; #define JSSL_enums_size 35 JSSL_SocketData* JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD, PRFilePrivate *priv); #define SSL_POLICY_DOMESTIC 0 #define SSL_POLICY_EXPORT 1 #define SSL_POLICY_FRANCE 2 typedef enum {LOCAL_SOCK, PEER_SOCK} LocalOrPeer; PRStatus JSSL_getSockAddr (JNIEnv *env, jobject self, PRNetAddr *addr, LocalOrPeer localOrPeer); PRFileDesc* JSS_SSL_javasockToPRFD(JNIEnv *env, jobject sockObj); jthrowable JSS_SSL_getException(PRFilePrivate *priv); void JSS_SSL_processExceptions(JNIEnv *env, PRFilePrivate *priv); #define EXCEPTION_CHECK(env, sock) \ if( sock != NULL && sock->jsockPriv!=NULL) { \ JSS_SSL_processExceptions(env, sock->jsockPriv); \ } void JSSL_throwSSLSocketException(JNIEnv *env, char *message); #endif jss-4.4.3/jss/org/mozilla/jss/ssl/manifest.mn000066400000000000000000000007171326145000000211140ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 REQUIRES = nspr20 nss PACKAGE = org/mozilla/jss/ssl CSRCS = SSLSocket.c \ callbacks.c \ SSLServerSocket.c \ common.c \ javasock.c \ $(NULL) LIBRARY_NAME = jssssl jss-4.4.3/jss/org/mozilla/jss/ssl/package.html000066400000000000000000000003771326145000000212350ustar00rootroot00000000000000 SSL sockets. jss-4.4.3/jss/org/mozilla/jss/ssl/rules.mk000066400000000000000000000014231326145000000204300ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. javadoc: @echo Steve's Javadoc rule ------------------------- /usr/java/jdk1.1.5/bin/javadoc -sourcepath $(JAVA_HOME)/lib/classes.zip:$(CORE_DEPTH)/ninja -d /u/stevep/javadoc $(JSRCS) @echo End of Steve's Javadoc rule ------------------ runserver: $(DEBUG_CMD) $(SOURCE_BIN_DIR)/jssjava -classpath $(JAVA_HOME)/lib/classes.zip:$(SOURCE_CLASSES_DIR)_DBG org.mozilla.jss.ssl.SSLServer runclient: $(DEBUG_CMD) $(SOURCE_BIN_DIR)/jssjava -classpath $(JAVA_HOME)/lib/classes.zip:$(SOURCE_CLASSES_DIR)_DBG org.mozilla.jss.ssl.SSLClient debugcore: dbx $(SOURCE_BIN_DIR)/jssjava core jss-4.4.3/jss/org/mozilla/jss/tests/000077500000000000000000000000001326145000000173065ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/tests/ClassServer.java000077500000000000000000000075051326145000000224170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.*; import java.net.*; import java.util.Vector; import javax.net.*; /* * ClassServer.java -- JSSE_SSLServer implements this * class. */ public abstract class ClassServer implements Runnable { private ServerSocket server = null; private Vector supportedCiphers = new Vector(); /** * Constructs a ClassServer based on ss */ protected ClassServer(ServerSocket ss) { server = ss; newListener(); } /** * The "listen" thread that accepts a connection to the * server, parses the header to obtain the file name * and sends back the bytes for the file (or error * if the file is not found or the response was malformed). */ public void run() { Socket socket = null; boolean socketListenStatus = true; // accept a connection while ( socketListenStatus ) { try { socket = server.accept(); } catch (Exception ex) { System.exit(1); } newListener(); //try to read some bytes, to allow the handshake to go through try { InputStream is = socket.getInputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); String socketData = bir.readLine(); if ( socketData.equals("null") ) socketListenStatus = false; else if ( socketData != null ) supportedCiphers.add(socketData); socket.close(); } catch(EOFException e) { } catch(IOException ex) { } catch(NullPointerException npe) { socketListenStatus = false; } } try { server.close(); } catch (Exception ex) { System.exit(1); } System.out.println("Server exiting"); System.out.println("-------------------------------------------" + "-------------"); System.out.println("Summary of JSS client to JSSE server " + "communication test :"); System.out.println("-------------------------------------------" + "-------------"); System.out.println("supportedCiphers.size " + supportedCiphers.size()); System.out.println("Constants.jssCiphersSuites "+ Constants.jssCipherSuites.length); for ( int i=0; i<(supportedCiphers.size()-1); i++ ) { System.out.print(i + " SC " + new Integer((String)supportedCiphers.elementAt(i)).intValue()); for ( int j=0; j<(Constants.jssCipherSuites.length); j++ ) { if (new Integer((String)supportedCiphers.elementAt(i)).intValue() == Constants.jssCipherSuites[j].value ) { System.out.print(" JSSC "); System.out.println(" ["+ i +"]\t" + Constants.jssCipherSuites[j].name); System.out.flush(); } } } System.out.println("-------------------------------------------" + "-------------"); System.out.flush(); if( !socketListenStatus ) { System.exit(0); } } /** * Create a new thread to listen. */ private void newListener() { (new Thread(this)).start(); } } jss-4.4.3/jss/org/mozilla/jss/tests/CloseDBs.java000066400000000000000000000042321326145000000216100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import java.util.Enumeration; import java.math.BigInteger; import java.security.PrivateKey; public final class CloseDBs extends org.mozilla.jss.DatabaseCloser { public CloseDBs() throws Exception { super(); } public static void main(String args[]) { int i; try { if(args.length != 1) { System.err.println("Usage: CloseDBs "); System.exit(0); } CryptoManager.initialize( args[0] ); CryptoManager manager = CryptoManager.getInstance(); Enumeration tokens = manager.getAllTokens(); CryptoStore store; X509Certificate certs[]; java.security.PrivateKey keys[]; while(tokens.hasMoreElements()) { CryptoToken token = (CryptoToken) tokens.nextElement(); store = token.getCryptoStore(); System.out.println("Token: "+token.getName()); certs = store.getCertificates(); System.out.println("Certs:"); for(i=0; i < certs.length; i++) { System.out.println( certs[i].getNickname() ); } keys = store.getPrivateKeys(); System.out.println("Keys:"); try { for(i=0; i < keys.length; i++) { System.out.println(new BigInteger(keys[i].getEncoded())); } } catch (Exception ex) { System.out.println(ex.getMessage()); } } System.out.println("Closing databases..."); try { (new CloseDBs()).closeDatabases(); } catch (Exception ex) { System.out.println(ex.getMessage()); System.exit(1); } System.out.println("Databases are closed."); System.exit(0); } catch(Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.4.3/jss/org/mozilla/jss/tests/Constants.java000077500000000000000000000254031326145000000221340ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.ssl.*; /** * Holds immutable values for JSS Tests. * */ public interface Constants { /** Debug level for all tests */ public static int debug_level = 1; public static final class cipher { int value; /* hex value */ String name; cipher(int v, String n) { value = v; name = n; } /* * returns the string representation of the ciphersuite OR * returns null if the ciphersuite is not found */ public static final String cipherToString(int aCipher ) { for (int i = 0; i < Constants.jssCipherSuites.length; i++) { if (aCipher == Constants.jssCipherSuites[i].value) { return Constants.jssCipherSuites[i].name; } } return null; } /* * returns the integer value of the ciphersuite OR * returns -1 if the ciphersuite is not found. */ public static final int stringToCipher(String sCipher ) { for (int i = 0; i < Constants.jssCipherSuites.length; i++) { if (sCipher.compareToIgnoreCase( Constants.jssCipherSuites[i].name) == 0) { return Constants.jssCipherSuites[i].value; } } return -1; } } /* cipherSuites Supported by JSS */ public static final cipher jssCipherSuites[] = { /*0 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"), /*1 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"), /*2 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA"), /*3 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA"), /*4 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"), /*5 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_256_CBC_SHA, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"), /*6 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"), /*7 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"), /*8 */ new cipher(SSLSocket.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA"), /*9 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA, "TLS_RSA_WITH_AES_256_CBC_SHA"), /*10 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"), /*11 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"), /*12 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"), /*13 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"), /*14 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA"), /*15 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA"), /*16 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_RC4_128_SHA, "TLS_DHE_DSS_WITH_RC4_128_SHA"), /*17 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"), /*18 */ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_128_CBC_SHA, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"), /*19 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS_ECDH_RSA_WITH_RC4_128_SHA"), /*20 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"), /*21 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"), /*22 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"), /*23 */ new cipher(SSLSocket.TLS_RSA_WITH_SEED_CBC_SHA, "TLS_RSA_WITH_SEED_CBC_SHA"), /*24 */ new cipher(SSLSocket.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA"), /*25 */ new cipher(SSLSocket.SSL3_RSA_WITH_RC4_128_MD5, "SSL3_RSA_WITH_RC4_128_MD5"), /*26 */ new cipher(SSLSocket.SSL3_RSA_WITH_RC4_128_SHA, "SSL3_RSA_WITH_RC4_128_SHA"), /*27 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA, "TLS_RSA_WITH_AES_128_CBC_SHA"), /*28 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"), /*29 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"), /*30 */ new cipher(SSLSocket.SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA"), /*31 */ new cipher(SSLSocket.SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA, "SSL3_DHE_DSS_WITH_3DES_EDE_CBC_SHA"), /*32 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"), /*33 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"), /*34 */ new cipher(SSLSocket.SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA"), /*35 */ new cipher(SSLSocket.SSL3_RSA_WITH_3DES_EDE_CBC_SHA, "SSL3_RSA_WITH_3DES_EDE_CBC_SHA"), /*36 */ new cipher(SSLSocket.SSL3_DHE_RSA_WITH_DES_CBC_SHA, "SSL3_DHE_RSA_WITH_DES_CBC_SHA"), /*37 */ new cipher(SSLSocket.SSL3_DHE_DSS_WITH_DES_CBC_SHA, "SSL3_DHE_DSS_WITH_DES_CBC_SHA"), /*38 */ new cipher(SSLSocket.SSL_RSA_FIPS_WITH_DES_CBC_SHA, "SSL_RSA_FIPS_WITH_DES_CBC_SHA"), /*39 */ new cipher(SSLSocket.SSL3_RSA_WITH_DES_CBC_SHA, "SSL3_RSA_WITH_DES_CBC_SHA"), /*40 */ new cipher(SSLSocket.TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA"), /*41 */ new cipher(SSLSocket.TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA"), /*42 */ new cipher(SSLSocket.SSL3_RSA_EXPORT_WITH_RC4_40_MD5, "SSL3_RSA_EXPORT_WITH_RC4_40_MD5"), /*43 */ new cipher(SSLSocket.SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5, "SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5"), /*44 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"), /*45 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS_ECDHE_RSA_WITH_NULL_SHA"), /*46 */ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_NULL_SHA, "TLS_ECDH_RSA_WITH_NULL_SHA"), /*47 */ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS_ECDH_ECDSA_WITH_NULL_SHA"), /*48 */ new cipher(SSLSocket.SSL3_RSA_WITH_NULL_SHA, "SSL3_RSA_WITH_NULL_SHA"), /*49 */ new cipher(SSLSocket.SSL3_RSA_WITH_NULL_MD5, "SSL3_RSA_WITH_NULL_MD5"), /*50 */ new cipher(SSLSocket.TLS_RSA_WITH_NULL_SHA256, "TLS_RSA_WITH_NULL_SHA256"), /*51 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"), /*52 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"), /*53 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"), /*54 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"), /*55 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"), /*56 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"), /*57 */ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256"), /*58 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"), /*59 */ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), /*60 */ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"), /** /* SSL2 ciphersuites are here for legacy purposes. * you should call SSLSocket.enableSSL2Default(false) during your setup. * to disable all SSL2 ciphersuites. **/ /*61 */ new cipher(SSLSocket.SSL2_RC4_128_WITH_MD5, "SSL2_RC4_128_WITH_MD5"), /*62 */ new cipher(SSLSocket.SSL2_RC2_128_CBC_WITH_MD5, "SSL2_RC2_128_CBC_WITH_MD5"), /*63 */ new cipher(SSLSocket.SSL2_DES_192_EDE3_CBC_WITH_MD5, "SSL2_DES_192_EDE3_CBC_WITH_MD5"), /*64 */ new cipher(SSLSocket.SSL2_DES_64_CBC_WITH_MD5, "SSL2_DES_64_CBC_WITH_MD5"), /*65 */ new cipher(SSLSocket.SSL2_RC4_128_EXPORT40_WITH_MD5, "SSL2_RC4_128_EXPORT40_WITH_MD5"), /*66 */ new cipher(SSLSocket.SSL2_RC2_128_CBC_EXPORT40_WITH_MD5, "SSL2_RC2_128_CBC_EXPORT40_WITH_MD5"), /*67 */ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"), /*68*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"), /*69*/ new cipher(SSLSocket.TLS_RSA_WITH_NULL_SHA256, "TLS_RSA_WITH_NULL_SHA256"), /*70*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS_RSA_WITH_AES_128_CBC_SHA256"), /*71*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS_RSA_WITH_AES_256_CBC_SHA256"), /*72*/ new cipher(SSLSocket.TLS_RSA_WITH_SEED_CBC_SHA, "TLS_RSA_WITH_SEED_CBC_SHA"), /*73*/ new cipher(SSLSocket.TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS_RSA_WITH_AES_128_GCM_SHA256"), /*74*/ new cipher(SSLSocket.TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"), /*75*/ new cipher(SSLSocket.TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"), /*76*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"), /*77*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"), /*78*/ new cipher(SSLSocket.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"), /*79*/ new cipher(SSLSocket.TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"), /*78*/ new cipher(SSLSocket.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"), /*80*/ new cipher(SSLSocket.TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256") }; /** Cipher supported by JSSE (JDK 1.5.x) */ public static String [] sslciphersarray_jdk150 = { // These ciphers must always pass "SSL_RSA_WITH_RC4_128_MD5", "SSL_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_DES_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_WITH_NULL_MD5", }; /** Cipher supported by JSSE (JDK 1.4.x) */ public static String [] sslciphersarray_jdk142 = { "SSL_RSA_WITH_RC4_128_MD5", "SSL_RSA_WITH_RC4_128_SHA", "TLS_RSA_WITH_AES_128_CBC_SHA", "SSL_RSA_WITH_DES_CBC_SHA", "SSL_RSA_WITH_3DES_EDE_CBC_SHA", "SSL_RSA_EXPORT_WITH_RC4_40_MD5", "SSL_RSA_WITH_NULL_MD5", }; } jss-4.4.3/jss/org/mozilla/jss/tests/DigestTest.java000066400000000000000000000115421326145000000222330ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.Debug; import java.security.MessageDigest; import java.security.Provider; import java.security.Security; public class DigestTest { /** * This is the name of the JSS crypto provider for use with * MessageDigest.getInstance(). */ static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; /** * List all the Digest Algorithms that JSS implements. */ static final String JSS_Digest_Algs[] = { "MD2", "MD5", "SHA-1", "SHA-256", "SHA-384","SHA-512"}; public static boolean messageDigestCompare(String alg, byte[] toBeDigested) throws Exception { byte[] otherDigestOut; byte[] mozillaDigestOut; boolean bTested = false; // get the digest for the Mozilla-JSS provider java.security.MessageDigest mozillaDigest = java.security.MessageDigest.getInstance(alg, MOZ_PROVIDER_NAME); mozillaDigestOut = mozillaDigest.digest(toBeDigested); // loop through all the providers that support the algorithm // compare the result to Mozilla-JSS's digest Provider[] providers = Security.getProviders("MessageDigest." + alg); String provider = null; for (int i = 0; i < providers.length; ++i) { provider = providers[i].getName(); if (provider.equals(MOZ_PROVIDER_NAME)) { continue; } java.security.MessageDigest otherDigest = java.security.MessageDigest.getInstance(alg, provider); otherDigestOut = otherDigest.digest(toBeDigested); if( MessageDigest.isEqual(mozillaDigestOut, otherDigestOut) ) { System.out.println(provider + " and " + MOZ_PROVIDER_NAME + " give same " + alg + " message digests"); bTested = true; } else { throw new Exception("ERROR: " + provider + " and " + MOZ_PROVIDER_NAME + " give different " + alg + " message digests"); } } return bTested; } public static boolean testJSSDigest(String alg, byte[] toBeDigested) throws Exception { byte[] mozillaDigestOut; java.security.MessageDigest mozillaDigest = java.security.MessageDigest.getInstance(alg, MOZ_PROVIDER_NAME); mozillaDigestOut = mozillaDigest.digest(toBeDigested); if( mozillaDigestOut.length == mozillaDigest.getDigestLength() ) { System.out.println(mozillaDigest.getAlgorithm() + " " + " digest output size is " + mozillaDigestOut.length); } else { throw new Exception("ERROR: digest output size is "+ mozillaDigestOut.length + ", should be "+ mozillaDigest.getDigestLength() ); } return true; } public static void main(String []argv) { try { if( argv.length != 2 ) { System.out.println( "Usage: java org.mozilla.jss.tests.DigestTest " + " "); System.exit(1); } String dbdir = argv[0]; FileInputStream fis = new FileInputStream(argv[1]); byte[] toBeDigested = new byte[ fis.available() ]; int read = fis.read( toBeDigested ); System.out.println(read + " bytes to be digested"); CryptoManager.initialize(dbdir); Debug.setLevel(Debug.OBNOXIOUS); ///////////////////////////////////////////////////////////// // Test all available algorithms ///////////////////////////////////////////////////////////// String javaVersion = System.getProperty("java.version"); System.out.println("The Java version is: " + javaVersion); for (int i = 0; i < JSS_Digest_Algs.length; i++) { // compare Mozilla-JSS implementation with all providers // that also support the given algorithm if (messageDigestCompare(JSS_Digest_Algs[i], toBeDigested) == false) { // no provider to compare results with testJSSDigest(JSS_Digest_Algs[i], toBeDigested); } } //HMAC examples in org.mozilla.jss.tests.HMACTest } catch( Exception e ) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/FilePasswordCallback.java000066400000000000000000000023131326145000000241670ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.util.*; import java.io.*; import java.util.Properties; /** */ public class FilePasswordCallback implements PasswordCallback { private Properties passwords; public FilePasswordCallback(String filename) throws IOException { passwords = new Properties(); passwords.load( new FileInputStream(filename) ); } /** */ public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { String pw = passwords.getProperty(info.getName()); if( pw == null ) { throw new PasswordCallback.GiveUpException(); } else { System.out.println("***FilePasswordCallback returns " + pw); return new Password(pw.toCharArray()); } } /** */ public Password getPasswordAgain(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } } jss-4.4.3/jss/org/mozilla/jss/tests/FipsTest.java000066400000000000000000000134571326145000000217240ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.*; import org.mozilla.jss.pkcs11.*; import org.mozilla.jss.crypto.*; import java.io.*; import org.mozilla.jss.util.PasswordCallback; public class FipsTest { public static void main(String args[]) { try { if( args.length < 2 ) { System.out.println("Usage: FipsTest "); return; } String dbdir = args[0]; String fipsmode = args[1]; String password = ""; if (args.length == 3) { password = args[2]; System.out.println("The password file " +password); } CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues(dbdir); System.out.println("output of Initilization values "); System.out.println("Manufacturer ID: " + vals.getManufacturerID()); System.out.println("Library: " + vals.getLibraryDescription()); System.out.println("Internal Slot: " + vals.getInternalSlotDescription()); System.out.println("Internal Token: " + vals.getInternalTokenDescription()); System.out.println("Key Storage Slot: " + vals.getFIPSKeyStorageSlotDescription()); System.out.println("Key Storage Token: " + vals.getInternalKeyStorageTokenDescription()); System.out.println("FIPS Slot: " + vals.getFIPSSlotDescription()); System.out.println("FIPS Key Storage: " + vals.getFIPSKeyStorageSlotDescription()); if (fipsmode.equalsIgnoreCase("enable")) { vals.fipsMode = CryptoManager.InitializationValues.FIPSMode.ENABLED; } else if (fipsmode.equalsIgnoreCase("disable")){ vals.fipsMode = CryptoManager.InitializationValues.FIPSMode.DISABLED; } else { vals.fipsMode = CryptoManager.InitializationValues.FIPSMode.UNCHANGED; } CryptoManager.initialize(vals); CryptoManager cm = CryptoManager.getInstance(); if (cm.FIPSEnabled() == true ) { System.out.println("\n\t\tFIPS enabled\n"); } else { System.out.println("\n\t\tFIPS not enabled\n"); } java.util.Enumeration items; items = cm.getModules(); System.out.println("\nListing of Modules:"); while(items.hasMoreElements()) { System.out.println("\t"+ ((PK11Module)items.nextElement()).getName() ); } CryptoToken tok; String tokenName; items = cm.getAllTokens(); System.out.println("\nAll Tokens:"); while(items.hasMoreElements()) { tok = (CryptoToken)items.nextElement(); System.out.print("\t" + tok.getName()); if (tok.needsLogin() == true){ System.out.println("\t - Needs login.\n"); } else { System.out.println("\t - Does not need login.\n"); } } items = cm.getExternalTokens(); System.out.println("\nExternal Tokens:"); while(items.hasMoreElements()) { System.out.println("\t"+ ((CryptoToken)items.nextElement()).getName() ); } /* find the Internal Key Storage token */ if (cm.FIPSEnabled() == true ) { tokenName = vals.getFIPSSlotDescription(); } else { tokenName = vals.getInternalKeyStorageTokenDescription(); } /* truncate to 32 bytes and remove trailing white space*/ tokenName = tokenName.substring(0, 32); tokenName = tokenName.trim(); System.out.println("\nFinding the Internal Key Storage token: "+ tokenName); tok = cm.getTokenByName(tokenName); if( ((PK11Token)tok).isInternalKeyStorageToken() && tok.equals(cm.getInternalKeyStorageToken()) ) { System.out.println("Good, "+tok.getName()+", knows it is " + "the internal Key Storage Token"); } else { System.out.println("ERROR: "+tok.getName()+", doesn't know"+ " it is the internal key storage token"); } if (!password.equals("")) { System.out.println("logging in to the Token: " + tok.getName()); PasswordCallback cb = new FilePasswordCallback(password); tok.login(cb); System.out.println("logged in to the Token: " + tok.getName()); } /* find the Internal Crypto token */ if (cm.FIPSEnabled() == true ) { tokenName = vals.getFIPSSlotDescription(); } else { tokenName = vals.getInternalTokenDescription(); } /* truncate to 32 bytes and remove trailing white space*/ tokenName = tokenName.substring(0, 32); tokenName = tokenName.trim(); System.out.println("\nFinding the Internal Crypto token: " + tokenName); tok = cm.getTokenByName(tokenName); if( ((PK11Token)tok).isInternalCryptoToken() && tok.equals(cm.getInternalCryptoToken() )) { System.out.println("Good, "+tok.getName()+ ", knows it is the internal Crypto token"); } else { System.out.println("ERROR: "+tok.getName()+ ", doesn't know that it is the internal Crypto token"); } System.exit(0); } catch( Exception e ) { e.printStackTrace(); System.exit(1); } } } jss-4.4.3/jss/org/mozilla/jss/tests/GenerateTestCert.java000077500000000000000000000303061326145000000233660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * GenerateTestCert is a class for generating SSL test certificates for * the JSS tests (all.pl). You should use certutil to create * your certificates. * */ package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.*; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.util.PasswordCallback; import java.util.Calendar; import java.util.Date; import java.security.*; import java.security.PrivateKey; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.InternalCertificate; import org.mozilla.jss.crypto.SignatureAlgorithm; import org.mozilla.jss.crypto.X509Certificate; public class GenerateTestCert { private X509Certificate nssServerCert, nssClientCert; static final private String CACERT_NICKNAME = "JSSCATestCert"; static final private String SERVERCERT_NICKNAME = "JSSTestServerCert"; static final private String CLIENTCERT_NICKNAME = "JSSTestClientCert"; private String keyType = "RSA"; private int keyLength = 1024; private SignatureAlgorithm sigAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest; /** * Main method for testing and generating cert pairs. */ public static void main(String[] args) throws Exception { GenerateTestCert gtc = new GenerateTestCert(); if ( args.length > 0 ) { gtc.doIt(args); } else { gtc.usage(); } } public void usage() { System.out.println("USAGE: " + "java org.mozilla.jss.tests.GenerateTestCert " + " [hostname] " + "[Signature Alg] [CAcertNickname] " + "[ServerCertNickname] [ClientCertNickName]"); System.out.println("This program creates self signed Certificates." + "They are only meant for testing and should never be " + "used in production. " + "\nThe default nicknames:" + "\n\tCA certificate: " + CACERT_NICKNAME + "\n\tServer certificate: " + SERVERCERT_NICKNAME + "\n\tClient certificate: " + CLIENTCERT_NICKNAME); System.out.println("Signature algorithm values:\n" + "\tSHA-1/RSA" + "\tSHA-256/RSA" + "\tSHA-384/RSA" + "\tSHA-512/RSA" + "\tSHA-1/DSA" + "\tSHA-1/EC" + "\tSHA-256/EC" + "\tSHA-384/EC" + "\tSHA-512/EC"); System.exit(1); } private void setSigAlg(String alg) { if (alg.equalsIgnoreCase("SHA-1/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest; } else if (alg.equalsIgnoreCase("SHA-256/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA256Digest; } else if (alg.equalsIgnoreCase("SHA-384/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA384Digest; } else if (alg.equalsIgnoreCase("SHA-512/RSA")) { sigAlg = SignatureAlgorithm.RSASignatureWithSHA512Digest; } else if (alg.equalsIgnoreCase("SHA-1/DSA")) { sigAlg = SignatureAlgorithm.DSASignatureWithSHA1Digest; } else if (alg.equalsIgnoreCase("SHA-1/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA1Digest; } else if (alg.equalsIgnoreCase("SHA-256/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA256Digest; } else if (alg.equalsIgnoreCase("SHA-384/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA384Digest; } else if (alg.equalsIgnoreCase("SHA-512/EC")) { sigAlg = SignatureAlgorithm.ECSignatureWithSHA512Digest; } else { usage(); } //For keyLength we are going to use default 1024 key for RSA/DSA //and 256 key for ECDSA if (alg.endsWith("RSA")) { keyType = "RSA"; } else if (alg.endsWith("DSA")) { keyType = "DSA"; } else if (alg.endsWith("EC")) { keyType = "EC"; keyLength = 256; } else { usage(); } } /** * Based on the input parameters, generate a cert * pair. */ private void doIt(String[] args) throws Exception { String caCertNick = CACERT_NICKNAME; String serverCertNick = SERVERCERT_NICKNAME; String clientCertNick = CLIENTCERT_NICKNAME; if ( args.length < 3 ) { usage(); } try { CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(args[1]); tok.login(cb); int serialNum = new Integer(args[2]).intValue(); X509Certificate[] permCerts = cm.getPermCerts(); int originalPermCerts = permCerts.length; System.out.println("Number of certificates stored in the " + " database: " + originalPermCerts); String hostname = "localhost"; if (args.length > 4) { hostname = args[3]; } String alg = "SHA-256/RSA"; if (args.length > 5) { alg = args[4]; } setSigAlg(alg); X509Certificate[] certs; if (args.length > 6) { caCertNick = args[5]; } /* ensure certificate does not already exists */ certs = cm.findCertsByNickname(caCertNick); if (certs.length > 0) { System.out.println(caCertNick + " already exists!"); System.exit(1); } if (args.length > 7) { serverCertNick = args[6]; } certs = cm.findCertsByNickname(serverCertNick); if (certs.length > 0) { System.out.println(serverCertNick + " already exists!"); System.exit(1); } if (args.length == 8) { clientCertNick = args[7]; } certs = cm.findCertsByNickname(clientCertNick); if (certs.length > 0) { System.out.println(clientCertNick + " already exists!"); System.exit(1); } // generate CA cert java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance( keyType, "Mozilla-JSS"); kpg.initialize(keyLength); KeyPair caPair = kpg.genKeyPair(); SEQUENCE extensions = new SEQUENCE(); extensions.addElement(makeBasicConstraintsExtension()); Certificate caCert = makeCert("CACert", "CACert", serialNum, caPair.getPrivate(), caPair.getPublic(), serialNum, extensions); X509Certificate nssCaCert = cm.importUserCACertPackage( ASN1Util.encode(caCert), caCertNick); InternalCertificate intern = (InternalCertificate)nssCaCert; intern.setSSLTrust( InternalCertificate.TRUSTED_CA | InternalCertificate.TRUSTED_CLIENT_CA | InternalCertificate.VALID_CA); // generate server cert kpg.initialize(keyLength); KeyPair serverPair = kpg.genKeyPair(); Certificate serverCert = makeCert("CACert", hostname, serialNum+1, caPair.getPrivate(), serverPair.getPublic(), serialNum, null); nssServerCert = cm.importCertPackage( ASN1Util.encode(serverCert), serverCertNick); // generate client auth cert kpg.initialize(keyLength); KeyPair clientPair = kpg.genKeyPair(); Certificate clientCert = makeCert("CACert", "ClientCert", serialNum+2, caPair.getPrivate(), clientPair.getPublic(), serialNum, null); nssClientCert = cm.importCertPackage( ASN1Util.encode(clientCert), clientCertNick); System.out.println("\nThis program created certificates with \n" + "following cert nicknames:" + "\n\t" + caCertNick + "\n\t" + serverCertNick + "\n\t" + clientCertNick); permCerts = cm.getPermCerts(); if ( (originalPermCerts + 3) != permCerts.length) { System.out.println("Error there should be three more " + " certificates stored in the database"); System.exit(1); } else { System.out.println("Number of certificates stored in the " + " database: " + permCerts.length); } /* ensure certificates exists */ certs = cm.findCertsByNickname(caCertNick); if (certs.length == 0) { System.out.println(caCertNick + " should exist!"); System.exit(1); } certs = cm.findCertsByNickname(serverCertNick); if (certs.length == 0) { System.out.println(serverCertNick + " should exist!"); System.exit(1); } certs = cm.findCertsByNickname(clientCertNick); if (certs.length == 0) { System.out.println(clientCertNick + " should exist!"); System.exit(1); } } catch(Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } /** * Make basic extension. */ private Extension makeBasicConstraintsExtension() throws Exception { SEQUENCE bc = new SEQUENCE(); bc.addElement( new BOOLEAN(true) ); // cA OBJECT_IDENTIFIER bcOID = new OBJECT_IDENTIFIER( new long[] {2, 5, 29, 19}); // from RFC 2459 OCTET_STRING enc = new OCTET_STRING(ASN1Util.encode(bc)); return new Extension(bcOID, true, enc); } /** * Method that generates a certificate for given credential * * @param issuerName * @param subjectName * @param serialNumber * @param privKey * @param pubKey * @param rand * @param extensions * @throws java.lang.Exception * @return */ private Certificate makeCert(String issuerName, String subjectName, int serialNumber, PrivateKey privKey, PublicKey pubKey, int rand, SEQUENCE extensions) throws Exception { AlgorithmIdentifier sigAlgID = new AlgorithmIdentifier(sigAlg.toOID()); Name issuer = new Name(); issuer.addCountryName("US"); issuer.addOrganizationName("Mozilla"); issuer.addOrganizationalUnitName("JSS Testing" + rand); issuer.addCommonName(issuerName); Name subject = new Name(); subject.addCountryName("US"); subject.addOrganizationName("Mozilla"); subject.addOrganizationalUnitName("JSS Testing" + rand); subject.addCommonName(subjectName); Calendar cal = Calendar.getInstance(); Date notBefore = cal.getTime(); cal.add(Calendar.YEAR, 1); Date notAfter = cal.getTime(); SubjectPublicKeyInfo.Template spkiTemp = new SubjectPublicKeyInfo.Template(); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode(spkiTemp, pubKey.getEncoded()); CertificateInfo info = new CertificateInfo( CertificateInfo.v3, new INTEGER(serialNumber), sigAlgID, issuer, notBefore, notAfter, subject, spki); if( extensions != null ) { info.setExtensions(extensions); } return new Certificate(info, privKey, sigAlg); } } jss-4.4.3/jss/org/mozilla/jss/tests/HMACTest.java000077500000000000000000000154771326145000000215420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.*; import java.security.MessageDigest; import org.mozilla.jss.CryptoManager; import java.security.Security; import java.security.Provider; import javax.crypto.*; import javax.crypto.spec.*; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.util.PasswordCallback; /** * HMAC is a hash function based message authentication code. * HMACTest compares the HMAC created by Mozilla, IBM and Sun JCE. * * @author Sandeep.Konchady@Sun.COM * @version 1.0 */ public class HMACTest { private CryptoManager cm; /** * JSS crypto provider name. */ static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; /** * List all the HMAC Algorithms that JSS implements. */ static final String JSS_HMAC_Algs[] = {"HmacSHA1", "HmacSHA256", "HmacSHA384", "HmacSHA512" }; public HMACTest(String[] argv) throws Exception { if (argv.length < 1) { System.out.println( "Usage: java org.mozilla.jss.tests.HMACTest " + " [password file only needed in FIPS mode]"); System.exit(1); } CryptoManager.initialize(argv[0]); cm = CryptoManager.getInstance(); if (cm.FIPSEnabled() == true) { System.out.println("\n\t\tFIPS enabled.\n"); if (argv.length == 2) { CryptoToken tok = cm.getInternalCryptoToken(); System.out.println("logging in to token: " + tok.getName()); PasswordCallback cb = new FilePasswordCallback(argv[1]); tok.login(cb); } } } public boolean compareHMAC(String alg, SecretKeyFacade sk, String clearText) throws Exception { byte[] providerHmacOut; byte[] mozillaHmacOut; boolean bTested = false; //Get the Mozilla HMAC Mac mozillaHmac = Mac.getInstance(alg, MOZ_PROVIDER_NAME); mozillaHmac.init(sk); mozillaHmac.update(clearText.getBytes()); mozillaHmacOut = mozillaHmac.doFinal(); // loop through all configured providers; if they support the // algorithm compare the result to Mozilla's HMAC Provider[] providers = Security.getProviders("Mac." + alg); String provider = null; for (int i = 0; i < providers.length; ++i) { provider = providers[i].getName(); //System.out.println ("Testing provider " + provider); if (provider.equals(MOZ_PROVIDER_NAME)) { continue; } Mac providerHmac = Mac.getInstance(alg, provider); providerHmac.init(sk); providerHmac.update(clearText.getBytes()); providerHmacOut = providerHmac.doFinal(); if (MessageDigest.isEqual(mozillaHmacOut, providerHmacOut)) { System.out.println(provider + " and " + MOZ_PROVIDER_NAME + " give same " + alg); bTested = true; } else { throw new Exception("ERROR: " + provider + " and " + MOZ_PROVIDER_NAME + " give different " + alg); } } return bTested; } public void doHMAC(String alg, SecretKeyFacade sk, String clearText) throws Exception { byte[] mozillaHmacOut; //Get the Mozilla HMAC Mac mozillaHmac = Mac.getInstance(alg, MOZ_PROVIDER_NAME); mozillaHmac.init(sk); mozillaHmacOut = mozillaHmac.doFinal(clearText.getBytes()); if (mozillaHmacOut.length == mozillaHmac.getMacLength()) { System.out.println(MOZ_PROVIDER_NAME + " supports " + mozillaHmac.getAlgorithm() + " and the output size is " + mozillaHmac.getMacLength()); } else { throw new Exception("ERROR: hmac output size is " + mozillaHmacOut.length + ", should be " + mozillaHmac.getMacLength()); } } public boolean fipsMode() { return cm.FIPSEnabled(); } /** * Main test method. * @param argv */ public static void main(String[] argv) { try { HMACTest hmacTest = new HMACTest(argv); //The secret key must be a JSS key. That is, it must be an //instanceof org.mozilla.jss.crypto.SecretKeyFacade. //Generate the secret key using PKCS # 5 password Based Encryption //we have to specify a salt and an iteration count. PBEKeySpec pbeKeySpec; SecretKeyFactory keyFac; SecretKeyFacade sk; byte[] salt = { (byte) 0x0a, (byte) 0x6d, (byte) 0x07, (byte) 0xba, (byte) 0x1e, (byte) 0xbd, (byte) 0x72, (byte) 0xf1 }; int iterationCount = 7; pbeKeySpec = new PBEKeySpec("password".toCharArray(), salt, iterationCount); keyFac = SecretKeyFactory.getInstance("PBEWithSHA1AndDES3", "Mozilla-JSS"); sk = (SecretKeyFacade) keyFac.generateSecret(pbeKeySpec); ///////////////////////////////////////////////////////////// // Test all available algorithms ///////////////////////////////////////////////////////////// String clearText = new String("FireFox and Thunderbird rule"); for (int i = 0; i < JSS_HMAC_Algs.length; i++) { if (hmacTest.fipsMode()) { //In FIPS Mode only test JSS due to NSS prevents //key data from being extracted above the //NSS cryptographic boundary when FIPS mode //is enabled. //note there is a bug with HmacSHA512 in fipsmode. //https://bugzilla.mozilla.org/show_bug.cgi?id=436907 if (!JSS_HMAC_Algs[i].equals("HmacSHA512")) { hmacTest.doHMAC(JSS_HMAC_Algs[i], sk, clearText); } } else { // compare MOZ_PROVIDER_NAME implementation with all // providers that also support the given algorithm if (!hmacTest.compareHMAC( JSS_HMAC_Algs[i], sk, clearText)) { // no provider to compare results with so just test JSS hmacTest.doHMAC(JSS_HMAC_Algs[i], sk, clearText); } } } } catch (Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/HmacTest.java000066400000000000000000000065011326145000000216630ustar00rootroot00000000000000 package org.mozilla.jss.tests; import java.security.Key; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.Mac; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.SymmetricKey; public class HmacTest { private static final String INTERNAL_KEY_STORAGE_TOKEN = new CryptoManager.InitializationValues("").getInternalKeyStorageTokenDescription().trim(); private static final String NSS_DATABASE_DIR = "sql:data"; private static final String PROVIDER = "Mozilla-JSS"; public static void main(String[] args) { String algorithm = "hmac-sha1"; try { configureCrypto(args); Mac mac = Mac.getInstance(algorithm, PROVIDER); byte[] keyData = new byte[16]; Key key = importHmacSha1Key(keyData); mac.init(key); doHMAC(mac,"Dogtag rules!"); System.out.println("Done"); System.exit(0); } catch (Exception e) { System.exit(1); } } private static void configureCrypto(String[] args) throws Exception { CryptoManager.InitializationValues initializationValues = new CryptoManager.InitializationValues(args[0]); CryptoManager.initialize(initializationValues); CryptoManager cryptoManager = CryptoManager.getInstance(); CryptoToken cryptoToken = cryptoManager.getTokenByName(INTERNAL_KEY_STORAGE_TOKEN); cryptoManager.setThreadToken(cryptoToken); } private static Key importHmacSha1Key(byte[] key) throws Exception { final String WRAPPING_ALGORITHM = "AES/CBC/PKCS5Padding"; Key wrappingKey = getWrappingKey(); byte[] iv = new byte[16]; IvParameterSpec ivParameterSpec = new IvParameterSpec(iv); Cipher wrappingCipher = Cipher.getInstance(WRAPPING_ALGORITHM, PROVIDER); wrappingCipher.init(Cipher.ENCRYPT_MODE, wrappingKey, ivParameterSpec); byte[] wrappedKeyData = wrappingCipher.doFinal(key); Cipher unwrappingCipher = Cipher.getInstance(WRAPPING_ALGORITHM, PROVIDER); unwrappingCipher.init(Cipher.UNWRAP_MODE, wrappingKey, ivParameterSpec); return (SecretKey) unwrappingCipher.unwrap(wrappedKeyData, SymmetricKey.SHA1_HMAC.toString(), Cipher.SECRET_KEY); } private static synchronized Key getWrappingKey() throws Exception { final String keyGenAlgorithm = "AES"; final int wrappingKeyLength = 256; KeyGenerator keyGen = KeyGenerator.getInstance(keyGenAlgorithm, PROVIDER); keyGen.init(wrappingKeyLength); return keyGen.generateKey(); } public static void doHMAC(Mac mozillaHmac, String clearText) throws Exception { byte[] mozillaHmacOut; //Get the Mozilla HMAC mozillaHmacOut = mozillaHmac.doFinal(clearText.getBytes()); if (mozillaHmacOut.length == mozillaHmac.getMacLength()) { System.out.println(PROVIDER + " supports " + mozillaHmac.getAlgorithm() + " and the output size is " + mozillaHmac.getMacLength()); } else { throw new Exception("ERROR: hmac output size is " + mozillaHmacOut.length + ", should be " + mozillaHmac.getMacLength()); } } } jss-4.4.3/jss/org/mozilla/jss/tests/JCAKeyWrap.java000077500000000000000000000425171326145000000220650ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.IOException; import java.io.UnsupportedEncodingException; import org.mozilla.jss.CryptoManager.NotInitializedException; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.crypto.AlreadyInitializedException; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenException; import javax.crypto.SecretKey; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; import javax.crypto.IllegalBlockSizeException; import javax.crypto.KeyGenerator; import javax.crypto.NoSuchPaddingException; import java.security.AlgorithmParameters; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.Provider; import java.security.SecureRandom; import java.security.Security; import java.util.Arrays; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.PasswordCallback; /** * Test Mozilla-JSS provider key wrap/unwrap * * JSS currently needs to compile with JDK 1.4.2.x * * This program tests wrapping/unwrapping on symmetric keys. * unwraping of private keys is not available at this time see * https://bugzilla.mozilla.org/show_bug.cgi?id=135328 * */ public class JCAKeyWrap { protected static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; public static void main(String args[]) { if (args.length != 2) { usage(); System.exit(1); } String dbdir = args[0]; String passwdfile = args[1]; try { JCAKeyWrap keyWrap = new JCAKeyWrap(dbdir, passwdfile); //If the IBMJCE provider exists tests with it otherwise //use the SunJCE provider. String otherProvider = new String("IBMJCE"); String otherRSAProvider = new String("IBMJCE"); Provider p = null; p = Security.getProvider(otherProvider); if (p == null) { otherProvider = new String("SunJCE"); otherRSAProvider = new String("SunRsaSign"); p = Security.getProvider(otherProvider); if (p == null) { System.out.println("unable to find IBMJCE or SunJCE " + "providers"); Provider[] providers = Security.getProviders(); for (int i = 0; i < providers.length; i++) { System.out.println("Provider " + i + ": " + providers[i].getName()); } System.exit(1); } } // Generate an RSA keypair KeyPairGenerator kpgen; kpgen = KeyPairGenerator.getInstance("RSA", MOZ_PROVIDER_NAME); kpgen.initialize(1024); KeyPair rsaKeyPairNSS = kpgen.generateKeyPair(); kpgen = KeyPairGenerator.getInstance("RSA", otherRSAProvider); kpgen.initialize(1024); KeyPair rsaKeyPairOtherProvider = kpgen.generateKeyPair(); javax.crypto.SecretKey tripleDESKey; KeyGenerator keyGen = KeyGenerator.getInstance("DESede", MOZ_PROVIDER_NAME); tripleDESKey = keyGen.generateKey(); keyWrap.wrapSymetricKeyWithRSA(tripleDESKey, rsaKeyPairNSS, MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); if (!keyWrap.isBFipsMode()) { keyWrap.wrapSymetricKeyWithRSA(tripleDESKey, rsaKeyPairNSS, MOZ_PROVIDER_NAME, otherProvider); } keyGen = KeyGenerator.getInstance("AES", MOZ_PROVIDER_NAME); javax.crypto.SecretKey aesKeyToWrap; keyGen.init(128); aesKeyToWrap = keyGen.generateKey(); keyGen = KeyGenerator.getInstance("AES", MOZ_PROVIDER_NAME); int AESKeySize[] = {128, 192, 256}; for (int k = 0; k < AESKeySize.length; k++) { //create AES key javax.crypto.SecretKey aesKey; keyGen.init(AESKeySize[k]); aesKey = keyGen.generateKey(); keyGen = KeyGenerator.getInstance("AES", MOZ_PROVIDER_NAME); int keyStrength = (((SecretKeyFacade) aesKey).key.getStrength()); //JDK 1.4 and 1.5 only supports 128 keys for AES //therefore only do comparison testing of providers with //128 key strength if (keyStrength == 128 && !keyWrap.isBFipsMode()) { keyWrap.wrapSymetricKey(tripleDESKey, "AES/CBC/PKCS5Padding", aesKey, MOZ_PROVIDER_NAME, otherProvider); keyWrap.wrapSymetricKey(aesKeyToWrap, "AES/CBC/PKCS5Padding", aesKey, MOZ_PROVIDER_NAME, otherProvider); keyWrap.wrapSymetricKeyWithRSA(aesKey, rsaKeyPairNSS, MOZ_PROVIDER_NAME, otherProvider); } else { keyWrap.wrapSymetricKey(tripleDESKey, "AES/CBC/PKCS5Padding", aesKey); keyWrap.wrapSymetricKey(aesKeyToWrap, "AES/CBC/PKCS5Padding", aesKey); keyWrap.wrapSymetricKeyWithRSA(aesKey, rsaKeyPairNSS); } aesKeyToWrap = aesKey; } } catch (Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } /** * */ public static void usage() { System.out.println( "Usage: java org.mozilla.jss.tests.JCAKeyWrap " + " "); } protected boolean bFipsMode = false; protected byte[] plainText = "Firefox rules!Firefox rules!Firefox rules!Firefox rules!Firefox rules!".getBytes(); protected byte[] plainTextPad = "Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!".getBytes(); /** * Default constructor to initialize Mozilla-JSS * @param certDbLoc * @param passwdFile */ public JCAKeyWrap(String certDbLoc, String passwdFile) { try { CryptoManager.initialize(certDbLoc); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(passwdFile); token.login(cb); if (cm.FIPSEnabled()) { bFipsMode = true; System.out.println("in Fipsmode."); } } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } catch (KeyDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (CertDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (AlreadyInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (GeneralSecurityException ex) { ex.printStackTrace(); System.exit(1); } catch (IncorrectPasswordException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (NotInitializedException ex) { ex.printStackTrace(); System.exit(1); } } /** * * @return true when in FIPS mode false otherwise */ public boolean isBFipsMode() { return bFipsMode; } /** * Randomly selects a cipher transformation "algorithm/mode/padding". * @param symKeyType * @return a cipher transformation "algorithm/mode/padding" * @throws Exception */ public String testCipher(String symKeyType) throws Exception { String testCipher; String[] cipherDESede = {"DESede/ECB/NoPadding", "DESede/CBC/PKCS5Padding", "DESede/CBC/NoPadding"}; String[] cipherAES = {"AES/ECB/NoPadding", "AES/CBC/NoPadding", "AES/CBC/PKCS5Padding"}; SecureRandom r = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); if (symKeyType.equalsIgnoreCase("AES")) { return cipherAES[r.nextInt(cipherAES.length)]; } else if (symKeyType.equalsIgnoreCase("DESede")) { return cipherDESede[r.nextInt(cipherDESede.length)]; } else { throw new Exception("no support for " + symKeyType); } } /** * * both providers are Mozilla-JSS * * @param symKey * @param keyPair * @throws Exception */ public void wrapSymetricKeyWithRSA(Key symKey, KeyPair keyPair) throws Exception { wrapSymetricKeyWithRSA(symKey, keyPair, MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); } /** * * @param symKey * @param keyPair * @param providerA * @param providerB * @throws Exception */ public void wrapSymetricKeyWithRSA( Key symKey, KeyPair keyPair, String providerA, String providerB) throws Exception { try { String symKeyType = new String(symKey.getAlgorithm()); System.out.print("Wrap " + symKeyType + " " + ((SecretKeyFacade) symKey).key.getStrength() + " with RSA. "); // wrap key Cipher cipher = Cipher.getInstance("RSA", providerA); cipher.init(Cipher.WRAP_MODE, keyPair.getPublic()); byte[] wrappedData = cipher.wrap(symKey); // unwrap key cipher = Cipher.getInstance("RSA", providerA); cipher.init(Cipher.UNWRAP_MODE, keyPair.getPrivate()); SecretKey unwrappedKey = (javax.crypto.SecretKey) cipher.unwrap(wrappedData, symKeyType, Cipher.SECRET_KEY); testKeys(symKey, unwrappedKey, providerA, providerB); } catch (BadPaddingException ex) { ex.printStackTrace(); System.exit(1); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); System.exit(1); } catch (IllegalBlockSizeException ex) { ex.printStackTrace(); System.exit(1); } catch (InvalidKeyException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchPaddingException ex) { ex.printStackTrace(); System.exit(1); } } /** * both providers used will be Mozilla-JSS * * @param symKey * @param wrapperAlg * @param wrapperKey * @throws Exception */ public void wrapSymetricKey(Key symKey, String wrapperAlg, Key wrapperKey) throws Exception { wrapSymetricKey(symKey, wrapperAlg, wrapperKey, MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); } /** * compare two keys * * @param key1 * @param key2 * @return true if equal false otherwise */ static boolean keysEqual(Key key1, Key key2) { if (key1.equals(key2)) { return true; } if (Arrays.equals(key1.getEncoded(), key2.getEncoded())) { return true; } return false; } /** * * @param keyA * @param keyB * @param providerA * @param providerB * @throws java.lang.Exception */ protected void testKeys(Key keyA, Key keyB, String providerA, String providerB) throws Exception { //ensure keys are equal if (bFipsMode) { //bFipsMode providerA and providerB mozilla-JSS //Keys are not extractable so just check key length if (((SecretKeyFacade) keyA).key.getStrength() != ((SecretKeyFacade) keyB).key.getStrength()) { throw new Exception("unwrapped key strength does not " + "match orginal"); } } else if (!keysEqual(keyA, keyB)) { throw new Exception("unwrapped key " + "does not match original"); } //As an extra test encrypt with keyA using ProviderA //and decrypt with with keyB using ProviderB String cipherAlg = testCipher(keyA.getAlgorithm()); System.out.println("Test " + cipherAlg + " encrypt with " + providerA + " decrypt " + providerB); // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText; if (cipherAlg.endsWith("PKCS5Padding")) { plaintext = plainTextPad; } //encrypt some text as a test with the key to be wrap Cipher cipher = Cipher.getInstance(cipherAlg, providerA); cipher.init(Cipher.ENCRYPT_MODE, keyA); byte[] encryptedText = cipher.doFinal(plaintext); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. AlgorithmParameters ap = null; byte[] encodedAlgParams = null; ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedAlgParams = ap.getEncoded(); } // use the unwrapped key for decryption cipher = Cipher.getInstance(cipherAlg, providerB); if (encodedAlgParams == null) { cipher.init(Cipher.DECRYPT_MODE, keyB); } else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance(keyB.getAlgorithm()); aps.init(encodedAlgParams); cipher.init(Cipher.DECRYPT_MODE, keyB, aps); } byte[] recovered = new byte[plaintext.length]; int rLen = cipher.update(encryptedText, 0, encryptedText.length, recovered, 0); rLen += cipher.doFinal(recovered, rLen); if (!java.util.Arrays.equals(plaintext, recovered)) { throw new Exception("key do not match. unable to encrypt/decrypt."); } } /** * * @param symKey * @param wrapperAlg * @param wrapperKey * @param providerA * @param providerB * @throws Exception */ public void wrapSymetricKey(Key symKey, String wrapperAlg, Key wrapperKey, String providerA, String providerB) throws Exception { try { System.out.print("Wrap " + symKey.getAlgorithm() + " " + ((SecretKeyFacade) symKey).key.getStrength() + " with " + wrapperKey.getAlgorithm() + " " + ((SecretKeyFacade) wrapperKey).key.getStrength() + " symmetric key. "); // wrap key Cipher cipher = Cipher.getInstance(wrapperAlg, providerA); cipher.init(Cipher.WRAP_MODE, wrapperKey); byte[] wrappedData = cipher.wrap(symKey); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. byte[] encodedKeyWrapAP = null; AlgorithmParameters ap = null; ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedKeyWrapAP = ap.getEncoded(); } // unwrap key cipher = Cipher.getInstance(wrapperAlg, providerA); if (encodedKeyWrapAP == null) { cipher.init(Cipher.UNWRAP_MODE, wrapperKey); } else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance( wrapperKey.getAlgorithm()); aps.init(encodedKeyWrapAP); cipher.init(Cipher.UNWRAP_MODE, wrapperKey, aps); } SecretKey unwrappedKey = (SecretKey) cipher.unwrap(wrappedData, symKey.getAlgorithm(), Cipher.SECRET_KEY); testKeys(symKey, unwrappedKey, providerA, providerB); } catch (BadPaddingException ex) { ex.printStackTrace(); System.exit(1); } catch (IllegalBlockSizeException ex) { ex.printStackTrace(); System.exit(1); } catch (UnsupportedEncodingException ex) { ex.printStackTrace(); System.exit(1); } catch (InvalidKeyException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchPaddingException ex) { ex.printStackTrace(); System.exit(1); } } } jss-4.4.3/jss/org/mozilla/jss/tests/JCASigTest.java000066400000000000000000000131731326145000000220560ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.security.*; import java.io.*; import org.mozilla.jss.util.*; import org.mozilla.jss.*; public class JCASigTest { public static void usage() { System.out.println( "Usage: java org.mozilla.jss.tests.JCASigTest "); } public static void sigTest(String alg, KeyPair keyPair) { byte[] data = new byte[] {1,2,3,4,5,6,7,8,9}; byte[] signature; Signature signer; try { signer = Signature.getInstance(alg); System.out.println("Created a signing context"); Provider provider = signer.getProvider(); System.out.println("The provider used for the signer " + provider.getName() + " and the algorithm was " + alg); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } signer.initSign( (org.mozilla.jss.crypto.PrivateKey)keyPair.getPrivate()); System.out.println("initialized the signing operation"); signer.update(data); System.out.println("updated signature with data"); signature = signer.sign(); System.out.println("Successfully signed!"); signer.initVerify(keyPair.getPublic()); System.out.println("initialized verification"); signer.update(data); System.out.println("updated verification with data"); if ( signer.verify(signature) ) { System.out.println("Signature Verified Successfully!"); } else { System.out.println("ERROR: Signature failed to verify."); } } catch ( Exception e ) { e.printStackTrace(); System.exit(1); } } public static void main(String args[]) { CryptoManager manager; KeyPairGenerator kpgen; KeyPair keyPair; if ( args.length != 2 ) { usage(); System.exit(1); } String dbdir = args[0]; String file = args[1]; try { CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues (dbdir ); vals.removeSunProvider = true; CryptoManager.initialize(vals); manager = CryptoManager.getInstance(); manager.setPasswordCallback( new FilePasswordCallback(file) ); Debug.setLevel(Debug.OBNOXIOUS); Provider[] providers = Security.getProviders(); for ( int i=0; i < providers.length; i++ ) { System.out.println("Provider "+i+": "+providers[i].getName()); } // Generate an RSA keypair kpgen = KeyPairGenerator.getInstance("RSA"); kpgen.initialize(1024); keyPair = kpgen.generateKeyPair(); Provider provider = kpgen.getProvider(); System.out.println("The provider used to Generate the Keys was " + provider.getName() ); System.out.println("provider info " + provider.getInfo() ); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } sigTest("MD5/RSA", keyPair); sigTest("MD2/RSA", keyPair); sigTest("SHA-1/RSA", keyPair); sigTest("SHA-256/RSA", keyPair); sigTest("SHA-384/RSA", keyPair); sigTest("SHA-512/RSA", keyPair); // Generate an DSA keypair kpgen = KeyPairGenerator.getInstance("DSA"); kpgen.initialize(1024); keyPair = kpgen.generateKeyPair(); provider = kpgen.getProvider(); System.out.println("The provider used to Generate the Keys was " + provider.getName() ); System.out.println("provider info " + provider.getInfo() ); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } sigTest("SHA-1/DSA", keyPair); kpgen = KeyPairGenerator.getInstance("EC"); kpgen.initialize(256); keyPair = kpgen.generateKeyPair(); provider = kpgen.getProvider(); System.out.println("The provider used to Generate the Keys was " + provider.getName() ); System.out.println("provider info " + provider.getInfo() ); if (provider.getName().equalsIgnoreCase("Mozilla-JSS") == false) { System.out.println("Mozilla-JSS is supposed to be the " + "default provider for JCASigTest"); System.exit(1); } sigTest("SHA-1/EC", keyPair); sigTest("SHA-256/EC", keyPair); sigTest("SHA-384/EC", keyPair); sigTest("SHA-512/EC", keyPair); } catch ( Exception e ) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/JCASymKeyGen.java000066400000000000000000000535431326145000000223540ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.PasswordCallback; import java.security.Provider; import java.security.Security; import java.security.AlgorithmParameters; import java.security.spec.AlgorithmParameterSpec; import javax.crypto.spec.RC2ParameterSpec; import javax.crypto.KeyGenerator; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.PBEKeySpec; import java.security.SecureRandom; /** * */ public class JCASymKeyGen { static final String MOZ_PROVIDER_NAME = "Mozilla-JSS"; byte[] plainText = "Firefox rules!Firefox rules!Firefox rules!Firefox rules!Firefox rules!".getBytes(); byte[] plainTextPad = "Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!Thunderbird rules!".getBytes(); byte[] plainTextB = "NSPR NSS JSS!NSPR NSS JSS!NSPR NSS JSS!".getBytes(); byte[] plainTextPadB = "Use Firefox and Thunderbird!".getBytes(); static boolean bFipsMode = false; /** * Default constructor */ public JCASymKeyGen( String certDbLoc, String passwdFile) { try { CryptoManager.initialize(certDbLoc); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); if (cm.FIPSEnabled()) { try { bFipsMode=true; PasswordCallback cb = new FilePasswordCallback(passwdFile); token.login(cb); System.out.println("Logged in"); } catch (IncorrectPasswordException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } } } catch (AlreadyInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (CertDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (CryptoManager.NotInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (GeneralSecurityException ex) { ex.printStackTrace(); System.exit(1); } catch (KeyDatabaseException ex) { ex.printStackTrace(); System.exit(1); } } /** * * @param keyType * @param provider * @return javax.crypto.SecretKey key */ public javax.crypto.SecretKey genSecretKey(String keyType, String provider){ javax.crypto.SecretKey key = null; javax.crypto.KeyGenerator kg = null; try { kg = KeyGenerator.getInstance(keyType, provider); if (keyType.equals("AES") || keyType.equals("RC2")) { kg.init(128); //JDK 1.4 and 1.5 only supports 128 keys for AES } System.out.println("Key " + keyType + " generation done by " + kg.getProvider().toString()); key = kg.generateKey(); if( !checkAlgorithm(key, keyType) ) { throw new Exception("Error: " + key.getAlgorithm() + " algorithm"); } //System.out.println("The length of the generated key in bits: " + // (key.getEncoded().length * 8) + // " " + key.getAlgorithm() ); } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } return key; } /** * * @param keyType * @param provider * @return javax.crypto.SecretKey key */ public javax.crypto.SecretKey genPBESecretKey(String keyType, String provider){ javax.crypto.SecretKey key = null; javax.crypto.SecretKeyFactory kf = null; try { char[] pw = "thunderbird".toCharArray(); byte[] salt = new byte[8]; SecureRandom random = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); random.nextBytes(salt); int iterationCount = 2; kf = SecretKeyFactory.getInstance(keyType, provider); PBEKeySpec keySpec = new PBEKeySpec(pw, salt, iterationCount); key = (SecretKeyFacade) kf.generateSecret(keySpec); //todo this should work as well //PBEKeySpec pbeKeySpec = new PBEKeySpec(pw)); // key = kf.generateSecret(pbeKeySpec); System.out.println("Key " + keyType + " generation done by " + kf.getProvider().toString()); if (!bFipsMode) { System.out.println("The length of the generated key in bits: " + (key.getEncoded().length * 8) + " " + key.getAlgorithm() ); } } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } return key; } /** * * @param sKey * @param algFamily * @param algType * @param providerForEncrypt * @param providerForDecrypt */ public void testCipher(javax.crypto.SecretKey sKey, String algFamily, String algType, String providerForEncrypt, String providerForDecrypt) throws Exception { try { // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText; if (algType.endsWith("PKCS5Padding")) { plaintext = plainTextPad; } //encypt Cipher cipher = Cipher.getInstance(algType, providerForEncrypt); AlgorithmParameters ap = null; byte[] encodedAlgParams = null; AlgorithmParameterSpec RC2ParSpec = null; if (algFamily.compareToIgnoreCase("RC2")==0) { //JDK 1.4 requires you to pass in generated algorithm //parameters for RC2 (JDK 1.5 does not). byte[] iv = new byte[8]; SecureRandom random = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); random.nextBytes(iv); RC2ParSpec = new RC2ParameterSpec(128, iv); cipher.init(Cipher.ENCRYPT_MODE, sKey, RC2ParSpec); } else { cipher.init(Cipher.ENCRYPT_MODE, sKey); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedAlgParams = ap.getEncoded(); } } //System.out.print(plaintext.length + " plaintext size " + // providerForEncrypt + " encrypt outputsize: " + // cipher.getOutputSize(plaintext.length)); byte[] ciphertext = new byte[cipher.getOutputSize(plaintext.length)]; int cLen = cipher.update(plaintext, 0, plaintext.length, ciphertext, 0); cLen += cipher.doFinal(ciphertext, cLen); //decrypt cipher = Cipher.getInstance(algType, providerForDecrypt); if (encodedAlgParams == null) if (RC2ParSpec != null) // JDK 1.4 RC2 cipher.init(Cipher.DECRYPT_MODE, sKey, RC2ParSpec); else cipher.init(Cipher.DECRYPT_MODE, sKey); else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance(algFamily); aps.init(encodedAlgParams); cipher.init(Cipher.DECRYPT_MODE, sKey, aps); } byte[] recovered = new byte[cLen]; int rLen = cipher.update(ciphertext, 0, cLen, recovered, 0); rLen += cipher.doFinal(recovered, rLen); //ensure the recovered bytes equals the orginal plaintext boolean isEqual = true; for (int i = 0; i < plaintext.length; i++) { if (plaintext[i] != recovered[i]) { isEqual = false; break; } } if (isEqual) { //System.out.println(providerForEncrypt + " encrypted & " + // providerForDecrypt + " decrypted using " + // algType + " successful."); } else { throw new Exception("ERROR: " + providerForEncrypt + " and " + providerForDecrypt + " failed for " + algType ); } } catch (InvalidKeyException ex) { ex.printStackTrace(); } catch (javax.crypto.BadPaddingException ex) { ex.printStackTrace(); } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (javax.crypto.NoSuchPaddingException ex) { ex.printStackTrace(); } catch (javax.crypto.IllegalBlockSizeException ex) { ex.printStackTrace(); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); } } /** * * @param sKey * @param algFamily * @param algType * @param providerForEncrypt * @param providerForDecrypt */ public void testMultiPartCipher(javax.crypto.SecretKey sKey, String algFamily, String algType, String providerForEncrypt, String providerForDecrypt) throws Exception { try { // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText; byte[] plaintextB = plainTextB; if (algType.endsWith("PKCS5Padding")) { plaintext = plainTextPad; plaintextB = plainTextPadB; } //encypt Cipher cipher = Cipher.getInstance(algType, providerForEncrypt); AlgorithmParameters ap = null; byte[] encodedAlgParams = null; AlgorithmParameterSpec RC2ParSpec = null; if (algFamily.compareToIgnoreCase("RC2")==0) { //JDK 1.4 requires you to pass in generated algorithm //parameters for RC2 (JDK 1.5 does not). byte[] iv = new byte[8]; SecureRandom random = SecureRandom.getInstance("pkcs11prng", MOZ_PROVIDER_NAME); random.nextBytes(iv); RC2ParSpec = new RC2ParameterSpec(128, iv); cipher.init(Cipher.ENCRYPT_MODE, sKey, RC2ParSpec); } else { cipher.init(Cipher.ENCRYPT_MODE, sKey); //generate the algorithm Parameters; they need to be //the same for encrypt/decrypt if they are needed. ap = cipher.getParameters(); if (ap != null) { //get parameters to store away as example. encodedAlgParams = ap.getEncoded(); } } byte[] ciphertext = new byte[(cipher.getOutputSize(plaintext.length + plaintextB.length))]; int cLen = cipher.update(plaintext, 0, plaintext.length, ciphertext, 0); cLen += cipher.update(plaintextB, 0, plaintextB.length, ciphertext, cLen); cLen += cipher.doFinal(ciphertext, cLen); //decrypt cipher = Cipher.getInstance(algType, providerForDecrypt); if (encodedAlgParams == null) if (RC2ParSpec != null) // JDK 1.4 RC2 cipher.init(Cipher.DECRYPT_MODE, sKey, RC2ParSpec); else cipher.init(Cipher.DECRYPT_MODE, sKey); else { //retrieve the algorithmParameters from the encoded array AlgorithmParameters aps = AlgorithmParameters.getInstance(algFamily); aps.init(encodedAlgParams); cipher.init(Cipher.DECRYPT_MODE, sKey, aps); } byte[] recovered = new byte[cLen]; int rLen = cipher.update(ciphertext, 0, cLen, recovered, 0); rLen += cipher.doFinal(recovered, rLen); //ensure the recovered bytes equals the original plaintext boolean isEqual = true; for (int i = 0; i < plaintext.length; i++) { if (i [passwordFile]"); System.out.println("password file only required if in " + "FIPSMODE."); System.out.println("FIPSMODE requires Java 1.6 or higher!"); System.exit(1); } //If the IBMJCE provider exists tests with it otherwise //use the SunJCE provider. String otherProvider = new String("IBMJCE"); Provider p = null; p = Security.getProvider(otherProvider); if (p == null) { otherProvider = new String("SunJCE"); p = Security.getProvider(otherProvider); if (p == null){ System.out.println("unable to find IBMJCE or SunJCE providers"); System.exit(1); } } JCASymKeyGen skg = new JCASymKeyGen(certDbLoc, passwdFile); System.out.println(otherProvider + ": " + p.getInfo()); p = Security.getProvider(MOZ_PROVIDER_NAME); System.out.println(MOZ_PROVIDER_NAME + ": " + p.getInfo()); javax.crypto.SecretKey mozKey = null; try { for (int i = 0 ; i < symKeyTable.length; i++) { try { //generate the key using mozilla if (symKeyTable[i][0].startsWith("PBE") == true) { mozKey = skg.genPBESecretKey(symKeyTable[i][0], MOZ_PROVIDER_NAME); } else { mozKey = skg.genSecretKey(symKeyTable[i][0], MOZ_PROVIDER_NAME); } } catch(Exception e) { System.out.println("unable to generate key: " + symKeyTable[i][0] + " " + e.getMessage()); } //test the cipher algorithms for this keyType for (int a = 1 ; a < symKeyTable[i].length; a++){ //encrypt/decrypt with Mozilla Provider skg.testCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); skg.testMultiPartCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, MOZ_PROVIDER_NAME); try { //check to see if the otherProvider we are testing //against supports the algorithm. Cipher cipher = Cipher.getInstance(symKeyTable[i][a], otherProvider); } catch (Exception e) { System.out.println(MOZ_PROVIDER_NAME + " only supports " + symKeyTable[i][a]); //therefore don't try comparison continue; } //in FIPSMODE you can only use the Mozilla Provider if (!bFipsMode) { //encrypt with Mozilla, and Decrypt with otherProvider skg.testCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, otherProvider); skg.testMultiPartCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], MOZ_PROVIDER_NAME, otherProvider); //encrypt with otherProvider and decrypt with Mozilla skg.testCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], otherProvider, MOZ_PROVIDER_NAME); skg.testMultiPartCipher(mozKey, symKeyTable[i][0], symKeyTable[i][a], otherProvider, MOZ_PROVIDER_NAME); System.out.println(MOZ_PROVIDER_NAME + " and " + otherProvider + " tested " + symKeyTable[i][a]); } } } } catch(Exception e) { e.printStackTrace(); System.exit(1); } //end of main System.exit(0); } /** * Validate if the key algorithm of a given SecretKey * is the same as expected. * @param SecretKey k * @param String algorithm * @return boolean status */ private boolean checkAlgorithm(SecretKey k, String alg) { boolean status = false; if( k.getAlgorithm().equals(alg) ) { status = true; } return status; } /** * Validate if the key length of a given SecretKey * is the same as expected. * @param SecretKey k * @param int key length * @return boolean status */ private boolean checkKeyLength(SecretKey k, int len) { boolean status = false; byte[] keyData = k.getEncoded(); if( keyData.length == len ) { status = true; } return status; } /** * Turns array of bytes into string * * @param buf Array of bytes to convert to hex string * @return Generated hex string */ private String asHex(byte buf[]) { StringBuffer strbuf = new StringBuffer(buf.length * 2); int i; for (i = 0; i < buf.length; i++) { if (((int) buf[i] & 0xff) < 0x10) strbuf.append("0"); strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); } return strbuf.toString(); } } jss-4.4.3/jss/org/mozilla/jss/tests/JSSE_SSLClient.java000077500000000000000000000456671326145000000226220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.net.*; import java.io.*; import java.security.KeyStoreException; import java.security.NoSuchProviderException; import javax.net.ssl.*; import java.security.KeyStore; import java.util.ArrayList; import java.util.Iterator; /** * This program connects to any SSL Server to exercise * all ciphers supported by JSSE for a given JDK/JRE * version. The result is listing of common ciphers * between the server and this JSSE client. * */ public class JSSE_SSLClient { // Local members private String sslRevision = "TLS"; private String host = null; private int port = -1; private String cipherName = null; private String path = null; private int debug_level = 0; private String EOF = "test"; private String keystoreLoc = "rsa.pfx"; private SSLSocketFactory factory = null; /* ciphersuites to test */ private ArrayList ciphersToTest = new ArrayList(); /* h_ciphers is for ciphersuite that were able to successfully * connect to the server */ private ArrayList h_ciphers = new ArrayList(); /* f_ciphers is for ciphersuite that failed to connect to the server */ private ArrayList f_ciphers = new ArrayList(); private boolean bVerbose = false; private boolean bFipsMode = false; /** * Set the protocol type and revision * @param fSslRevision */ public void setSslRevision(String fSslRevision) { if (!(fSslRevision.equals("TLS") || fSslRevision.equals("SSLv3"))) { System.out.println("type must equal \'TLS\' or \'SSLv3\'\n"); System.exit(1); } this.sslRevision = fSslRevision; } /** * Set the host name to connect to. * @param fHost */ public void setHost(String fHost) { this.host = fHost; } /** * Set the port number to connect to. * @param fPort */ public void setPort(int fPort) { this.port = fPort; } /** * Set the cipher suite name to use. * @param fCipherSuite */ public void setCipherSuite(String fCipherSuite) { this.cipherName = fCipherSuite; } /** * Set the location of rsa.pfx * @param fKeystoreLoc */ public void setKeystoreLoc(String fKeystoreLoc) { keystoreLoc = fKeystoreLoc + "/" + keystoreLoc; } /** * Get the location of rsa.pfx * @return String fKeystoreLoc */ public String getKeystoreLoc() { return keystoreLoc; } /** * Default constructor. */ public JSSE_SSLClient() { //Do nothing. } public boolean isServerAlive() { boolean isServerAlive = false; SSLSocket socket = null; if (factory == null) { initSocketFactory(); } for (int i = 0 ; i < 20 ; i++) { try { Thread.sleep(1000); System.out.println("Testing Connection:" + host + ":" + port); socket = (SSLSocket)factory.createSocket(host, port); socket.setEnabledCipherSuites(factory.getDefaultCipherSuites()); if (socket.isBound()) { System.out.println("connect isBound"); isServerAlive = true; socket.close(); break; } } catch (java.net.ConnectException ex) { //not able to connect } catch (InterruptedException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } return isServerAlive; } /** * Test communication with SSL server S */ public void testCiphersuites() { SSLSocket socket = null; int i = 0; if (factory == null) { initSocketFactory(); } if (!isServerAlive()) { System.out.println("Unable to connect to " + host + ":" + port + " exiting."); System.exit(1); } Iterator iter = ciphersToTest.iterator(); while (iter.hasNext()) { String cs = (String)iter.next(); String ciphers[] = {cs}; try { socket = (SSLSocket)factory.createSocket(host, port); socket.setEnabledCipherSuites(ciphers); testSSLSocket(socket, cs, i++); } catch (Exception ex) { System.out.println("failed ciphersuite" + ciphers[0]); f_ciphers.add(ciphers[0]); } } } public void configureCipherSuites(String server, String CipherSuite) { boolean testCipher = true; if (factory == null) { initSocketFactory(); } String ciphers[] = factory.getSupportedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { String ciphersuite = ciphers[i]; testCipher = true; if (bVerbose) { System.out.print(ciphersuite); } if (server.equalsIgnoreCase("JSS")) { //For JSS SSLServer don't test if ((ciphersuite.indexOf("_DHE_") != -1)|| (ciphersuite.indexOf("_DES40_") != -1) || (ciphersuite.indexOf("TLS_EMPTY_RENEGOTIATION_INFO_SCSV") != -1) || (ciphersuite.indexOf("SHA256") != -1) || // reenable in bug 776597 (ciphersuite.indexOf("_anon_") != -1) || (ciphersuite.indexOf("_KRB5_") != -1)) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (server.equalsIgnoreCase("JSSE")) { //For JSSE SSLServers don't test _DHE_, _EXPORT_, _anon_, _KRB5_ /* if ((ciphersuite.indexOf("_DHE_") != -1) || (ciphersuite.indexOf("_EXPORT_") != -1) || (ciphersuite.indexOf("_anon_") != -1) || (ciphersuite.indexOf("_KRB5_") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } */ } if (testCipher) { ciphersToTest.add(ciphers[i]); if (bVerbose) System.out.print(" - Testing"); } } if (bVerbose) System.out.print("\n"); if(bVerbose) System.out.println("\nTesting " + ciphersToTest.size() + " ciphersuites."); } private void initSocketFactory() { SSLContext ctx = null; KeyManagerFactory kmf = null; TrustManagerFactory tmf = null; KeyStore ks = null; KeyStore ksTrust = null; String provider = "SunJCE"; /* * Set up a key manager for client authentication * if asked by the server. Use the implementation's * default TrustStore and secureRandom routines. */ char[] passphrase = "m1oZilla".toCharArray(); try { String javaVendor = System.getProperty("java.vendor"); if (Constants.debug_level > 3) System.out.println("DEBUG: JSSE_SSLClient.java java.vendor=" + javaVendor); // Initialize the system if (javaVendor.equals("IBM Corporation")) { System.setProperty("java.protocol.handler.pkgs", "com.ibm.net.ssl.www.protocol.Handler"); java.security.Security.addProvider((java.security.Provider) Class.forName("com.ibm.jsse2.IBMJSSEProvider2").newInstance()); provider = "IBMJCE"; } else { System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol"); java.security.Security.addProvider((java.security.Provider) Class.forName("com.sun.crypto.provider.SunJCE").newInstance()); } // Load the keystore that contains the certificate String certificate = new String("SunX509"); ks = KeyStore.getInstance("PKCS12"); if (javaVendor.equals("IBM Corporation")) { certificate = new String("IbmX509"); ks = KeyStore.getInstance("PKCS12", provider); } try { kmf = KeyManagerFactory.getInstance(certificate); ks.load(new FileInputStream(getKeystoreLoc()), passphrase); } catch (Exception keyEx) { if (Constants.debug_level > 3) { if(System.getProperty("java.vendor").equals("IBM Corporation")) { System.out.println("Using IBM JDK: Cannot load keystore due "+ "to strong security encryption settings\nwith limited " + "Jurisdiction policy files :\n" + "http://www-1.ibm.com/support/docview.wss?uid=swg21169931"); System.exit(0); } else { System.out.println(keyEx.getMessage()); keyEx.printStackTrace(); } } throw keyEx; } kmf.init(ks, passphrase); // trust manager that trusts all certificates TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public boolean checkClientTrusted( java.security.cert.X509Certificate[] chain){ return true; } public boolean isServerTrusted( java.security.cert.X509Certificate[] chain){ return true; } public boolean isClientTrusted( java.security.cert.X509Certificate[] chain){ return true; } public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] chain, String authType) {} public void checkServerTrusted( java.security.cert.X509Certificate[] chain, String authType) {} } }; ctx = SSLContext.getInstance(sslRevision); ctx.init(kmf.getKeyManagers(), trustAllCerts, null); factory = ctx.getSocketFactory(); String[] JSSE_ciphers = factory.getSupportedCipherSuites(); } catch (KeyStoreException ex) { ex.printStackTrace(); } catch (NoSuchProviderException ex) { ex.printStackTrace(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } catch (IllegalAccessException ex) { ex.printStackTrace(); } catch (InstantiationException ex) { ex.printStackTrace(); } catch (Exception ex) { ex.printStackTrace(); } } /** * sendServerShutdownMsg */ public void sendServerShutdownMsg() { try { SSLSocket socket = null; if (factory == null) { initSocketFactory(); } socket = (SSLSocket)factory.createSocket(host, port); socket.setEnabledCipherSuites(factory.getDefaultCipherSuites()); if (bVerbose) System.out.println("Sending shutdown message " + "to server."); socket.startHandshake(); OutputStream os = socket.getOutputStream(); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); out.println("shutdown"); out.flush(); out.close(); socket.close(); } catch (Exception ex) { ex.printStackTrace(); } } private void testSSLSocket(SSLSocket socket, String ciphersuite, int socketID) { /* * register a callback for handshaking completion event */ try { socket.addHandshakeCompletedListener( new HandshakeCompletedListener() { public void handshakeCompleted( HandshakeCompletedEvent event) { h_ciphers.add(event.getCipherSuite()); System.out.println(event.getCipherSuite()); if ( Constants.debug_level >= 3 ) { System.out.println( "SessionId "+ event.getSession() + " Test Status : PASS"); System.out.flush(); } } } ); } catch (Exception handshakeEx) { System.out.println(handshakeEx.getMessage()); handshakeEx.printStackTrace(); System.exit(1); } try { // Set socket timeout to 10 sec socket.setSoTimeout(10 * 1000); socket.startHandshake(); String outputLine = null; String inputLine = null; InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out; out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(os))); //write then read on the connection once. outputLine = ciphersuite + ":" + socketID + "\n"; if (bVerbose) { System.out.println("Sending: " + outputLine); } out.print(outputLine); out.flush(); inputLine = bir.readLine(); if (bVerbose) { System.out.println("Received: " + inputLine + " on Client-" + socketID); } bir.close(); out.close(); } catch (SSLHandshakeException ex) { f_ciphers.add(ciphersuite); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } try { socket.close(); } catch (IOException ex) { ex.printStackTrace(); } } public void outputCipherResults() { String banner = new String ("\n----------------------------------------------------------\n"); System.out.println(banner); System.out.println("JSSE has " + factory.getSupportedCipherSuites().length + " ciphersuites and " + ciphersToTest.size() + " were configured and tested."); if (ciphersToTest.size() == h_ciphers.size()) { System.out.println("All " + ciphersToTest.size() + " configured ciphersuites tested Successfully!\n"); } if (!h_ciphers.isEmpty()) { if (!f_ciphers.isEmpty()) { System.out.println(banner); System.out.println(h_ciphers.size() + " ciphersuites successfully connected to the "+ "server\n"); } Iterator iter = h_ciphers.iterator(); while (iter.hasNext()) { System.out.println((String) iter.next()); } } if (bFipsMode) { System.out.println("Note: ciphersuites that have the prefix " + "\"SSL\" or \"SSL3\" were used in TLS mode."); } if (ciphersToTest.size() != (h_ciphers.size() + f_ciphers.size())) { System.out.println("ERROR: did not test all expected ciphersuites"); } if (!f_ciphers.isEmpty()) { System.out.println(banner); System.out.println(f_ciphers.size() + " ciphersuites that did not connect to the "+ "server\n\n"); Iterator iter = f_ciphers.iterator(); while (iter.hasNext()) { System.out.println((String) iter.next()); } System.out.println("we should have no failed ciphersuites!"); System.exit(1); } System.out.println(banner); } /** * Main method for local unit testing. */ public static void main(String [] args) { String testCipher = null; String testHost = "localhost"; String keystoreLocation = "rsa.pfx"; int testPort = 29750; String serverType = "JSSE"; String usage = "java org.mozilla.jss.tests.JSSE_SSLClient" + "\n " + " "; try { if ( args[0].toLowerCase().equals("-h") || args.length < 1) { System.out.println(usage); System.exit(1); } if ( args.length >= 1 ) { keystoreLocation = (String)args[0]; } if ( args.length >= 2) { testPort = new Integer(args[1]).intValue(); System.out.println("using port: " + testPort); } if ( args.length >= 3) { testHost = (String)args[2]; } if ( args.length == 4) { serverType = (String)args[3]; } if ( args.length == 5) { testCipher = (String)args[4]; } } catch (Exception e) { System.out.println(usage); System.exit(1); } JSSE_SSLClient sslSock = new JSSE_SSLClient(); sslSock.setHost(testHost); sslSock.setPort(testPort); sslSock.setKeystoreLoc(keystoreLocation); sslSock.setCipherSuite(testCipher); sslSock.configureCipherSuites(serverType, testCipher); try { sslSock.testCiphersuites(); } catch (Exception e) { System.out.println("Exception caught testing ciphersuites\n" + e.getMessage()); e.printStackTrace(); System.exit(1); } sslSock.sendServerShutdownMsg(); sslSock.outputCipherResults(); System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/JSSE_SSLServer.java000077500000000000000000000313761326145000000226420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.*; import java.net.*; import javax.net.ssl.*; import java.security.KeyStore; import java.util.Vector; import org.mozilla.jss.*; import java.security.Provider; import java.security.Security; //note: SunPKCS11 requires JDK 1.5 or higher. //SunPKCS11 import sun.security.pkcs11.SunPKCS11; /** * JSSE SSLServer class that acts as SSL Server * * @author Sandeep.Konchady@Sun.COM * @version 1.0 */ public class JSSE_SSLServer { private int DefaultServerPort = 29753; private int port = DefaultServerPort; private String type = "SSLv3"; private String configDir = ""; private boolean bClientAuth = false; private boolean bVerbose = false; private Vector supportedCiphers = new Vector(); private CryptoManager manager; private String provider = "SunJCE"; /** * Constructs a JSSE_SSLServer. */ public JSSE_SSLServer() throws IOException { } /** * Set the provider to use. * @param p */ public void setProvider(String p) { provider = p; } /** * Get the configured provider. * @return String provider */ public String getProvider() { return provider; } /** * Set the location of keystore file. * @param fconfigDir */ public void setKeystore(String fconfigDir) { configDir = fconfigDir; } /** * Get the location of keystore file. * @return String configDir */ public String getKeystore() { return configDir; } /** * Main method to create the class server. This takes * one command line arguments, the port on which the * server accepts requests. */ public static void main(String args[]) { try { (new JSSE_SSLServer()).startSSLServer(args); } catch (Exception e) {} } /** * Start SSLServer and accept connections. * @param args */ public void startSSLServer(String[] args) throws Exception { String configDir = ""; String pwFile = ""; String nssConfig = ""; JSSE_SSLServer sslServer = new JSSE_SSLServer(); if ( args.length <= 1 ) { System.out.println( "USAGE: java JSSE_SSLServer [port] [TLS | SSLv3]" + "[ClientAuth = true | false]" + "[config directory] [keystore filename]" + "[NSS DB passwordFile]" + "[JCE || Mozilla-JSS || Sunpkcs11]"); System.out.println( "\nIf the second argument is TLS, it will start as a\n" + "TLS server, otherwise, it will be started in SSLv3 mode." + "\nIf the third argument is true,it will require\n" + "client authentication as well."); System.exit(1); } for (int i = 0; i < args.length; i++) { System.out.println(i + " = " + args[i]); } if (args.length >= 1) { port = Integer.parseInt(args[0]); } if (args.length >= 2) { type = args[1]; } if (args.length >= 3 && args[2].equals("true")) { bClientAuth = true; } if (args.length >= 4 && args.length >= 5) { configDir = args[3]; String keystore = configDir + "/" + args[4]; if ( keystore != null ) { sslServer.setKeystore(keystore); } } if (args.length >= 7 && args.length >=8 ) { if ((args[5].equalsIgnoreCase("Mozilla-JSS"))) { if (args.length >= 8) { pwFile = args[7]; } System.out.println("Initializing " + args[5]); CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues(configDir); vals.removeSunProvider = false; CryptoManager.initialize(vals); manager = CryptoManager.getInstance(); manager.setPasswordCallback( new FilePasswordCallback(pwFile) ); } else if (args[5].equalsIgnoreCase("Sunpkcs11")) { System.out.println("Sunpkcs11 requires JDK 1.5" + "at this time JSS need to build with JDK 1.4.2"); //SunPKCS11 nssConfig = args[6]; //SunPKCS11 System.out.println("Initializing " + args[5] + "-NSS"); //SunPKCS11 Provider nss = null; //SunPKCS11 nss = new sun.security.pkcs11.SunPKCS11(nssConfig); //SunPKCS11 Security.insertProviderAt(nss, 1); //SunPKCS11 System.out.println("Initialized " + args[5] + "-NSS"); } else { //use default } } Provider[] providers = Security.getProviders(); for ( int i=0; i < providers.length; i++ ) { System.out.println("Provider "+i+": "+providers[i].getName()); } // System.out.println("using port: " + port); // System.out.println("mode type " + type + " ClientAuth " + // (bClientAuth ? "true" : "false")); // System.out.println("configDir " + configDir); try { System.out.println("creating SSLSockets:"); SSLServerSocketFactory ssf = sslServer.getServerSocketFactory(type); if ( ssf != null ) { SSLServerSocket ss = (SSLServerSocket)ssf.createServerSocket(port); // Set server socket timeout to 5 minutes ss.setSoTimeout(300 * 1000); System.out.println("Enable ciphers."); // Enable all the JSSE ciphersuites ss.setEnabledCipherSuites(ss.getSupportedCipherSuites()); System.out.println("Create JSSE SSLServer"); ((SSLServerSocket)ss).setNeedClientAuth(bClientAuth); JSSE_SSLServer JSSEServ = new JSSE_SSLServer(); // accept an SSL connection int socketCntr = 0; while (true) { try { //The client will tell the server to shutdown Socket socket = ss.accept(); socket.setSoTimeout(300 * 1000); socketCntr ++; readWriteThread rwThread = new readWriteThread(socket, socketCntr); rwThread.start(); } catch (IOException ex) { System.out.println("Exception caught in " + "SSLServerSocket.accept():" + ex.getMessage()); try { ss.close(); } catch (Exception e) {} break; } } } else { if(System.getProperty("java.vendor").equals("IBM Corporation")){ System.out.println("Using IBM JDK: Cannot load keystore " + "due to strong security encryption settings\nwith " + "limited Jurisdiction policy files :\n http://" + "www-1.ibm.com/support/docview.wss?uid=swg21169931"); System.exit(0); } System.out.println("unable to initialize JSSE_SocketFactory " + "exiting!"); System.exit(1); } } catch (Exception e) { System.out.println("Unable to start JSSE_SSLServer: " + e.getMessage()); e.printStackTrace(); System.exit(1); } System.out.println("Main JSSE_SSLServer exiting."); // Exit gracefully System.exit(0); } /** * ReadWrite thread class that takes a * SSLSocket as input and read then writes * back to client. */ private class readWriteThread extends Thread { private Socket socket = null; private int socketCntr = 0; public readWriteThread(Socket sock, int cntr) { this.socket = sock; this.socketCntr = cntr; } public void run() { try { String inputLine = null; String outputLine = null; InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while (true) { try { if ((inputLine = bir.readLine()) != null) { if (inputLine.equalsIgnoreCase("shutdown")) { if (bVerbose) { System.out.println("Client told " + "JSSE_SSLServer to Shutdown!"); } is.close(); os.close(); socket.close(); System.exit(0); } outputLine = "ServerSSLSocket- " + socketCntr; if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + ": Received " + inputLine); System.out.println("Sending" + outputLine); } out.println(outputLine); out.flush(); } else { /* if you read null then quit. otherwise you * will be in endless loop with the socket * stuck in CLOSED_WAIT. */ if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + " read null aborting connection."); } break; } } catch (SocketTimeoutException ste) { System.out.println("ServerSSLSocket-" + socketCntr + " timed out: " + ste.toString()); break; } catch (IOException ex) { if (bVerbose) ex.printStackTrace(); break; } } /* close streams and close socket */ is.close(); os.close(); socket.close(); if (bVerbose) { System.out.println("ServerSSLSocket " + socketCntr + " has been Closed."); } } catch (IOException e) { e.printStackTrace(); } } } SSLServerSocketFactory getServerSocketFactory(String type) { // set up key manager to do server authentication SSLContext ctx = null; KeyManagerFactory kmf = null; KeyStore ks = null; char[] passphrase = "m1oZilla".toCharArray(); SSLServerSocketFactory ssf = null; System.setProperty("javax.net.ssl.trustStore", System.getProperty("java.home") + "/jre/lib/security/cacerts"); String certificate = "SunX509"; String javaVendor = System.getProperty("java.vendor"); if (javaVendor.equals("IBM Corporation")) certificate = "IbmX509"; System.out.println("keystore loc: " + getKeystore()); if (!(type.equals("TLS") || type.equals("SSLv3"))) { System.out.println("type must equal \'TLS\' or \'SSLv3\'\n"); System.exit(1); } try { ctx = SSLContext.getInstance(type); kmf = KeyManagerFactory.getInstance(certificate); ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream(getKeystore()), passphrase); kmf.init(ks, passphrase); ctx.init(kmf.getKeyManagers(), null, null); ssf = ctx.getServerSocketFactory(); return ssf; } catch (Exception e) { //if (Constants.debug_level > 3) e.printStackTrace(); } return ssf; } } jss-4.4.3/jss/org/mozilla/jss/tests/JSSPackageTest.java000066400000000000000000000044401326145000000227260ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; public class JSSPackageTest { public static void main(String[] args) { try { Package pkg = Package.getPackage("org.mozilla.jss"); if (pkg != null) { System.out.println("\n---------------------------------------------------------"); System.out.println("Checking jss jar and library version"); System.out.println("---------------------------------------------------------"); System.out.println(" Introspecting jss jar file"); System.out.println("Package name:\t" + pkg.getName()); System.out.println("Spec title :\t" + pkg.getSpecificationTitle()); System.out.println("Spec vendor :\t" + pkg.getSpecificationVendor()); System.out.println("Spec version:\t" + pkg.getSpecificationVersion()); System.out.println("Impl title :\t" + pkg.getImplementationTitle()); System.out.println("Impl vendor :\t" + pkg.getImplementationVendor()); System.out.println("Impl version:\t" + pkg.getImplementationVersion()); } System.out.println("\n\tFetching version information " + "from CryptoManager"); System.out.println("\n\t" + org.mozilla.jss.CryptoManager.JAR_JSS_VERSION); System.out.println("\n\tSuggested NSS/NSPR version to use " + "with this JSS:"); System.out.println("\n\t" + org.mozilla.jss.CryptoManager.JAR_NSS_VERSION); System.out.println("\t" + org.mozilla.jss.CryptoManager.JAR_NSPR_VERSION); System.out.println("\n\tTo check the JNI version in libjss4.so:"); System.out.println("\n\ttry: strings libjss4.so | grep -i header"); System.out.println("\n\tor : ident libjss4.so"); System.exit(0); } catch (Exception e) { System.out.println("Exception caught : " + e.getMessage()); e.printStackTrace(); System.exit(1); } } } jss-4.4.3/jss/org/mozilla/jss/tests/JSS_FileUploadClient.java000077500000000000000000000307341326145000000240650ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.ssl.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.*; import org.mozilla.jss.util.PasswordCallback; import java.security.*; import java.net.*; import java.io.*; public class JSS_FileUploadClient { private String clientCertNick = null; private String serverHost = null; private boolean TestCertCallBack = false; private boolean success = true; private int fCipher = -1; private int port = 29755; private String EOF = "test"; private boolean handshakeCompleted = false; private CryptoManager cm = null; private CryptoToken tok = null; private PasswordCallback cb = null; private String fPasswordFile = "passwords"; private String fCertDbPath = "."; private String fUploadFile = "foo.in"; /** * Default Constructor, do not use. */ public JSS_FileUploadClient() { } /** * Initialize the desired cipher to be set * on the socket. * @param aCipher */ public void setCipher(int aCipher) { fCipher = aCipher; } /** * Initialize the hostname to run the server * @param aHostName */ public void setHostName(String aHostName) { serverHost = aHostName; } /** * Initialize the port to run the server * @param aPort */ public void setPort(int aPort) { port = aPort; } /** * Initialize the passwords file name * @param aPasswordFile */ public void setPasswordFile(String aPasswordFile) { fPasswordFile = aPasswordFile; } /** * Initialize the cert db path name * @param aCertDbPath */ public void setCertDbPath(String aCertDbPath) { fCertDbPath = aCertDbPath; } /** * Initialize the name of the file to * be used for testing along with full path. * @param aUploadFile */ public void setUploadFile(String aUploadFile) { fUploadFile = aUploadFile; } /** * Enable/disable Test Cert Callback. * @param aTestCertCallback */ public void setTestCertCallback(boolean aTestCertCallback) { TestCertCallBack = aTestCertCallback; } /** * Set client certificate * @param aClientCertNick Certificate Nick Name */ public void setClientCertNick(String aClientCertNick) { clientCertNick = aClientCertNick; } /** * Return true if handshake is completed * else return false; * @return boolean handshake status */ public boolean isHandshakeCompleted() { return this.handshakeCompleted; } /** * Set handshakeCompleted flag to indicate * that the socket handshake is coplete. */ public void setHandshakeCompleted() { this.handshakeCompleted = true; } /** * Clear handshakeCompleted flag to indicate * that the system is now ready for another * socket connection. */ public void clearHandshakeCompleted() { this.handshakeCompleted = false; } /** * Set EOF for closing server socket * @param fEof null for closing server socket */ public void setEOF(String fEof) { this.EOF = fEof; } /** * ReadWrite thread class that takes a * SSLSocket as input and sleeps * for 2 sec between sending some test * data and receiving. * NOTE: If bufferedStream.mark(Integer.MAX_VALUE); * method is invoked then fill method of * BufferedInputStream class copies lot of data using * System.arraycopy (which in-turn use memcpy). This * causes very high CPU usage. */ private class readWriteThread extends Thread { private SSLSocket clientSock = null; private int socketCntr = 0; public readWriteThread(SSLSocket sock, int cntr) { clientSock = sock; socketCntr = cntr; } public void run() { try { String socketData = null; char[] cbuf = null; int readLength = 0; String readString = null; OutputStream os = clientSock.getOutputStream(); System.out.println("Reading file foo.in"); BufferedReader in = new BufferedReader( new FileReader(fUploadFile)); System.out.println("Successfully got a handle to " + fUploadFile); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while ((readString = in.readLine()) != null) { System.out.println("Read:" + readString); out.println(readString); out.flush(); } in.close(); out.close(); } catch (Exception e) { System.out.println("Exception caught" + e.getMessage()); e.printStackTrace(); System.exit(1); } } } /** * Initialize and create a socket connection to * SSLServer using the set parameters. */ public void doIt() throws Exception { try { CryptoManager.initialize(fCertDbPath); cm = CryptoManager.getInstance(); tok = cm.getInternalKeyStorageToken(); cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); } catch (Exception e) { } // connect to the server if ( Constants.debug_level >= 3 ) System.out.println("client about to connect..."); String hostAddr = InetAddress.getByName(serverHost).getHostAddress(); if ( Constants.debug_level >= 3 ) System.out.println("the host " + serverHost + " and the address " + hostAddr); SSLCertificateApprovalCallback approvalCallback = new TestCertApprovalCallback(); SSLClientCertificateSelectionCallback certSelectionCallback = new TestClientCertificateSelectionCallback(); SSLSocket sock = null; if (TestCertCallBack) { if ( Constants.debug_level >= 3 ) System.out.println("calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port, null, 0, new TestCertApprovalCallback(), null); } else { if ( Constants.debug_level >= 3 ) System.out.println("NOT calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port); } if ( Constants.debug_level >= 3 ) System.out.println("clientCertNick=" + clientCertNick); sock.setClientCertNickname(clientCertNick); if ( fCipher != -1 ) { sock.setCipherPreference(fCipher, true); } if ( Constants.debug_level >= 3 ) { System.out.println("Client specified cert by nickname"); System.out.println("client connected"); } // Set socket timeout to 10 sec //sock.setSoTimeout(10 * 1000); //sock.setKeepAlive(true); sock.addHandshakeCompletedListener( new HandshakeListener("client",this)); sock.forceHandshake(); readWriteThread rwThread = new readWriteThread(sock, 0); rwThread.start(); } /** * SSL Handshake Listener implementation. */ public class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_FileUploadClient boss; public HandshakeListener(String who, JSS_FileUploadClient boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } if ( Constants.debug_level >= 3 ) System.out.println(mesg); } catch(Exception e) { e.printStackTrace(); boss.setFailure(); } setHandshakeCompleted(); } } /** * Set status return value to false. */ public synchronized void setFailure() { success = false; } /** * Set status return value to success. */ public synchronized boolean getSuccess() { return success; } /** * Main method. Used for unit testing. */ public static void main(String[] args) { String certnick = "JSSCATestCert"; String testCipher = "1"; String testhost = "localhost"; int testport = 29755; int socketCntr = 1; String certDbPath = null; String passwdFile = null; String uploadFile = "foo.in"; String usage = "\nUSAGE:\n" + "java org.mozilla.jss.tests.JSS_FileUploadClient" + " [# sockets] [JSS cipher integer]\n[certdb path]" + " [password file] [upload test file] " + " [server host] [server port]"; try { if (args.length <= 0 || args[0].toLowerCase().equals("-h")) { System.out.println(usage); System.exit(1); } else { socketCntr = new Integer(args[0]).intValue(); System.out.println("Socket Counter = " + socketCntr); } testCipher = (String)args[1]; System.out.println("Test Cipher = " + testCipher); if ( args.length >= 3 ) { certDbPath = (String)args[2]; passwdFile = (String)args[3]; } if ( args.length >= 5 ) { uploadFile = (String)args[4]; testhost = (String)args[5]; testport = new Integer(args[6]).intValue(); } } catch (Exception e) { } System.out.println("Client connecting to server ..."); for ( int j=0; j 0 && !args[0].equals(".")) fCertDbPath = args[0]; if (args[1].length() > 0 && !args[1].equals("passwords")) fPasswordFile = args[1]; if (args[2].length() > 0 && !args[2].equals("localhost")) fServerHost = args[2]; if (args[3].length() > 0) fServerCertNick = args[3]; } catch (Exception e) {} CryptoManager.initialize(fCertDbPath); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); if (args[4].equalsIgnoreCase("true") == true) { TestInetAddress = true; } // We have to configure the server session ID cache before // creating any server sockets. SSLServerSocket.configServerSessionIDCache(10, 100, 100, null); //Disable SSL2 SSLSocket.enableSSL2Default(false); //Note we will use the NSS default enabled ciphers suites // open the server socket and bind to the port if ( Constants.debug_level >= 3 ) System.out.println("Server about .... to create socket"); if (TestInetAddress) { if ( Constants.debug_level >= 3 ) System.out.println("the HostName " + fServerHost + " the Inet Address " + InetAddress.getByName(fServerHost)); serverSock = new SSLServerSocket(port, 5, InetAddress.getByName(fServerHost), null , true); } else { if ( Constants.debug_level >= 3 ) System.out.println("Inet set to Null"); serverSock = new SSLServerSocket(port, 5, null , null , true); } if ( Constants.debug_level >= 3 ) System.out.println("Server created socket"); //serverSock.setSoTimeout(120 * 1000); serverSock.requireClientAuth(SSLSocket.SSL_REQUIRE_NO_ERROR); serverSock.setServerCertNickname(fServerCertNick); if ( Constants.debug_level >= 3 ) System.out.println("Server specified cert by nickname"); System.out.println("Server ready to accept connections"); while ( true ) { // accept the connection sock = (SSLSocket) serverSock.accept(); //sock.setKeepAlive(true); sock.addHandshakeCompletedListener( new HandshakeListener("server", this)); socketCntr++; readWriteThread rwThread = new readWriteThread(sock, socketCntr); rwThread.start(); } } /** * ReadWrite thread class that takes a * SSLSocket as input and sleeps * for 2 sec between sending some test * data and receiving. */ private class readWriteThread extends Thread { private SSLSocket socket = null; private int socketCntr = 0; public readWriteThread(SSLSocket sock, int cntr) { this.socket = sock; this.socketCntr = cntr; } public void run() { try { String socketData = null; char[] cbuf = null; int readLength = 0; String readString = null; InputStream is = socket.getInputStream(); BufferedReader in = new BufferedReader( new InputStreamReader(is)); long timeInMs = new Date().getTime(); while ((readString = in.readLine()) != null) { long now = new Date().getTime(); System.out.print("Read " + readString.getBytes().length + "bytes in " + (now-timeInMs) + "\n"); timeInMs = now; } } catch (Exception e) { System.out.println("Exception caught in readWriteThread.run()\n"); e.printStackTrace(); System.exit(1); } } } public static class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_FileUploadServer boss; public HandshakeListener(String who, JSS_FileUploadServer boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } if ( Constants.debug_level >= 3 ) System.out.println(mesg); } catch(Exception e) { e.printStackTrace(); boss.setFailure(); } } } public synchronized void setFailure() { success = false; } public synchronized boolean getSuccess() { return success; } } jss-4.4.3/jss/org/mozilla/jss/tests/JSS_SelfServClient.java000077500000000000000000001110571326145000000235700ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.KeyDatabaseException; import org.mozilla.jss.ssl.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.IncorrectPasswordException; import org.mozilla.jss.util.PasswordCallback; import org.mozilla.jss.util.Debug; import java.security.*; import java.net.*; import java.io.*; import java.util.*; /************** * Note on how to use JSS_SelfServServer and JSS_SelfServerClient * * For debugging purposes you should modify Constant.java debug_level to 4. * * First create db's and certificates * java -cp jss4.jar org.mozilla.jss.tests.SetupDBs . ./passwords * java -cp jss4.jar org.mozilla.jss.tests.GenerateTestCert . /passwords * localhost SHA-256/RSA CA_RSA Client_RSA Server_RSA * * Start the server: * * java -cp ./jss4.jar org.mozilla.jss.tests.JSS_SelfServServer . passwords * localhost false 2921 verboseoff * * Start the client with 4 threads using ciphersuite 0x33. * Look at the file Constant.java for the ciphersuites values. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 2 0x33 * . localhost 2921 verboseoff JSS Client_RSA * * If you envoke the client with a ciphersuite value -1 * then all current JSS ciphersuites will be tested fox X number of * threads, and once all ciphersuites have been tested the client * will closed all client SSLSockets and then tell the server to * shutdown. This case is for the nightly automated tests. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 4 -1 * . passwords localhost 2921 verboseoff JSS */ interface ConstantsBase { // Test all implemented ciphersuites public static final int TEST_CIPHERS = -1; } public class JSS_SelfServClient implements ConstantsBase, Constants { private String clientCertNick = "default"; private String serverHost = "localhost"; private String ciphersuiteTested = null; private boolean TestCertCallBack = false; private boolean success = true; private int fCipher = TEST_CIPHERS; private int aWorkingCipher = 0; private boolean bTestCiphers = true; private String CipherName = null; private int port = 29754; private String EOF = "test"; private boolean handshakeCompleted = false; private boolean bVerbose = false; private boolean bFipsMode = false; /* ciphersuites to test */ private ArrayList ciphersToTest = new ArrayList(); private CryptoManager cm = null; private CryptoToken tok = null; private PasswordCallback cb = null; private String fPasswordFile = "passwords"; private String fCertDbPath = "."; private ArrayList sockList = new ArrayList(); /* h_ciphers is for ciphersuite that were able to successfully * connect to the server */ private ArrayList h_ciphers = new ArrayList(); /* f_ciphers is for ciphersuite that failed to connect to the server */ private ArrayList f_ciphers = new ArrayList(); private int sockID = 0; /* JSS only needs to be initailized for one instance */ private static boolean bJSS = false; private ThreadGroup socketThreads = new ThreadGroup("SSLSockets"); public void setTestCiphers(boolean t) { bTestCiphers = t; } public boolean getTestCiphers() { return bTestCiphers; } /** * Default Constructor. */ public JSS_SelfServClient() { if (Constants.debug_level > 3) { bVerbose = true; } /* *if (bVerbose) { * for (int i = 0; i < jssCipherSuites.length; i++) { * System.out.println(jssCipherSuites[i].name + " " + * Integer.toHexString(jssCipherSuites[i].value) ); * } *} */ } public void setVerbose(boolean v) { bVerbose = v; } /** * returns true if JSS is sync with NSS ciphersuites. */ public boolean testJSSCiphersMatchNSS() { initJSS(); boolean cipherSuites = true; int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; i++) { //if we do not find the ciphersuite than the JSS // table is out of date. if (Constants.cipher.cipherToString(ciphers[i]) == null) { cipherSuites = false; System.out.println("JSS does not support ciphersuite: " + Integer.toHexString(ciphers[i])); } } if (!cipherSuites) { System.out.println("ERROR: NSS has implemented " + "ciphersuites that JSS does not support!\n"); System.out.println("see http://mxr.mozilla.org/nss/" + "source/lib/ssl/sslproto.h"); System.out.println("Update org/mozilla/jss/ssl/" + "SSLSocket.java"); System.out.println("Update org/mozilla/jss/tests/" + "Constants.java"); System.out.println("NSS implemented ciphersuites " + "missing from JSS"); } return cipherSuites; } public void configureDefaultSSLOptions() { initJSS(); try { //Disable SSL2 SSLSocket.enableSSL2Default(false); //if in FIPS mode disable SSL3 if (bFipsMode) SSLSocket.enableSSL3Default(false); } catch (SocketException ex) { ex.printStackTrace(); System.exit(1); } } public void configureCipherSuites(String server) { int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); boolean testCipher; for (int i = 0; i < ciphers.length; ++i) { String ciphersuite = Constants.cipher.cipherToString(ciphers[i]); testCipher = true; if (bVerbose) { System.out.print(ciphersuite); } // This class uses the TLS versions that NSS enables by default. // Until NSS enables TLS 1.2 by default, don't test the cipher // suites that only work in TLS 1.2. if ((ciphersuite.indexOf("_SHA256") != -1) || (ciphersuite.indexOf("_SHA384") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } if (server.equalsIgnoreCase("JSS")) { //For JSS SSLServer don't test if ((ciphersuite.indexOf("_DHE_") != -1) || (ciphersuite.indexOf("SSL2") != -1) || //Need to figure out why _ECDH_RSA don't work ( (ciphersuite.indexOf("RSA") != -1) && (ciphersuite.indexOf("_ECDH_") != -1)) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (server.equalsIgnoreCase("JSSE")) { //For JSSE SSLServers don't test if ((ciphersuite.indexOf("SSL2_") != -1) || (ciphersuite.indexOf("_ECDHE_") != -1) || (ciphersuite.indexOf("_ECDH_") != -1) || (ciphersuite.indexOf("_CAMELLIA_") != -1) || (ciphersuite.indexOf("_SEED_") != -1) || (ciphersuite.indexOf("_DHE_DSS_") != -1) || (ciphersuite.indexOf("_EXPORT1024_") != -1) || (ciphersuite.indexOf("_RSA_FIPS_") != -1) || (ciphersuite.indexOf("EXPORT_WITH_RC2") != -1) || (ciphersuite.indexOf("_ECDSA_") != -1) || (ciphersuite.indexOf("_256_") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (server.equalsIgnoreCase("Mozilla-JSS")) { //For JSSE Mozilla-JSS SSLServers don't test if ((ciphersuite.indexOf("SSL2_") != -1) || (ciphersuite.indexOf("_ECDHE_") != -1) || (ciphersuite.indexOf("_ECDH_") != -1) || (ciphersuite.indexOf("_CAMELLIA_") != -1) || (ciphersuite.indexOf("_SEED_") != -1) || (ciphersuite.indexOf("_DHE_DSS_") != -1)|| (ciphersuite.indexOf("_EXPORT1024_") != -1) || (ciphersuite.indexOf("_RSA_FIPS_") != -1) || (ciphersuite.indexOf("EXPORT_WITH_RC2") != -1) || (ciphersuite.indexOf("_ECDSA_") != -1) || (ciphersuite.indexOf( "SSL3_DHE_RSA_WITH_3DES_EDE_CBC_SHA") != -1) || (ciphersuite.indexOf( "SSL3_RSA_WITH_3DES_EDE_CBC_SHA") != -1) || (ciphersuite.indexOf( "SSL3_DHE_RSA_WITH_DES_CBC_SHA") != -1)|| (ciphersuite.indexOf( "SSL3_RSA_WITH_DES_CBC_SHA") != -1) || (ciphersuite.indexOf( "SSL3_RSA_EXPORT_WITH_RC4_40_MD5") != -1) || (ciphersuite.indexOf("_256_") != -1) ) { if (bVerbose) System.out.print(" -"); testCipher = false; } } if (testCipher) { if (bFipsMode) { try { if (SSLSocket.isFipsCipherSuite(ciphers[i])) { ciphersToTest.add(new Integer(ciphers[i])); if (bVerbose) System.out.print(" - FIPS Testing"); } else if (bVerbose) System.out.print(" -"); } catch (SocketException ex) { ex.printStackTrace(); } } else { ciphersToTest.add(new Integer(ciphers[i])); if (bVerbose) System.out.print(" - Testing"); } } } if (bVerbose) System.out.print("\n"); if(bVerbose) System.out.println("\nTesting " + ciphersToTest.size() + " ciphersuites."); } /** *For every enabled ciphersuite created numOfThreads connections. */ public void testCiphersuites(int numOfThreads) { Iterator iter = ciphersToTest.iterator(); setTestCiphers(true); while (iter.hasNext()) { setCipher(((Integer)iter.next()).intValue()); try { createSSLConnections(numOfThreads); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } } /** * Initialize the desired ciphersuite to be set * on the socket. * @param aCipher */ public void setCipher(int aCipher) { initJSS(); int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); ciphersuiteTested = Constants.cipher.cipherToString(aCipher); if (bVerbose || !bTestCiphers) { System.out.println("Testing " + Integer.toHexString(aCipher) + " " + ciphersuiteTested); } if (ciphersuiteTested != null) { fCipher = aCipher; } else { System.out.print("ciphersuite not supported"); System.exit(1); } try { if (cm.FIPSEnabled() && !SSLSocket.isFipsCipherSuite(aCipher)) { System.out.println("You are trying to test a non FIPS " + "ciphersuite when FIPS is enabled!"); System.exit(1); } } catch (SocketException ex) { ex.printStackTrace(); } //Disable all Ciphers we only want the one cipher //to be turned on for (int i = 0; i < ciphers.length; i++) { try { if (SSLSocket.getCipherPreferenceDefault(ciphers[i])) { // System.out.println("Implemented Cipher Suite: " + // Integer.toHexString(ciphers[i]) + " is ON"); SSLSocket.setCipherPreferenceDefault(ciphers[i], false); } } catch (SocketException ex) { ex.printStackTrace(); } } //note all ciphers are disabled but the ciphersuite to be tested //will only be enabled in the method createSSLSocket } /** * Initialize the hostname to run the server * @param aHostName */ public void setHostName(String aHostName) { serverHost = aHostName; } /** * Initialize the port to run the server * @param aPort */ public void setPort(int aPort) { port = aPort; } /** * Initialize the passwords file name * @param aPasswordFile */ public void setPasswordFile(String aPasswordFile) { fPasswordFile = aPasswordFile; } /** * Initialize the cert db path name * @param aCertDbPath */ public void setCertDbPath(String aCertDbPath) { fCertDbPath = aCertDbPath; } /** * Enable/disable Test Cert Callback. * @param aTestCertCallback */ public void setTestCertCallback(boolean aTestCertCallback) { TestCertCallBack = aTestCertCallback; } /** * Set client certificate * @param aClientCertNick Certificate Nick Name */ public void setClientCertNick(String aClientCertNick) { clientCertNick = aClientCertNick; X509Certificate certs[]; try { certs = cm.findCertsByNickname(clientCertNick); if (certs.length == 0) { System.out.println("unable to find cert nickname: " + clientCertNick); System.exit(1); } } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } } /** * Return true if handshake is completed * else return false; * @return handshake status */ public boolean isHandshakeCompleted() { return this.handshakeCompleted; } /** * Set handshakeCompleted flag to indicate * that the socket handshake is coplete. */ public void setHandshakeCompleted() { this.handshakeCompleted = true; } /** * Clear handshakeCompleted flag to indicate * that the system is now ready for another * socket connection. */ public void clearHandshakeCompleted() { this.handshakeCompleted = false; } /** * returns the total number SSLSockets created. */ public int getSockTotal() { return sockID; } /** * ReadWrite thread class that takes a * SSLSocket as input and sleeps * for 1 sec between sending some test * data and receiving. */ private class readWriteThread extends Thread { private SSLSocket clientSock = null; private String socketID = null; private String ciphersuite; public readWriteThread(ThreadGroup tgOb, String tName, String cs, SSLSocket sock) { super(tgOb, tName); if (bVerbose) { System.out.println("New thread: " + this); } ciphersuite = cs; clientSock = sock; socketID = tName; } public void run() { try { String outputLine = null; String inputLine = null; InputStream is = clientSock.getInputStream(); OutputStream os = clientSock.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while (true) { outputLine = ciphersuite + ":" + socketID + "\n"; if (bVerbose) { System.out.println("Sending: " + outputLine); } out.print(outputLine); out.flush(); inputLine = bir.readLine(); if (bVerbose) { System.out.println("Received: " + inputLine + " on Client-" + socketID); } Thread.sleep(50); } } catch (InterruptedException e) { e.printStackTrace(); } catch (java.net.SocketTimeoutException e) { e.printStackTrace(); } catch (IOException e) { if ((e.getMessage().equalsIgnoreCase( "SocketException cannot read on socket")) || (e.getMessage().equalsIgnoreCase( "Socket has been closed, and cannot be reused.")) ) { //System.out.println("SSLSocket " // + socketID + " has been closed."); } else e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } private void initJSS() { if (bJSS) { return; /* JSS already initialized */ } try { CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues(fCertDbPath); CryptoManager.initialize(vals); cm = CryptoManager.getInstance(); if (cm.FIPSEnabled()) { System.out.println("The database is in FIPSMODE"); bFipsMode = true; } tok = cm.getInternalKeyStorageToken(); cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); bJSS = true; if (bVerbose) { Debug.setLevel(Debug.OBNOXIOUS); } }catch (KeyDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (CertDatabaseException ex) { ex.printStackTrace(); System.exit(1); } catch (CryptoManager.NotInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } catch (AlreadyInitializedException ex) { ex.printStackTrace(); System.exit(1); } catch (GeneralSecurityException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (IncorrectPasswordException ex) { ex.printStackTrace(); System.exit(1); } } public boolean isServerAlive() { boolean isServerAlive = false; try { SSLSocket s = null; if (bVerbose) System.out.println("Confirming Server is alive "); //TLS_RSA_WITH_AES_128_CBC_SHA works in FIPS and Non FIPS mode. //and with JSS and JSSE SSL servers. setCipher(SSLSocket.TLS_RSA_WITH_AES_128_CBC_SHA); System.out.println("Testing Connection:" + serverHost + ":" + port); for (int i = 0; i < 20; i++) { s = createSSLSocket(); if (s != null) break; Thread.sleep(1000); } if (s != null) { s.close(); isServerAlive = true; } } catch (InterruptedException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } return isServerAlive; } /** * sendServerShutdownMsg */ public void sendServerShutdownMsg() { try { SSLSocket s = null; if (bVerbose) System.out.println("Sending shutdown message " + "to server."); if (aWorkingCipher == 0) { System.out.println("no ciphersuite was able to connect to " + "the server!"); System.exit(1); } setCipher(aWorkingCipher); s = createSSLSocket(); if (s == null) throw new IOException("Unable to connect to server"); OutputStream os = s.getOutputStream(); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); out.println("shutdown"); out.flush(); out.close(); s.close(); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } } /** * closes the SSLSocket */ public void closeAllSockets() { try { SSLSocket s; long start = System.currentTimeMillis(); Iterator sIter = sockList.iterator(); while (sIter.hasNext()) { s = (SSLSocket) sIter.next(); s.close(); } System.out.println("Waiting till all threads are dead"); int i = 0; while (socketThreads.activeCount() > 0) { Thread.sleep(10); System.out.println("ActiveCount" + socketThreads.activeCount()); //This loop should always exit but it has the potential //to hang the QA tests so... if (i == 100) { // 100 x 10 System.out.println("It is taking too long for the " + "threads to die. Exiting the program"); System.out.println("Time taken: " + (System.currentTimeMillis() - start) + " Milliseconds"); /* while all the threads have not completed cleanup. */ /* the functional test of each configured cihpersuite */ /* successfully established a connection. */ /* Let remaining threads die when this application */ /* ends execution */ return; } i++; } System.out.println("All threads are dead. Time taken: " + (System.currentTimeMillis() - start) + " Milliseconds."); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } catch (InterruptedException ex) { ex.printStackTrace(); System.exit(1); } } /** * returns a connected SSLSocket or null if unable to connect. */ private SSLSocket createSSLSocket() { SSLSocket sock = null; try { // connect to the server if ( bVerbose ) System.out.println("client about to connect..."); String hostAddr = InetAddress.getByName(serverHost).getHostAddress(); if ( bVerbose ) System.out.println("the host " + serverHost + " and the address " + hostAddr); if (TestCertCallBack) { if ( bVerbose ) System.out.println("calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port, null, 0, new TestCertificateApprovalCallback(), null); } else { if ( bVerbose ) System.out.println("NOT calling approvalCallBack"); sock = new SSLSocket(InetAddress.getByName(hostAddr), port); } if (clientCertNick.equalsIgnoreCase("default")) { sock.setClientCertNickname("Client_RSA"); sock.setClientCertNickname("Client_ECDSA"); sock.setClientCertNickname("Client_DSS"); } else { sock.setClientCertNickname(clientCertNick); if ( bVerbose ) { System.out.println("Client specified cert by nickname"); } } //Ensure the ciphersuite is disable, then enabled only it. if (sock.getCipherPreference(fCipher)) { System.out.println("Ciphersuite should have been disabled?"); System.exit(1); } else { sock.setCipherPreference(fCipher, true); } sock.addHandshakeCompletedListener( new HandshakeListener("client",this)); sock.forceHandshake(); sock.setSoTimeout(10*1000); sockList.add(sock); sockID++; aWorkingCipher = fCipher; if ( bVerbose ) { System.out.println("client connected"); } } catch (SocketException ex) { if (bTestCiphers) { sock = null; } else { ex.printStackTrace(); System.exit(1); } } catch (UnknownHostException ex) { ex.printStackTrace(); System.exit(1); } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } return sock; } public void outputCipherResults() { String banner = new String ("\n-------------------------------------------------------\n"); System.out.println(banner); System.out.println("JSS has " + org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites().length + " ciphersuites and " + ciphersToTest.size() + " were configured and tested."); if (ciphersToTest.size() == h_ciphers.size()) { System.out.println("All " + ciphersToTest.size() + " configured ciphersuites tested Successfully!\n"); } if (!h_ciphers.isEmpty()) { if (!f_ciphers.isEmpty()) { System.out.println(banner); System.out.println(h_ciphers.size() + " ciphersuites successfully connected to the "+ "server\n"); } Iterator iter = h_ciphers.iterator(); while (iter.hasNext()) { System.out.println((String) iter.next()); } } if (bFipsMode) { System.out.println("Note: ciphersuites that have the prefix " + "\"SSL\" or \"SSL3\" were used in TLS mode."); } if (ciphersToTest.size() != (h_ciphers.size() + f_ciphers.size())) { System.out.println("ERROR: did not test all expected ciphersuites"); } if (!f_ciphers.isEmpty()) { System.out.println(banner); System.out.println(f_ciphers.size() + " ciphersuites that did not connect to the "+ "server\n\n"); Iterator iter = f_ciphers.iterator(); while (iter.hasNext()) { System.out.println((String) iter.next()); } System.out.println("we should have no failed ciphersuites!"); System.exit(1); } System.out.println(banner); } /** * Initialize given number of SSLSocket client connection to the * SSLServer using the set parameters. Each Connection will have * a separate thread performing I/O to the Server. */ public void createSSLConnections(int numToCreate) throws Exception { SSLSocket sock = null; initJSS(); for (int i = 1; i <= numToCreate; i++) { sock = createSSLSocket(); if (sock != null) { String threadName = new String(sockID + "-" + i); readWriteThread rwThread = new readWriteThread(socketThreads, threadName, ciphersuiteTested, sock); rwThread.start(); if (i == 1) { h_ciphers.add(ciphersuiteTested); } } else { /* ciphersuite failed */ if (bTestCiphers) { f_ciphers.add(ciphersuiteTested); } break; } } if ( bVerbose ) { System.out.println("Active thread count: " + socketThreads.activeCount()); System.out.println("Total threads created: " + getSockTotal()); } } /** * SSL Handshake Listener implementation. */ public class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_SelfServClient boss; public HandshakeListener(String who, JSS_SelfServClient boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } if ( bVerbose ) { System.out.println(mesg); } } catch(Exception e) { e.printStackTrace(); System.exit(1); } setHandshakeCompleted(); } } /** * Set status return value to false. */ public synchronized void setFailure() { success = false; } /** * Set status return value to success. */ public synchronized boolean getSuccess() { return success; } /** * Main method. Used for unit testing. */ public static void main(String[] args) { String certnick = "default"; int testCipher = TEST_CIPHERS; String testhost = "localhost"; int testport = 29754; int numOfThreads = 10; String certDbPath = null; String passwdFile = null; boolean bVerbose = false; String server = "JSS"; try { Thread.sleep(3*1000); } catch (InterruptedException ex) { ex.printStackTrace(); } String usage = "\nUSAGE:\n" + "java org.mozilla.jss.tests.JSS_SelfServClient" + " [# sockets] [JSS cipher hex code \"0xC013\" value or -1] " + "\n\nOptional:\n" + "[certdb path] [password file] [server host] [server port]" + "[verbose] [server = JSS or JSSE] [ClientCert]"; try { if (args.length <= 0 || args[0].toLowerCase().equals("-h")) { System.out.println(usage); System.exit(1); } else { numOfThreads = new Integer(args[0]).intValue(); System.out.println("Number of Threads to create: " + numOfThreads); } if (args.length >= 2) { if (args[1].startsWith("0x") || args[1].startsWith("0X")) { testCipher = Integer.decode(args[1]).intValue(); } else { testCipher = new Integer(args[1]).intValue(); } } if (args.length >= 3) { certDbPath = (String)args[2]; } if (args.length >= 4) { passwdFile = (String)args[3]; } if (args.length >= 5) { testhost = (String)args[4]; } if (args.length >= 6) { testport = new Integer(args[5]).intValue(); } if ((args.length >= 7) && args[6].equalsIgnoreCase("verbose") == true) { System.out.println("verbose mode enabled."); bVerbose = true; } if (args.length >= 8) { server = args[7].toUpperCase(); } if (args.length >=9) { certnick = (String)args[8]; System.out.println("certnickname: " + certnick); } } catch (Exception e) { System.out.println("Unknown exception : " + e.getMessage()); System.exit(1); } System.out.println("Client connecting to server: " + testhost + ":" + testport); JSS_SelfServClient jssTest = new JSS_SelfServClient(); try { if ( !testhost.equals("localhost") ) jssTest.setHostName(testhost); if ( testport != 29754 ) jssTest.setPort(testport); jssTest.setPasswordFile(passwdFile); jssTest.setCertDbPath(certDbPath); jssTest.setVerbose(bVerbose); jssTest.initJSS(); if (!jssTest.testJSSCiphersMatchNSS()) { System.out.println("JSS needs to update the ciphersuites!"); System.exit(1); } jssTest.setTestCertCallback(true); jssTest.configureDefaultSSLOptions(); if ( certDbPath != null ) jssTest.setCertDbPath(certDbPath); if ( passwdFile != null ) jssTest.setPasswordFile(passwdFile); if (!jssTest.isServerAlive()) { System.out.println("Server " + testhost + ":" + testport + " is not Alive.\nIf this test was ran by " + "all.pl look at the server invocation for failures " + "and check network issues."); System.exit(1); } if (testCipher != TEST_CIPHERS) { jssTest.setClientCertNick(certnick); jssTest.setTestCiphers(false); jssTest.setCipher(testCipher); jssTest.createSSLConnections(numOfThreads); } else { jssTest.configureCipherSuites(server); jssTest.testCiphersuites(numOfThreads); } } catch (Exception ex) { System.out.println(ex.getMessage()); ex.printStackTrace(); System.exit(1); } if (jssTest.getSockTotal() == 0 ) { System.out.println("No SSLSockets created check your " + "configuration."); System.exit(1); } // choose how to exit the program System.out.println(jssTest.getSockTotal() + " SSLSockets created."); System.out.println("Each created SSLSocket is reading/writing to" + " the SSLServer."); if (jssTest.getTestCiphers()) { try { //Sleep for 30 seconds Thread.sleep(30*1000); } catch (InterruptedException ex) { ex.printStackTrace(); System.exit(1); } jssTest.closeAllSockets(); jssTest.sendServerShutdownMsg(); jssTest.outputCipherResults(); System.exit(0); } System.out.println("You can choose to exit the program enter:" + "\n\t\'A\' to abort with out closing the sockets." + "\n\t\'C\' to close all client sockets (server will not quit)" + "\n\tor any other letter to close all sockets and tell the" + "server to quit."); try { BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); String p = stdin.readLine(); if (p.equalsIgnoreCase("a")) { System.out.println("Aborting with out closing SSLSockets."); } else { jssTest.closeAllSockets(); if (!p.equalsIgnoreCase("c")) { //shutdown the server jssTest.sendServerShutdownMsg(); } } } catch (IOException ex) { ex.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/JSS_SelfServServer.java000077500000000000000000000344731326145000000236260ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.IOException; import org.mozilla.jss.ssl.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.PasswordCallback; import java.util.Vector; import java.net.InetAddress; import java.net.SocketTimeoutException; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.InputStream; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import org.mozilla.jss.util.Debug; /************** * Note on how to use JSS_SelfServServer and JSS_SelfServerClient * * For debugging purposes you should modify Constant.java debug_level to 4. * * First create db's and certificates * java -cp jss4.jar org.mozilla.jss.tests.SetupDBs . ./passwords * java -cp jss4.jar org.mozilla.jss.tests.GenerateTestCert . /passwords * localhost SHA-256/RSA CA_RSA Client_RSA Server_RSA * * Start the server: * * java -cp ./jss4.jar org.mozilla.jss.tests.JSS_SelfServServer . passwords localhost * false 2921 verboseoff * * Start the client with 4 threads using ciphersuite 0x33. * Look at the file Constant.java for the ciphersuites values. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 2 0x33 * . localhost 2921 verboseoff JSS Client_RSA * * If you envoke the client with a ciphersuite value -1 * then all current JSS ciphersuites will be tested fox X number of * threads, and once all ciphersuites have been tested the client * will closed all client SSLSockets and then tell the server to * shutdown. This case is for the nightly automated tests. * * java -cp jss4.jar org.mozilla.jss.tests.JSS_SelfServClient 4 -1 * . passwords localhost 2921 verboseoff JSS */ public class JSS_SelfServServer { private static Vector jssSupportedCiphers = new Vector(); private static SSLServerSocket serverSock = null; private static SSLSocket sock = null; public static void main(String[] args) throws Exception { try { (new JSS_SelfServServer()).doIt(args); } catch (Exception e) { System.out.println("JSS_SelfServServer exiting with Exception " + e.getMessage()); System.exit(1); } System.exit(0); } private String fServerCertNick = null; private String fServerHost = "localhost"; private String fPasswordFile = "passwords"; private String fCertDbPath = "."; private boolean TestInetAddress = false; private boolean success = true; private boolean bVerbose = false; public int port = 29754; public static String usage = "\nUSAGE:\njava JSS_SelfServServer"+ " [certdb path] [password file]\n"+ "[server_host_name] [testInetAddress: true|false]" + " "; public void JSS_SelfServServer() { if (Constants.debug_level > 3) { bVerbose = true; } } public void doIt(String[] args) throws Exception { if ( args.length < 5 || args[0].toLowerCase().equals("-h")) { System.out.println(usage); System.exit(1); } try { if (!args[0].equals(".")) fCertDbPath = args[0]; if (!args[1].equals("passwords")) fPasswordFile = args[1]; if (!args[2].equals("localhost")) fServerHost = args[2]; if (args[3].equalsIgnoreCase("true") == true) TestInetAddress = true; if (args.length >= 5) port = new Integer(args[4]).intValue(); if (args.length >=6 && args[5].equalsIgnoreCase("verbose")) { bVerbose = true; } if (args.length >=7 && !args[6].equalsIgnoreCase("default")) { fServerCertNick = args[6]; } } catch (Exception e) { System.out.println("Error parsing command line " + e.getMessage()); System.out.println(usage); System.exit(1); } if (bVerbose) System.out.println("initializing JSS"); CryptoManager.initialize(fCertDbPath); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(fPasswordFile); tok.login(cb); if (bVerbose) { Debug.setLevel(Debug.OBNOXIOUS); } // We have to configure the server session ID cache before // creating any server sockets. SSLServerSocket.configServerSessionIDCache(10, 100, 100, null); if (cm.FIPSEnabled()) { /* turn on only FIPS ciphersuites */ /* Disable SSL2 and SSL3 ciphers */ SSLSocket.enableSSL2Default(false); SSLSocket.enableSSL3Default(false); //Enable only FIPS ciphersuites. int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { if (SSLSocket.isFipsCipherSuite(ciphers[i])) { /* enable the FIPS ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], true); } else if (SSLSocket.getCipherPreferenceDefault( ciphers[i])) { /* disable the non fips ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], false); } } } else { /* turn on all implemented ciphersuites the server certificate * will determine if the ciphersuites can be used. */ int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { try { SSLSocket.setCipherPreferenceDefault(ciphers[i], true); if (bVerbose) { System.out.println(Constants.cipher.cipherToString( ciphers[i]) + " " + Integer.toHexString(ciphers[i])); } } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } //disable SSL2 ciphersuites SSLSocket.enableSSL2Default(false); } // open the server socket and bind to the port if (bVerbose) System.out.println("JSS_SelfServServ about .... to create socket"); if (TestInetAddress) { if (bVerbose) System.out.println("JSS_SelfServServ HostName " + fServerHost + " the Inet Address " + InetAddress.getByName(fServerHost)); serverSock = new SSLServerSocket(port, 5, InetAddress.getByName(fServerHost), null , true); } else { if (bVerbose) System.out.println("Inet set to Null"); serverSock = new SSLServerSocket(port, 5, null , null , true); } if (bVerbose) System.out.println("JSS_SelfServServ created socket"); serverSock.setSoTimeout(600*1000); // Set timeout for 10 minutes serverSock.requireClientAuth(SSLSocket.SSL_REQUIRE_NO_ERROR); serverSock.setServerCertNickname("Server_ECDSA"); serverSock.setServerCertNickname("Server_RSA"); serverSock.setServerCertNickname("Server_DSS"); if (bVerbose) System.out.println("JSS_SelfServServ specified cert by nickname"); System.out.println("JSS_SelfServServ " + fServerHost + " ready to accept connections on " + port); int socketCntr = 0; try { while ( true ) { // accept the connection sock = (SSLSocket) serverSock.accept(); sock.addHandshakeCompletedListener( new HandshakeListener("server", this)); socketCntr++; sock.setSoTimeout(300*1000); if (bVerbose) { System.out.println("Timeout value for SSL sockets: " + sock.getSoTimeout() + " milliseconds"); } readWriteThread rwThread = new readWriteThread(sock, socketCntr); rwThread.start(); } } catch (SocketTimeoutException ex) { if (socketCntr == 0) { System.out.println("JSS_SelfServServ No Client attempted to " + "connect! If " + "test ran from all.pl check the client execution " + "for errors."); } else { System.out.println("JSS_SelfServServ there has been " + socketCntr + " client " + " connections but the server Accept has timed out!"); } System.out.println("JSS_SelfServServ Timeout value: " + serverSock.getSoTimeout() + " milliseconds"); ex.printStackTrace(); System.out.println("JSS_SelfServServ exiting due to timeout."); System.exit(1); } catch (Exception ex) { System.out.println("JSS_SelfServServ Exception:"); ex.printStackTrace(); System.out.println("JSS_SelfServServ exiting."); System.exit(1); } } /** * ReadWrite thread class that takes a * SSLSocket as input and read then writes * back to client. */ private class readWriteThread extends Thread { private SSLSocket socket = null; private int socketCntr = 0; public readWriteThread(SSLSocket sock, int cntr) { this.socket = sock; this.socketCntr = cntr; } public void run() { try { String inputLine = null; String outputLine = null; InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); BufferedReader bir = new BufferedReader( new InputStreamReader(is)); PrintWriter out = new PrintWriter(new BufferedWriter( new OutputStreamWriter(os))); while (true) { try { if ((inputLine = bir.readLine()) != null) { if (inputLine.equalsIgnoreCase("shutdown")) { if (bVerbose) { System.out.println("Client told " + " JSS_SelfServServer to Shutdown!"); } is.close(); os.close(); socket.close(); System.exit(0); } outputLine = "ServerSSLSocket- " + socketCntr; if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + ": Received " + inputLine); System.out.println("Sending" + outputLine); } out.println(outputLine); out.flush(); } else { /* if you read null then quit. otherwise you * will be in endless loop with the socket * stuck in CLOSED_WAIT. */ if (bVerbose) { System.out.println("ServerSSLSocket-" + socketCntr + " read null aborting connection."); } break; } } catch (SocketTimeoutException ste) { System.out.println("ServerSSLSocket-" + socketCntr + " timed out: " + ste.toString()); break; } catch (IOException ex) { break; } } /* close streams and close socket */ is.close(); os.close(); socket.close(); if (bVerbose) { System.out.println("ServerSSLSocket " + socketCntr + " has been Closed."); } } catch (IOException e) { e.printStackTrace(); } } } public static class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private JSS_SelfServServer boss; public HandshakeListener(String who, JSS_SelfServServer boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } if (Constants.debug_level > 3) System.out.println(mesg); } catch(Exception e) { e.printStackTrace(); boss.setFailure(); } } } public synchronized void setFailure() { success = false; } public synchronized boolean getSuccess() { return success; } } jss-4.4.3/jss/org/mozilla/jss/tests/KeyFactoryTest.java000066400000000000000000000176171326145000000231050ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.security.*; import java.security.spec.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.util.PasswordCallback; abstract class TestValues { protected TestValues(String keyGenAlg, String sigAlg, Class privateKeySpecClass, Class publicKeySpecClass, String provider) { this.keyGenAlg = keyGenAlg; this.sigAlg = sigAlg; this.privateKeySpecClass = privateKeySpecClass; this.publicKeySpecClass = publicKeySpecClass; this.provider = provider; } public final String keyGenAlg; public final String sigAlg; public final Class privateKeySpecClass; public final Class publicKeySpecClass; public final String provider; } class RSATestValues extends TestValues { public RSATestValues() { super("RSA", "SHA1withRSA", RSAPrivateCrtKeySpec.class, RSAPublicKeySpec.class, "SunRsaSign"); } public RSATestValues(String provider) { super("RSA", "SHA1withRSA", RSAPrivateCrtKeySpec.class, RSAPublicKeySpec.class, provider); } } class DSATestValues extends TestValues { public DSATestValues() { super("DSA", "SHA1withDSA", DSAPrivateKeySpec.class, DSAPublicKeySpec.class, "SUN"); } public DSATestValues(String provider) { super("DSA", "SHA1withDSA", DSAPrivateKeySpec.class, DSAPublicKeySpec.class, provider); } } public class KeyFactoryTest { public static void main(String argv[]) { try { if( argv.length < 2 ) { System.out.println( "Usage: java org.mozilla.jss.tests.KeyFactoryTest " + " "); System.exit(1); } CryptoManager.initialize(argv[0]); CryptoToken tok = CryptoManager.getInstance().getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(argv[1]); tok.login(cb); /* This is just a huge amount of needless info for the tinderbox and nightly QA * Provider []provs = Security.getProviders(); * for( int i=0; i < provs.length; ++i) { * System.out.println("======"); * System.out.println(provs[i].getName()); * provs[i].list(System.out); * System.out.println("======"); * } */ (new KeyFactoryTest()).doTest(); } catch(Throwable e) { e.printStackTrace(); System.exit(1); } System.exit(0); } public void doTest() throws Throwable { String javaVendor = System.getProperty("java.vendor"); RSATestValues rsa = null; DSATestValues dsa = null; boolean exception = false; if ( javaVendor.equals("IBM Corporation") ) { rsa = new RSATestValues("IBMJCE"); dsa = new DSATestValues("IBMJCE"); } else { rsa = new RSATestValues(); dsa = new DSATestValues(); } // Generate RSA private key from spec try { genPrivKeyFromSpec(rsa); } catch (java.security.spec.InvalidKeySpecException ex) { if (Constants.debug_level > 3) System.out.println("InvalidKeySpecException caught " + "genPrivKeyFromSpec(rsa): " + ex.getMessage()); if ( javaVendor.equals("IBM Corporation") ) { System.out.println("Could not generated a RSA private key from " + "a\njava.security.spec.RSAPrivateKeySpec. Not supported " + "IBMJCE"); } else { exception = true; } } catch (Exception ex) { if (Constants.debug_level > 3) System.out.println("Exception caught genPrivKeyFromSpec(rsa): " + ex.getMessage()); } // Generate DSA private key from spec try { genPrivKeyFromSpec(dsa); } catch (java.security.spec.InvalidKeySpecException ex) { if (Constants.debug_level > 3) System.out.println("InvalidKeySpecException caught " + "genPrivKeyFromSpec(dsa): " + ex.getMessage()); exception = true; } catch (Exception ex) { if (Constants.debug_level > 3) System.out.println("Exception caught genPrivKeyFromSpec(dsa): " + ex.getMessage()); } // translate RSA key try { genPubKeyFromSpec(rsa); } catch (Exception ex) { if (Constants.debug_level > 3) System.out.println("Exception caught genPubKeyFromSpec(rsa): " + ex.getMessage()); exception = true; } // translate key try { genPubKeyFromSpec(dsa); } catch (Exception ex) { if (Constants.debug_level > 3) System.out.println("Exception caught genPubKeyFromSpec(dsa): " + ex.getMessage()); exception = true; } if (exception) System.exit(1); else System.exit(0); } void genPrivKeyFromSpec(TestValues vals) throws Throwable { // generate the key pair KeyPairGenerator kpg = KeyPairGenerator.getInstance(vals.keyGenAlg, vals.provider); kpg.initialize(512); KeyPair pair = kpg.generateKeyPair(); // get the private key spec KeyFactory sunFact = KeyFactory.getInstance(vals.keyGenAlg, vals.provider); KeySpec keySpec = sunFact.getKeySpec(pair.getPrivate(), vals.privateKeySpecClass); // import it into JSS KeyFactory jssFact = KeyFactory.getInstance(vals.keyGenAlg, "Mozilla-JSS"); PrivateKey jssPrivk = jssFact.generatePrivate(keySpec); signVerify(vals.sigAlg, jssPrivk, "Mozilla-JSS", pair.getPublic(), vals.provider); System.out.println("Successfully generated a " + vals.keyGenAlg + " private key from a " + vals.privateKeySpecClass.getName()); } public void signVerify(String sigAlg, PrivateKey privk, String signProv, PublicKey pubk, String verifyProv) throws Throwable { Signature signSig = Signature.getInstance(sigAlg, signProv); signSig.initSign(privk); String toBeSigned = "blah blah blah sign me"; signSig.update(toBeSigned.getBytes("UTF-8")); byte[] signature = signSig.sign(); Signature verSig = Signature.getInstance(sigAlg, verifyProv); verSig.initVerify(pubk); verSig.update(toBeSigned.getBytes("UTF-8")); if( ! verSig.verify(signature) ) { throw new Exception( "Private/public key mismatch: signing alg=" + sigAlg + ", signing provider=" + signProv + ", verifying provider = " + verifyProv); } } void genPubKeyFromSpec(TestValues vals) throws Throwable { // generate a key pair KeyPairGenerator kpg = KeyPairGenerator.getInstance(vals.keyGenAlg, vals.provider); kpg.initialize(512); KeyPair pair = kpg.generateKeyPair(); // get the public key spec KeyFactory sunFact = KeyFactory.getInstance(vals.keyGenAlg, vals.provider); KeySpec keySpec = sunFact.getKeySpec(pair.getPublic(), vals.publicKeySpecClass); // import it into JSS KeyFactory jssFact = KeyFactory.getInstance(vals.keyGenAlg, "Mozilla-JSS"); PublicKey jssPubk = jssFact.generatePublic(keySpec); signVerify(vals.sigAlg, pair.getPrivate(), vals.provider, jssPubk, "Mozilla-JSS"); System.out.println("Successfully generated a " + vals.keyGenAlg + " public key from a " + vals.publicKeySpecClass.getName()); } } jss-4.4.3/jss/org/mozilla/jss/tests/KeyStoreTest.java000066400000000000000000000147541326145000000225710ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.KeyGenerator; import org.mozilla.jss.crypto.KeyGenAlgorithm; import org.mozilla.jss.crypto.SecretKeyFacade; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.util.ConsolePasswordCallback; import java.security.*; import java.security.cert.CertificateFactory; import java.util.Enumeration; import java.security.cert.Certificate; import java.io.*; import javax.crypto.SecretKey; public class KeyStoreTest { public static void printUsage() { System.out.println("Usage: KeyStoreTest " + " [...]"); System.out.println("Operations:\n" + "getAliases\n" + "deleteEntry . . .\n" + "getCertByName . . .\n" + "getCertByDER \n" + "getKey \n" + "addKey \n" + "isTrustedCert \n"); } public static void main(String argv[]) { try { if( argv.length < 2 ) { printUsage(); System.exit(1); } String op = argv[1]; String[] args = new String[ argv.length - 2 ]; for(int i=2; i < argv.length; ++i) { args[i-2] = argv[i]; } CryptoManager.initialize(argv[0]); CryptoManager cm = CryptoManager.getInstance(); // login to the token CryptoToken token = cm.getInternalKeyStorageToken(); //CryptoToken token = cm.getTokenByName("Builtin Object Token"); try { token.login(new ConsolePasswordCallback()); } catch(PK11Token.NotInitializedException ex) { } cm.setThreadToken(token); KeyStore ks = KeyStore.getInstance("Mozilla-JSS"); ks.load(null, null); if( op.equalsIgnoreCase("getAliases") ) { dumpAliases(ks); } else if( op.equalsIgnoreCase("deleteEntry") ) { for(int j=0; j < args.length; ++j) { ks.deleteEntry(args[j]); } } else if( op.equalsIgnoreCase("getCertByName") ) { for(int j=0; j < args.length; ++j) { dumpCert(ks, args[j]); } } else if( op.equalsIgnoreCase("getCertByDER") ) { if( args.length < 1 ) { printUsage(); System.exit(1); } getCertByDER(ks, args[0]); } else if( op.equalsIgnoreCase("getKey") ) { if( args.length != 1 ) { printUsage(); System.exit(1); } getKey(ks, args[0]); } else if( op.equalsIgnoreCase("isTrustedCert") ) { if( args.length != 1 ) { printUsage(); System.exit(1); } isTrustedCert(ks, args[0]); } else if( op.equalsIgnoreCase("addKey") ) { if( args.length != 1 ) { printUsage(); System.exit(1); } addKey(ks, args[0]); } else { printUsage(); System.exit(1); } } catch(Throwable t) { t.printStackTrace(); System.exit(1); } } public static void dumpCert(KeyStore ks, String alias) throws Throwable { Certificate cert = ks.getCertificate(alias); if( cert == null ) { System.out.println("Certificate with alias \"" + alias + "\" not found"); } else { System.out.println(cert.toString()); } } public static void dumpAliases(KeyStore ks) throws Throwable { Enumeration aliases = ks.aliases(); System.out.println("Aliases:"); while( aliases.hasMoreElements() ) { String alias = (String) aliases.nextElement(); System.out.println( "\"" + alias + "\""); } System.out.println(); } public static void getCertByDER(KeyStore ks, String derCertFilename) throws Throwable { FileInputStream fis = new FileInputStream(derCertFilename); ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] buf = new byte[1024]; int numRead; while( (numRead = fis.read(buf)) != -1 ) { bos.write(buf, 0, numRead); } ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); CertificateFactory fact = CertificateFactory.getInstance("X.509"); Certificate cert = fact.generateCertificate( bis ); String nick = ks.getCertificateAlias(cert); if( nick == null ) { System.out.println("No matching certificate was found."); } else { System.out.println("Found matching certificate \"" + nick + "\""); } } public static void getKey(KeyStore ks, String alias) throws Throwable { Key key = ks.getKey(alias, null); if( key == null ) { System.out.println("Could not find key for alias \"" + alias + "\""); System.exit(1); } else { String clazz = key.getClass().getName(); System.out.println("Found " + clazz + " for alias \"" + alias + "\""); } } public static void isTrustedCert(KeyStore ks, String alias) throws Throwable { if( ks.isCertificateEntry(alias) ) { System.out.println("\"" + alias + "\" is a trusted certificate" + " entry"); } else { System.out.println("\"" + alias + "\" is NOT a trusted certificate" + " entry"); } } public static void addKey(KeyStore ks, String alias) throws Throwable { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA", "Mozilla-JSS"); kpg.initialize(1024); KeyPair pair = kpg.genKeyPair(); Certificate [] certs = new Certificate[1]; ks.setKeyEntry(alias, pair.getPrivate(), null, certs); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); KeyGenerator kg = tok.getKeyGenerator( KeyGenAlgorithm.DES3 ); SecretKey key = new SecretKeyFacade(kg.generate()); ks.setKeyEntry(alias+"sym", key, null, null); } } jss-4.4.3/jss/org/mozilla/jss/tests/KeyWrapping.java000066400000000000000000000112311326145000000224070ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import java.security.KeyPair; /** * Keywrapping tests.. * */ public class KeyWrapping { public static void main(String args[]) { try { CryptoManager.initialize("."); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); CryptoToken keyToken = cm.getInternalKeyStorageToken(); KeyGenerator kg = token.getKeyGenerator(KeyGenAlgorithm.DES); KeyGenerator keyKg = keyToken.getKeyGenerator(KeyGenAlgorithm.DES3); SymmetricKey wrapped = kg.generate(); SymmetricKey wrapper = kg.generate(); SymmetricKey keyWrapper = keyKg.generate(); SymmetricKey keyWrapped = keyKg.clone(wrapped); // wrap a symmetric with a symmetric byte[] plaintextPre = new byte[] { (byte)0x73, (byte)0x24, (byte)0x51, (byte)0x48, (byte)0x32, (byte)0x87, (byte)0x23, (byte)0x33, (byte)0x65}; byte[] plaintext = Cipher.pad(plaintextPre, EncryptionAlgorithm.DES_ECB.getBlockSize()); System.out.println("plaintext length is " + plaintext.length); Cipher encryptor = token.getCipherContext(EncryptionAlgorithm.DES_ECB); encryptor.initEncrypt(wrapped); byte[] ciphertext = encryptor.doFinal(plaintext); System.out.println("ciphertext length is " + ciphertext.length); KeyWrapper keyWrap = token.getKeyWrapper(KeyWrapAlgorithm.DES_ECB); keyWrap.initWrap(wrapper,null); byte[] wrappedKey = keyWrap.wrap(wrapped); keyWrap.initUnwrap(wrapper, null); SymmetricKey unwrapped = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES, SymmetricKey.Usage.DECRYPT, 0); Cipher decryptor = token.getCipherContext(EncryptionAlgorithm.DES_ECB); decryptor.initDecrypt(unwrapped); byte[] recoveredPre = decryptor.doFinal(ciphertext); System.out.println("Decrypted "+ recoveredPre.length+ " bytes"); byte[] recovered = Cipher.unPad(recoveredPre, EncryptionAlgorithm.DES_ECB.getBlockSize()); System.out.println("plaintext:"); displayByteArray(plaintextPre); System.out.println("ciphertext:"); displayByteArray(ciphertext); System.out.println("recovered:"); displayByteArray(recovered); // wrap a private with a symmetric keyWrap = keyToken.getKeyWrapper(KeyWrapAlgorithm.DES3_CBC_PAD); IVParameterSpec iv = new IVParameterSpec(recovered); keyWrap.initWrap(keyWrapper,iv); KeyPairGenerator kpg = keyToken.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpg.initialize(512); kpg.temporaryPairs(true); KeyPair kp = kpg.genKeyPair(); java.security.PublicKey pub = kp.getPublic(); PrivateKey privk = (org.mozilla.jss.crypto.PrivateKey)kp.getPrivate(); wrappedKey = keyWrap.wrap(privk); System.out.println("Original key:"); displayByteArray(privk.getUniqueID()); privk = null; kp = null; //keyToken.getCryptoStore().deletePrivateKey(privk); keyWrap.initUnwrap(keyWrapper,iv); PrivateKey newPrivk = keyWrap.unwrapTemporaryPrivate(wrappedKey, PrivateKey.RSA, pub ); System.out.println("New key:"); displayByteArray(newPrivk.getUniqueID()); // wrap a symmetric with a private keyWrap = keyToken.getKeyWrapper(KeyWrapAlgorithm.RSA); keyWrap.initWrap(pub,null); wrappedKey = keyWrap.wrap(keyWrapped); keyWrap.initUnwrap(newPrivk, null); unwrapped = keyWrap.unwrapSymmetric(wrappedKey, SymmetricKey.DES, SymmetricKey.Usage.DECRYPT, 0); unwrapped = kg.clone(unwrapped); decryptor = token.getCipherContext(EncryptionAlgorithm.DES_ECB); decryptor.initDecrypt(unwrapped); recovered = decryptor.doFinal(ciphertext); System.out.println("Recovered again:"); displayByteArray(Cipher.unPad(recovered, 8)); } catch(Exception e) { e.printStackTrace(); } } public static void displayByteArray(byte[] ba) { for(int i=0; i < ba.length; i++) { System.out.print( Integer.toHexString(ba[i]&0xff) + " " ); if( (i % 26) == 25 ) { System.out.println(""); } } System.out.println(""); } } jss-4.4.3/jss/org/mozilla/jss/tests/ListCACerts.java000066400000000000000000000030251326145000000222710ustar00rootroot00000000000000package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; public class ListCACerts { public static void main(String args[]) throws Exception { if( args.length > 2) { System.out.println( "Usage: java org.mozilla.jss.tests.ListCACerts [verbose]"); System.exit(1); } try { CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); X509Certificate[] certs = cm.getCACerts(); //added verbose option to limited the output of the tinderbox // and nightly QA. System.out.println("Number of CA certs: " + certs.length); System.out.println("use option \"verbose\" if you want the CA " + "certs printed out"); if (args.length == 2 && args[1].equalsIgnoreCase("verbose")) { for(int i=0; i < certs.length; ++i ) { System.out.println(certs[i].getSubjectDN().toString()); InternalCertificate ic = (InternalCertificate) certs[i]; System.out.println("SSL: " + ic.getSSLTrust() + ", Email: " + ic.getEmailTrust() + ", Object Signing: " + ic.getObjectSigningTrust()); } } } catch(Throwable e) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/ListCerts.java000066400000000000000000000106461326145000000220740ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.io.ByteArrayInputStream; import java.security.cert.CertificateFactory; import java.util.Iterator; import java.util.Set; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.asn1.ASN1Util; import org.mozilla.jss.asn1.OBJECT_IDENTIFIER; import org.mozilla.jss.asn1.OCTET_STRING; import org.mozilla.jss.asn1.SEQUENCE; import org.mozilla.jss.crypto.*; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.pkix.cert.CertificateInfo; import org.mozilla.jss.pkix.cert.Extension; public class ListCerts { public static void main(String args[]) { try { if( args.length != 2 ) { System.out.println("Usage: ListCerts "); return; } String dbdir = args[0]; String nickname = args[1]; CryptoManager.initialize(dbdir); CryptoManager cm = CryptoManager.getInstance(); X509Certificate[] certs = cm.findCertsByNickname(nickname); System.out.println(certs.length + " certs found with this nickname."); for(int i=0; i < certs.length; i++) { System.out.println("\nSubject: "+certs[i].getSubjectDN()); Certificate cert = (Certificate)ASN1Util.decode(Certificate.getTemplate(), certs[i].getEncoded()); CertificateInfo info = cert.getInfo(); OBJECT_IDENTIFIER sigalg = info.getSignatureAlgId().getOID(); System.out.println("Signature oid " + info.getSignatureAlgId().getOID()); SEQUENCE extensions = info.getExtensions(); for (int j = 0; j < extensions.size(); j++) { Extension ext = (Extension)extensions.elementAt(i); OBJECT_IDENTIFIER oid = ext.getExtnId(); OCTET_STRING value = ext.getExtnValue(); System.out.println("Extension " + oid.toString()); if (ext.getCritical()) { System.out.println("Critical extension: " + oid.toString()); } else { System.out.println("NON Critical extension: " + oid.toString()); } } System.out.println("Convert to JDK cert"); //Convert to JDK certificate CertificateFactory cf = CertificateFactory.getInstance("X.509"); ByteArrayInputStream bais = new ByteArrayInputStream( certs[i].getEncoded()); java.security.cert.X509Certificate jdkCert = (java.security.cert.X509Certificate) cf.generateCertificate(bais); bais.close(); System.out.println("Subject " + jdkCert.getSubjectDN()); System.out.println("Signature oid " + jdkCert.getSigAlgName()); /* non critical extensions */ Set nonCritSet = jdkCert.getNonCriticalExtensionOIDs(); if (nonCritSet != null && !nonCritSet.isEmpty()) { for (Iterator j = nonCritSet.iterator(); j.hasNext();) { String oid = (String)j.next(); System.out.println(oid); } } else { System.out.println("no NON Critical Extensions"); } /* critical extensions */ Set critSet = jdkCert.getCriticalExtensionOIDs(); if (critSet != null && !critSet.isEmpty()) { System.out.println("Set of critical extensions:"); for (Iterator j = critSet.iterator(); j.hasNext();) { String oid = (String)j.next(); System.out.println(oid); } } else { System.out.println("no Critical Extensions"); } } System.out.println("END"); } catch( Exception e ) { e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/PK10Gen.java000066400000000000000000000051741326145000000212650ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.pkcs11.*; import org.mozilla.jss.pkcs11.PK11Token; import org.mozilla.jss.util.*; public class PK10Gen { public static void main(String args[]) { CryptoManager manager; Password pass1=null, pass2=null; char[] passchar1 = {'f', 'o', 'o', 'b', 'a', 'r'}; char[] passchar2 = {'n', 'e', 't', 's', 'c', 'a', 'p', 'e'}; if(args.length != 2) { System.err.println("Usage: java org.mozilla.jss.PK10Gen [rsa|dsa]"); return; } try { CryptoManager.initialize(args[0]); /* CryptoManager.initialize("secmod.db", "key3.db", "cert7.db"); CryptoManager cm = CryptoManager.getInstance(); PK11Token token = (PK11Token)cm.getInternalCryptoToken(); */ /* CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues( args[0]+"/secmodule.db", args[0]+"/key3.db", args[0]+"/cert7.db"); CryptoManager.initialize(vals); */ try { manager = CryptoManager.getInstance(); } catch( CryptoManager.NotInitializedException e ) { System.out.println("CryptoManager not initialized"); return; } CryptoToken token = (PK11Token) manager.getInternalKeyStorageToken(); if(token.isLoggedIn() == false) { System.out.println("Good, isLoggedIn correctly says we're"+ " not logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " logged in"); } pass1 = new Password( (char[]) passchar1.clone()); pass2 = new Password( new char[]{0} ); token.initPassword(pass2, pass1); pass1.clear(); pass2.clear(); System.out.println("initialized PIN"); token.login(pass1); System.out.println("logged in"); String blob = token.generateCertRequest("cn=christina Fu", 512, args[1], (byte[]) null, (byte[]) null, (byte[]) null); System.out.println("pkcs#10 blob = \n" + blob); } catch(Exception e) { System.out.println("exception caught in PK10Gen: " + e.getMessage()); e.printStackTrace(); System.exit(1); } System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/README_bbenv000066400000000000000000000043651326145000000213520ustar00rootroot00000000000000# This file has been renamed to "jss/org/mozilla/jss/tests/README_bbenv", and # the build/test procedure documented below has been replaced; the new build/test # procedure has been documented in top-level "jss/README". Procedure for building nspr/nss/jss and testing jss by using the provided sample run and bbenv scripts located in the jss/org/mozilla/jss/tests directory: 1. Create working directories: % mkdir -p work4jss/hg 2. Checkout all the needed sources: % cd work4jss/hg % hg clone https://hg.mozilla.org/projects/nspr % hg clone https://hg.mozilla.org/projects/nss % hg clone https://hg.mozilla.org/projects/jss % cd .. 3. Copy runSample.sh renaming it to run.sh: % cp hg/jss/org/mozilla/jss/tests/runSample.sh run.sh 4. Copy bbenvSample.sh renaming it to bbenv.sh: % cp hg/jss/org/mozilla/jss/tests/bbenvSample.sh bbenv.sh 5. Edit bbenv.sh to comply with the system that is being tested: (a) Set/reset the DOMSUF variable so that it can be resolved locally: NOTE: By default, DOMSUF=localdomain is set. (b) Set/reset the JAVA_HOME_64 variable in the bbenv script accordingly: On Linux (e. g. - Fedora 25), update java-1.8.0-openjdk to the latest and then run sudo /usr/sbin/alternatives --config java and hit enter. To check/select your Java version on Linux: % sudo /usr/sbin/alternatives --config java There is 1 program that provides 'java'. Selection Command ----------------------------------------------- *+ 1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc25.x86_64/jre/bin/java) Enter to keep the current selection[+], or type selection number: NOTE: You may have multiple entries (like on RHEl-7.x) or only one. Per this example, set: JAVA_HOME_64=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc25.x86_64 Alternatively, on macOS, you'll have something like this: JAVA_HOME_64=/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home 6. Build nspr, nss, and jss and run the jss tests: % run.sh 1> run.log 2>&1 7. View the results captured in the various log files, for example: % less run.log % less output/all.log % less output/tmp.log jss-4.4.3/jss/org/mozilla/jss/tests/SDR.java000066400000000000000000000037661326145000000206150ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.SecretDecoderRing; import org.mozilla.jss.util.ConsolePasswordCallback; import java.io.*; public class SDR { public static void main(String[] args) { try { CryptoManager.initialize("."); String cmd = args[0]; String infile = args[1]; String outfile = args[2]; CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalKeyStorageToken(); token.login(new ConsolePasswordCallback()); SecretDecoderRing sdr = new SecretDecoderRing(); FileInputStream fis = new FileInputStream(infile); ByteArrayOutputStream bos = new ByteArrayOutputStream(); int numread; byte[] data = new byte[1024]; while( (numread = fis.read(data)) != -1 ) { bos.write(data, 0, numread); } byte[] inputBytes = bos.toByteArray(); byte[] outputBytes; if( cmd.equalsIgnoreCase("encrypt") ) { outputBytes = sdr.encrypt(inputBytes); } else { outputBytes = sdr.decrypt(inputBytes); } FileOutputStream fos = new FileOutputStream(outfile); fos.write(outputBytes); } catch(Exception e) { e.printStackTrace(); System.exit(1); } System.exit(0); } private static char[] hex = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; private static void dumpBytes(byte[] bytes) { for(int i=0; i < bytes.length; ++i) { System.out.print(hex[(bytes[i] & 0xf0)>>4] + hex[(bytes[i] & 0xf)] + " "); } System.out.println(); } } jss-4.4.3/jss/org/mozilla/jss/tests/SSLClientAuth.java000066400000000000000000000357561326145000000226130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.security.cert.CertificateEncodingException; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.ssl.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.*; import org.mozilla.jss.pkix.cert.Certificate; import org.mozilla.jss.util.PasswordCallback; import java.util.Calendar; import java.util.Date; import java.security.*; import java.security.PrivateKey; import java.io.*; import java.net.SocketException; /** * SSLClientAuth Server/client test. */ public class SSLClientAuth implements Runnable { private CryptoManager cm; public static final SignatureAlgorithm sigAlg = SignatureAlgorithm.RSASignatureWithSHA1Digest; /** * Method that generates a certificate for given credential * * @param issuerName * @param subjectName * @param serialNumber * @param privKey * @param pubKey * @param rand * @param extensions * @throws java.lang.Exception * @return Certificate */ public static Certificate makeCert(String issuerName, String subjectName, int serialNumber, PrivateKey privKey, PublicKey pubKey, int rand, SEQUENCE extensions) throws Exception { AlgorithmIdentifier sigAlgID = new AlgorithmIdentifier( sigAlg.toOID()); Name issuer = new Name(); issuer.addCountryName("US"); issuer.addOrganizationName("Mozilla"); issuer.addOrganizationalUnitName("JSS Testing" + rand); issuer.addCommonName(issuerName); Name subject = new Name(); subject.addCountryName("US"); subject.addOrganizationName("Mozilla"); subject.addOrganizationalUnitName("JSS Testing" + rand); subject.addCommonName(subjectName); Calendar cal = Calendar.getInstance(); Date notBefore = cal.getTime(); cal.add(Calendar.YEAR, 1); Date notAfter = cal.getTime(); SubjectPublicKeyInfo.Template spkiTemp = new SubjectPublicKeyInfo.Template(); SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) ASN1Util.decode(spkiTemp, pubKey.getEncoded()); CertificateInfo info = new CertificateInfo( CertificateInfo.v3, new INTEGER(serialNumber), sigAlgID, issuer, notBefore, notAfter, subject, spki); if( extensions != null ) { info.setExtensions(extensions); } return new Certificate(info, privKey, sigAlg); } /** * * @param args * @throws java.lang.Exception */ public static void main(String[] args) throws Exception { (new SSLClientAuth()).doIt(args); } private X509Certificate nssServerCert, nssClientCert; private String serverCertNick, clientCertNick; /** * * @param args * @throws java.lang.Exception */ public void doIt(String[] args) throws Exception { if ( args.length < 2 ) { System.out.println("Usage: java org.mozilla.jss.tests." + "SSLClientAuth [port]" + " [Certificate Serial Number]"); System.exit(1); } CryptoManager.initialize(args[0]); cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); PasswordCallback cb = new FilePasswordCallback(args[1]); tok.login(cb); if (args.length >= 3) { port = new Integer(args[2]).intValue(); System.out.println("using port:" + port); } if (args.length >= 4) { serialNum = new Integer(args[3]).intValue(); } else { SecureRandom rng= SecureRandom.getInstance("pkcs11prng", "Mozilla-JSS"); serialNum = nextRandInt(rng); } X509Certificate[] certs; /* ensure certificate does not already exists */ /* we don't have to test all three */ serverCertNick = "SSLserver-"+serialNum; clientCertNick = "SSLclient-"+serialNum; certs = cm.findCertsByNickname(serverCertNick); if (certs.length == 0) { generateCerts(cm, serialNum); } else { try { nssServerCert = cm.findCertByNickname(serverCertNick); nssClientCert = cm.findCertByNickname(clientCertNick); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (ObjectNotFoundException ex) { ex.printStackTrace(); System.exit(1); } } configureDefaultSSLoptions(); useNickname = false; testConnection(); useNickname = true; testConnection(); System.out.println("Exiting main()"); if( getSuccess() ) { System.exit(0); } else { System.exit(1); } } private boolean useNickname; private void generateCerts(CryptoManager cm, int serialNum) { // RSA Key with default exponent int keyLength = 1024; try { java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance("RSA", "Mozilla-JSS"); kpg.initialize(keyLength); KeyPair caPair = kpg.genKeyPair(); //Generate CA cert SEQUENCE extensions = new SEQUENCE(); extensions.addElement(makeBasicConstraintsExtension()); Certificate caCert = makeCert("CACert", "CACert", serialNum, caPair.getPrivate(), caPair.getPublic(), serialNum, extensions); X509Certificate nssCaCert = cm.importUserCACertPackage( ASN1Util.encode(caCert), "SSLCA-"+serialNum); InternalCertificate intern = (InternalCertificate)nssCaCert; intern.setSSLTrust( InternalCertificate.TRUSTED_CA | InternalCertificate.TRUSTED_CLIENT_CA | InternalCertificate.VALID_CA); // generate server cert kpg.initialize(keyLength); KeyPair serverPair = kpg.genKeyPair(); Certificate serverCert = makeCert("CACert", "localhost", serialNum+1, caPair.getPrivate(), serverPair.getPublic(), serialNum, null); nssServerCert = cm.importCertPackage( ASN1Util.encode(serverCert), serverCertNick); // generate client auth cert kpg.initialize(keyLength); KeyPair clientPair = kpg.genKeyPair(); Certificate clientCert = makeCert("CACert", "ClientCert", serialNum+2, caPair.getPrivate(), clientPair.getPublic(), serialNum, null); nssClientCert = cm.importCertPackage( ASN1Util.encode(clientCert), clientCertNick); } catch (CertificateEncodingException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchAlgorithmException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchProviderException ex) { ex.printStackTrace(); System.exit(1); } catch (CryptoManager.NicknameConflictException ex) { ex.printStackTrace(); System.exit(1); } catch (CryptoManager.UserCertConflictException ex) { ex.printStackTrace(); System.exit(1); } catch (TokenException ex) { ex.printStackTrace(); System.exit(1); } catch (NoSuchItemOnTokenException ex) { ex.printStackTrace(); System.exit(1); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } private void configureDefaultSSLoptions() { try { //Disable SSL2 and SSL3 ciphers SSLSocket.enableSSL2Default(false); SSLSocket.enableSSL3Default(false); /* TLS is enabled by default */ /* Enable Session tickets by default */ SSLSocket.enableSessionTicketsDefault(true); /* if FIPS is enabled, configure only FIPS ciphersuites */ if (cm.FIPSEnabled()) { System.out.println("The NSS database is configured in FIPS" + "mode."); System.out.println("Enable ony FIPS ciphersuites."); int ciphers[] = org.mozilla.jss.ssl.SSLSocket.getImplementedCipherSuites(); for (int i = 0; i < ciphers.length; ++i) { if (SSLSocket.isFipsCipherSuite(ciphers[i])) { /* enable the FIPS ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], true); } else if (SSLSocket.getCipherPreferenceDefault( ciphers[i])) { /* disable the non fips ciphersuite */ SSLSocket.setCipherPreferenceDefault(ciphers[i], false); } } } } catch (SocketException ex) { System.out.println("Error configuring default SSL options."); ex.printStackTrace(); System.exit(1); } } private void testConnection() throws Exception { serverReady = false; // spawn server Thread server = new Thread(this); server.start(); // wait for server to open its socket synchronized(this) { while(!serverReady) { this.wait(); } } // connect to the server System.out.println("client about to connect"); SSLSocket sock = new SSLSocket("localhost", port); if( useNickname ) { sock.setClientCertNickname(clientCertNick); System.out.println("Client specified cert by nickname"); } else { sock.setClientCert(nssClientCert); System.out.println("Client specified cert directly"); } System.out.println("client connected"); sock.addHandshakeCompletedListener( new HandshakeListener("client",this)); // force the handshake sock.forceHandshake(); String cipher = sock.getStatus().getCipher(); System.out.println("client forced handshake. ciphersuite: " + cipher); sock.close(); // wait for the server to finish server.join(); } public static class HandshakeListener implements SSLHandshakeCompletedListener { private String who; private SSLClientAuth boss; public HandshakeListener(String who, SSLClientAuth boss) { this.who = who; this.boss = boss; } public void handshakeCompleted(SSLHandshakeCompletedEvent event) { try { String mesg = who + " got a completed handshake "; SSLSecurityStatus status = event.getStatus(); if( status.isSecurityOn() ) { mesg += "(security is ON)"; } else { mesg += "(security is OFF)"; } System.out.println(mesg); } catch(Exception e) { e.printStackTrace(); boss.setFailure(); } } } public synchronized void setFailure() { success = false; } public synchronized boolean getSuccess() { return success; } private boolean success = true; public int port = 29752; public int serialNum = 0; public boolean serverReady = false; /** * Server run method. */ public void run() { try { // We have to configure the server session ID cache before // creating any server sockets. SSLServerSocket.configServerSessionIDCache(10, 100, 100, null); // open the server socket and bind to the port System.out.println("Server about to create socket"); SSLServerSocket serverSock = new SSLServerSocket(port, 5, null, null, true); System.out.println("Server created socket"); serverSock.requireClientAuth(SSLSocket.SSL_REQUIRE_NO_ERROR); if( useNickname ) { serverSock.setServerCertNickname(serverCertNick); System.out.println("Server specified cert by nickname"); } else { serverSock.setServerCert(nssServerCert); System.out.println("Server specified cert directly"); } // tell the client we're ready synchronized(this) { serverReady = true; this.notify(); } // accept the connection System.out.println("Server about to accept"); SSLSocket sock = (SSLSocket) serverSock.accept(); System.out.println("Server accepted"); sock.addHandshakeCompletedListener( new HandshakeListener("server", this)); // try to read some bytes, to allow the handshake to go through InputStream is = sock.getInputStream(); try { System.out.println("Server about to read"); is.read(); System.out.println("Server read successful"); } catch(EOFException e) { System.out.println("Server got EOF"); } sock.close(); serverSock.close(); } catch(Exception e) { synchronized(this) { serverReady = true; setFailure(); this.notify(); } e.printStackTrace(); } System.out.println("Server exiting"); } static Extension makeBasicConstraintsExtension() throws Exception { SEQUENCE bc = new SEQUENCE(); bc.addElement( new BOOLEAN(true) ); // cA OBJECT_IDENTIFIER bcOID = new OBJECT_IDENTIFIER( new long[] {2, 5, 29, 19}); // from RFC 2459 OCTET_STRING enc = new OCTET_STRING(ASN1Util.encode(bc)); return new Extension(bcOID, true, enc); } static int nextRandInt(SecureRandom rand) throws Exception { int i; byte[] bytes = new byte[4]; rand.nextBytes(bytes); i = ((int)bytes[0])<<24 | ((int)bytes[1])<<16 | ((int)bytes[2])<<8 | ((int)bytes[3]); System.out.println("generated random value:" + i); return i; } } jss-4.4.3/jss/org/mozilla/jss/tests/SelfTest.java000066400000000000000000000167671326145000000217230ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.util.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.*; import org.mozilla.jss.pkcs11.*; import java.io.*; import java.awt.*; import java.security.cert.*; public class SelfTest { public static void main(String[] args) throws Throwable { CryptoToken tok; CryptoToken intTok; CryptoManager manager; Password pass1=null, pass2=null; java.security.KeyPair keyPair; java.util.Enumeration items; char[] passchar1 = {'f', 'o', 'o', 'b', 'a', 'r'}; char[] passchar2 = {'n', 'e', 't', 's', 'c', 'a', 'p', 'e'}; if(args.length != 1) { System.err.println("Usage: java ...SelfTest "); return; } CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues( args[0] ); CryptoManager.initialize(vals); try { manager = CryptoManager.getInstance(); } catch( CryptoManager.NotInitializedException e ) { System.out.println("CryptoManager not initialized"); return; } Debug.setLevel(Debug.OBNOXIOUS); try { tok = manager.getTokenByName("asdffda"); System.out.println("ERROR: found a nonexistent token"); } catch (NoSuchTokenException e) { System.out.println("Good, could not find non-existent token"); } try { items = manager.getModules(); System.out.println("Modules:"); while(items.hasMoreElements()) { System.out.println("\t"+ ((PK11Module)items.nextElement()).getName() ); } items = manager.getAllTokens(); System.out.println("All Tokens:"); while(items.hasMoreElements()) { System.out.println("\t"+ ((CryptoToken)items.nextElement()).getName() ); } items = manager.getExternalTokens(); System.out.println("External Tokens:"); while(items.hasMoreElements()) { System.out.println("\t"+ ((CryptoToken)items.nextElement()).getName() ); } tok = manager.getTokenByName("Internal Key Storage Token"); System.out.println("Good, found internal DB token"); if( tok.equals(manager.getInternalKeyStorageToken()) ) { System.out.println("Good, it really is the key storage token"); } else { System.out.println("ERROR: it's not the same as the key "+ "storage token!"); } if( ((PK11Token)tok).isInternalKeyStorageToken() ) { System.out.println("Good, "+tok.getName()+" knows "+ "what it is"); } else { System.out.println("ERROR: "+tok.getName()+" doesn't know"+ " it is key storage token"); } intTok = manager.getInternalCryptoToken(); if( ((PK11Token)intTok).isInternalCryptoToken() ) { System.out.println("Good, "+tok.getName()+ " knows it is the internal token"); } else { System.out.println("ERROR: "+tok.getName()+ " doesn't know what that it is the internal token"); } if(tok.isLoggedIn() == false) { System.out.println("Good, isLoggedIn correctly says we're"+ " not logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " logged in"); } System.out.println("Good, successfully opened token \""+ tok.getName()+"\""); pass1 = new Password( (char[]) passchar1.clone()); pass2 = new Password( new char[]{0} ); tok.initPassword(pass2, pass1); pass1.clear(); pass2.clear(); System.out.println("Good, initialized PIN"); tok.logout(); try { pass1 = new Password( (char[]) passchar2.clone()); tok.login(pass1); System.out.println("ERROR: Successfully logged in with wrong"+ " PIN"); } catch (IncorrectPasswordException e) { System.out.println("Good, unable to login with wrong PIN"); } finally { pass1.clear(); } pass1 = new Password( (char[]) passchar1.clone()); tok.login(pass1); pass1.clear(); System.out.println("Good, logged in"); if(tok.isLoggedIn() == true) { System.out.println("Good, isLoggedIn correctly says we're"+ " logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " not logged in"); } pass1 = new Password( (char[]) passchar1.clone()); pass2 = new Password( (char[]) passchar2.clone()); tok.changePassword(pass1, pass2); pass1.clear(); pass2.clear(); System.out.println("Good, changed PIN"); try { pass1 = new Password( (char[]) passchar1.clone()); tok.login(pass1); // Should still be logged in System.out.println("Good, logging in with wrong PIN ok if "+ " already logged in"); } catch (IncorrectPasswordException e) { System.out.println("ERROR: logged in second time with wrong"+ "PIN, but we should still be logged in"); } finally { pass1.clear(); } try { tok.logout(); System.out.println("Good, logged out successfully."); } catch (TokenException e) { System.out.println("ERROR: failed to logout from token"); } if(tok.isLoggedIn() == false) { System.out.println("Good, isLoggedIn correctly says we're"+ " not logged in"); } else { System.out.println("ERROR: isLoggedIn incorrectly says we're"+ " logged in"); } try { tok.logout(); System.out.println("ERROR: logged out twice in a row"); } catch (TokenException e) { System.out.println("Good, got an exception when we tried"+ " to log out twice in a row"); } try { pass1 = new Password( (char[]) passchar1.clone()); tok.login(pass1); pass1.clear(); System.out.println("ERROR: logged in with wrong pw"); } catch (IncorrectPasswordException e) { System.out.println("Good, logging in with wrong PIN gave err"); } System.out.println("Test completed"); tok = null; } catch (IncorrectPasswordException e) { System.out.println("Got an incorrect PIN: "+e); } catch (AlreadyInitializedException e) { System.out.println( "ERROR: This test only works with uninitialized databases"); } catch (TokenException e) { System.out.println("Token error: " + e); } catch (NoSuchTokenException e) { System.out.println("ERROR: could not find internal DB token"); } finally { if(pass1 != null) { pass1.clear(); } if(pass2 != null) { pass2.clear(); } } //System.gc(); //NativeProxy.assertRegistryEmpty(); //System.runFinalization(); } } jss-4.4.3/jss/org/mozilla/jss/tests/SetupDBs.java000066400000000000000000000026221326145000000216440ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; /** * Create the NSS databases * **/ public class SetupDBs { public static void main(String args[]) { try { if( args.length != 2 ) { System.err.println("Usage: java org.mozilla.jss.tests.SetupDBs " + " \n" + "Password file should have format:\n " + "Internal\\ Key\\ Storage\\ Token=m1oZilla\n " + "NSS\\ FIPS\\ 140-2\\ User\\ Private\\ " + "Key=m1oZilla\n"); System.exit(1); } String dbdir = args[0]; CryptoManager.initialize(dbdir); CryptoManager cm = CryptoManager.getInstance(); CryptoToken tok = cm.getInternalKeyStorageToken(); tok.initPassword( new NullPasswordCallback(), new FilePasswordCallback( args[1] ) ); Thread.currentThread().sleep(3*1000); System.exit(0); } catch(Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.4.3/jss/org/mozilla/jss/tests/SigTest.java000066400000000000000000000101501326145000000215300ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* This program demonstrates how to sign data with keys from JSS * * The token name can be either the name of a hardware token, or * one of the internal tokens: * Internal Crypto Services Token * Internal Key Storage Token (keys stored in key4.db) */ package org.mozilla.jss.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.crypto.Signature; import org.mozilla.jss.crypto.KeyPairGenerator; import org.mozilla.jss.crypto.KeyPairGeneratorSpi; import java.security.*; import java.util.*; import org.mozilla.jss.pkcs11.*; import org.mozilla.jss.*; import org.mozilla.jss.crypto.KeyPairGeneratorSpi.Usage; public class SigTest { public static void usage() { System.out.println( "Usage: java org.mozilla.jss.crypto.SigTest " + " [tokenname]"); } public static void main(String args[]) { try { CryptoToken token; CryptoManager manager; byte[] data = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9}; byte[] signature; Signature signer; PublicKey pubk; KeyPairGenerator kpgen; KeyPair keyPair; if (args.length < 2 || args.length > 3) { usage(); System.exit(1); } String dbdir = args[0]; CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues(args[0]); CryptoManager.initialize(vals); manager = CryptoManager.getInstance(); manager.setPasswordCallback(new FilePasswordCallback(args[1])); /* Print out list of available tokens */ Enumeration en = manager.getAllTokens(); System.out.println("Available tokens:"); while (en.hasMoreElements()) { PK11Token p = (PK11Token) en.nextElement(); System.out.println(" token : " + p.getName()); } if (args.length >= 3) { token = manager.getTokenByName(args[2]); } else { //get default internal key storage token token = manager.getInternalKeyStorageToken(); } // Generate an RSA keypair kpgen = token.getKeyPairGenerator(KeyPairAlgorithm.RSA); kpgen.initialize(1024); KeyPairGeneratorSpi.Usage usages[] = { KeyPairGeneratorSpi.Usage.SIGN, KeyPairGeneratorSpi.Usage.VERIFY}; KeyPairGeneratorSpi.Usage usages_mask[] = { KeyPairGeneratorSpi.Usage.SIGN, KeyPairGeneratorSpi.Usage.VERIFY}; kpgen.setKeyPairUsages(usages, usages_mask); keyPair = kpgen.genKeyPair(); // RSA MD5 signer = token.getSignatureContext( SignatureAlgorithm.RSASignatureWithMD5Digest); System.out.println("Created a signing context"); signer.initSign( (org.mozilla.jss.crypto.PrivateKey) keyPair.getPrivate()); System.out.println("initialized the signing operation"); signer.update(data); System.out.println("updated signature with data"); signature = signer.sign(); System.out.println("Successfully signed!"); signer.initVerify(keyPair.getPublic()); System.out.println("initialized verification"); signer.update(data); System.out.println("updated verification with data"); if (signer.verify(signature)) { System.out.println("Signature Verified Successfully!"); } else { throw new Exception("ERROR: Signature failed to verify."); } System.out.println("SigTest passed."); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.4.3/jss/org/mozilla/jss/tests/SymKeyDeriving.java000066400000000000000000000467611326145000000231000ustar00rootroot00000000000000/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either the GNU General Public License Version 2 or later (the "GPL"), or * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ package org.mozilla.jss.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.Assert; import org.mozilla.jss.pkcs11.*; import sun.security.pkcs11.wrapper.PKCS11Constants; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Vector; import java.util.Enumeration; /** * Sym Key deriving tests.. * */ public class SymKeyDeriving { private static final byte[] iv8 = new byte [] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 }; private static final byte[] iv16 = new byte [] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9,0xa, 0xb, 0xc,0xd,0xe, 0xf,0x10 }; private static final byte[] derivationData1 = new byte[] { 0x11, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 }; private static final byte[] derivationData2 = new byte [] { 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10 }; private static final byte[] derivationData16 = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10 }; public static void main(String args[]) { SymmetricKey macKeyDev = null; try { CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues("./" ); CryptoManager.initialize(vals); CryptoManager cm = CryptoManager.getInstance(); CryptoToken token = cm.getInternalCryptoToken(); CryptoToken keyToken = cm.getInternalKeyStorageToken(); System.out.println("interal token name: " + keyToken.getName()); KeyGenerator keyKg = keyToken.getKeyGenerator(KeyGenAlgorithm.DES3); SymmetricKey baseKey = keyKg.generate(); KeyGenerator keyKgDes = keyToken.getKeyGenerator(KeyGenAlgorithm.DES); SymmetricKey baseKeyDes = keyKgDes.generate(); System.out.println("strength: " + baseKeyDes.getStrength()); KeyGenerator keyKgAES = keyToken.getKeyGenerator(KeyGenAlgorithm.AES); keyKgAES.initialize(128); SymmetricKey baseKeyAES = keyKgAES.generate(); System.out.println("baseKey bytes: "); byte[] baseBytes = baseKey.getEncoded(); displayByteArray(baseBytes,true); /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_EXTRACT_KEY_FROM_KEY test 16 bytes. \n"); SymmetricKeyDeriver deriver = token.getSymmetricKeyDeriver(); System.out.println("deriver: " + deriver); System.out.println("CKM_EXTRACT_KEY_FROM_KEY : " + PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY); long bitPosition = 0; byte[] param = longToBytes(bitPosition); deriver.initDerive( baseKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey extracted16 = deriver.derive(); System.out.println("Derived key: " + extracted16); if(extracted16 == null) { System.out.println("Failed to derive 16 byte key with mechanism: CKM_EXTRACT_KEY_FROM_KEY \n"); } System.out.println("derivedKey 16 bytes: "); byte[] derivedBytes = extracted16.getEncoded(); displayByteArray(derivedBytes,true); /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_EXTRACT_KEY_FROM_KEY test 8 bytes. \n"); SymmetricKeyDeriver extract8 = token.getSymmetricKeyDeriver(); extract8.initDerive( extracted16, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,(long) 8); SymmetricKey extracted8 = extract8.derive(); System.out.println("Derived key: " + extracted8); if(extracted8 == null) { System.out.println("Failed to derive key extracted 8 bytes with mechanism: CKM_EXTRACT_KEY_FROM_KEY \n"); } byte[] extracted8Bytes = extracted8.getEncoded(); System.out.println("derived extracted 8 bytes of key: "); displayByteArray(extracted8Bytes,true); /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_CONCATENATE_BASE_AND_KEY test 16 + 8 = 24 byte key. \n"); SymmetricKeyDeriver concat = keyToken.getSymmetricKeyDeriver(); concat.initDerive( extracted16,extracted8, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,(long) 0); SymmetricKey concated24 = concat.derive(); if( concated24 == null) { System.out.println("Failed to derive key concated 8 bytes to 16 bytes key: CKM_CONCATENATE_BASE_AND_KEY \n"); } byte[] concated24Bytes = concated24.getEncoded(); System.out.println("derived concated 16 + 8 = 24 byte key: "); displayByteArray(concated24Bytes,true); /*****************************************************************************************************/ // Now lets try more complex derivation // tmp2 = PK11_Derive( master , CKM_DES_ECB_ENCRYPT_DATA , ¶m , CKM_CONCATENATE_BASE_AND_KEY , CKA_DERIVE , 0); System.out.println("\n Mechanism CKM_DES_ECB_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encrypt = token.getSymmetricKeyDeriver(); encrypt.initDerive( baseKeyDes, /* PKCS11Constants.CKM_DES_ECB_ENCRYPT_DATA */ 4352L,derivationData1 ,null, PKCS11Constants.CKM_DES_ECB, PKCS11Constants.CKA_DERIVE,(long) 8); SymmetricKey encrypted8 = encrypt.derive(); if( encrypted8 == null) { System.out.println("Failed to derive 8 bytes from encrypted derivation data."); } byte[] encrypted8Bytes = encrypted8.getEncoded(); System.out.println("derived encrypted 8 bytes: " + encrypted8Bytes.length); displayByteArray(encrypted8Bytes,true); Cipher cipher = null; cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES_ECB); cipher.initEncrypt(baseKeyDes); byte[] ciphertext = cipher.doFinal(derivationData1); displayByteArray(ciphertext,true); if ( ciphertext.length != encrypted8Bytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encrypted8Bytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encrypted8Bytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ // Try ecnrypted des3 derivation System.out.println("\n Mechanism CKM_DES3_ECB_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptDes3 = token.getSymmetricKeyDeriver(); encryptDes3.initDerive( baseKey, /* PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA */ 4354L ,derivationData16 ,null, PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encrypted16 = encryptDes3.derive(); if ( encrypted16 == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encrypted16Bytes = encrypted16.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encrypted16Bytes.length); displayByteArray(encrypted16Bytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES3_ECB); cipher.initEncrypt(baseKey); ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encrypted16Bytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encrypted16Bytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encrypted16Bytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_DES_CBC_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptDesCBC = token.getSymmetricKeyDeriver(); encryptDesCBC.initDerive( baseKeyDes, /* PKCS11Constants.CKM_DES_CBC_ENCRYPT_DATA */ 4353L ,derivationData1 ,iv8, PKCS11Constants.CKM_DES_CBC, PKCS11Constants.CKA_DERIVE,(long) 8); SymmetricKey encryptedDesCBC = encryptDesCBC.derive(); if ( encryptedDesCBC == null) { System.out.println("Failed to derive 8 bytes from encrypted derivation data."); } byte[] encryptedDesCBCBytes = encryptedDesCBC.getEncoded(); System.out.println("derived encrypted 8 bytes: " + encryptedDesCBCBytes.length); displayByteArray(encryptedDesCBCBytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES_CBC); cipher.initEncrypt(baseKeyDes,new IVParameterSpec(iv8)); ciphertext = cipher.doFinal(derivationData1); displayByteArray(ciphertext,true); if ( ciphertext.length != encryptedDesCBCBytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encryptedDesCBCBytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encryptedDesCBCBytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_DES3_CBC_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptDes3CBC = token.getSymmetricKeyDeriver(); encryptDes3CBC.initDerive( baseKey, /* PKCS11Constants.CKM_DES3_CBC_ENCRYPT_DATA */ 4355L ,derivationData16 ,iv8, PKCS11Constants.CKM_DES3_CBC, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encryptedDes3CBC = encryptDes3CBC.derive(); if ( encryptedDes3CBC == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encryptedDes3CBCBytes = encryptedDes3CBC.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encryptedDes3CBCBytes.length); displayByteArray(encryptedDes3CBCBytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES3_CBC); cipher.initEncrypt(baseKey,new IVParameterSpec(iv8)); ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encryptedDes3CBCBytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encryptedDes3CBCBytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encryptedDes3CBCBytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_AES_ECB_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptAESECB = token.getSymmetricKeyDeriver(); //System.in.read(); encryptAESECB.initDerive( baseKeyAES, /* PKCS11Constants.CKM_AES_ECB_ENCRYPT_DATA */ 4356L ,derivationData16 ,null, PKCS11Constants.CKM_AES_ECB, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encryptedAESECB = encryptAESECB.derive(); if ( encryptedAESECB == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encryptedAESECBBytes = encryptedAESECB.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encryptedAESECBBytes.length); displayByteArray(encryptedAESECBBytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.AES_128_ECB); cipher.initEncrypt(baseKeyAES); ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encryptedAESECBBytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encryptedAESECBBytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encryptedAESECBBytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } /*****************************************************************************************************/ System.out.println("\n Mechanism CKM_AES_CBC_ENCRYPT_DATA test. \n"); SymmetricKeyDeriver encryptAESCBC= token.getSymmetricKeyDeriver(); //System.in.read(); encryptAESCBC.initDerive( baseKeyAES, /* PKCS11Constants.CKM_AES_CBC_ENCRYPT_DATA */ 4357L ,derivationData16 ,iv16, PKCS11Constants.CKM_AES_CBC, PKCS11Constants.CKA_DERIVE,(long) 16); SymmetricKey encryptedAESCBC = encryptAESCBC.derive(); if ( encryptedAESCBC == null) { System.out.println("Failed to derive 16 bytes from encrypted derivation data."); } byte[] encryptedAESCBCBytes = encryptedAESCBC.getEncoded(); System.out.println("derived encrypted 16 bytes: " + encryptedAESCBCBytes.length); displayByteArray(encryptedAESCBCBytes,true); cipher = keyToken.getCipherContext(EncryptionAlgorithm.AES_128_CBC); cipher.initEncrypt(baseKeyAES,new IVParameterSpec(iv16)); ciphertext = cipher.doFinal(derivationData16); displayByteArray(ciphertext,true); if ( ciphertext.length != encryptedAESCBCBytes.length ) { System.out.println("FAILED: encrypted data length not equal to derived key length."); } else { for ( int i = 0; i < ciphertext.length ; i ++) { ciphertext[i]&=0xfe; encryptedAESCBCBytes[i]&=0xfe; } if ( Arrays.equals(ciphertext, encryptedAESCBCBytes)) { System.out.println("PASSED: derived key the same as encrypted data."); } else { System.out.println("FAILED: derived key not the same as encrypted data."); } } // get vector of symkeys Enumeration ect = null; ect = (Enumeration) cm.getAllTokens(); CryptoToken ct = null; //ct = cm.getTokenByName("ePass Token"); while (ect.hasMoreElements()) { ct = ect.nextElement(); System.out.println("CryptoToken.name= " + ct.getName()); } SymmetricKey[] keys = keyToken.getCryptoStore().getSymmetricKeys(); SymmetricKey macKey = getSymKeyByName(keys, "defKeySet-macKey"); System.out.println("macKey: " + macKey); } catch(Exception e) { e.printStackTrace(); } } public static void displayByteArray(byte[] ba, boolean has_check_sum) { char mask = 0xff; if ( has_check_sum == true ) mask = 0xfe; for(int i=0; i < ba.length; i++) { System.out.print( Integer.toHexString(ba[i]&mask) + " " ); if( (i % 26) == 25 ) { System.out.println(""); } } System.out.println(""); } public static byte[] longToBytes(long x) { ByteBuffer buffer = ByteBuffer.allocate(8); buffer.putLong(x); return buffer.array(); } public static byte[] concatByteArrays(byte[] a, byte[] b) { byte[] result = new byte[a.length + b.length]; System.arraycopy(a, 0, result, 0, a.length); System.arraycopy(b, 0, result, a.length, b.length); return result; } public static SymmetricKey getSymKeyByName( SymmetricKey[] keys, String name) { if ( keys == null || name == null ) { return null; } int len = keys.length; for(int i = 0 ; i < len ; i++ ) { SymmetricKey cur = keys[i]; if ( cur != null ) { if( name.equals(cur.getNickName())) { System.out.println("Found key: " + name + "\n"); return cur; } } } return null; } } jss-4.4.3/jss/org/mozilla/jss/tests/SymKeyGen.java000066400000000000000000000332501326145000000220270ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.crypto.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.util.Password; import java.security.InvalidAlgorithmParameterException; import java.security.spec.AlgorithmParameterSpec; import org.mozilla.jss.CertDatabaseException; import org.mozilla.jss.KeyDatabaseException; import java.security.GeneralSecurityException; import org.mozilla.jss.pkcs11.PK11SecureRandom; import javax.crypto.spec.RC2ParameterSpec; import java.util.*; /** * Most of this code is Deprecated look at JCASymKeyGen.java for sample. */ public class SymKeyGen { private CryptoToken token = null; byte[] plainText16Bytes = "Firefox rules!".getBytes(); /* 16 bytes */ byte[] plainText18Bytes = "Thunderbird rules!".getBytes(); /* 18 bytes */ public SymmetricKey genPBEKey(PBEAlgorithm alg, SymmetricKey.Type keyType, int keyStrength) throws Exception { SymmetricKey key = null; byte[] keyData; KeyGenerator kg = token.getKeyGenerator(alg); try { //this is debug code you don't initialize //PBE algs with key Strength doing this should throw //InvaldAlgortithmParameterException kg.initialize(keyStrength); throw new Exception("ERROR: Initializing PBE key with strength " + keyStrength + " succeeded"); } catch( InvalidAlgorithmParameterException e) { } Password pass = new Password( ("passwd1").toCharArray() ); byte[] salt = genSalt(alg.getSaltLength()); PBEKeyGenParams kgp = new PBEKeyGenParams(pass, salt, 2); pass.clear(); kg.initialize(kgp); key = kg.generate(); kgp.clear(); if( key.getType() != keyType ) { throw new Exception("Wrong key type: "+key.getType()); } if( ! key.getOwningToken().equals( token ) ) { throw new Exception("wrong token"); } if( key.getStrength() != keyStrength ) { throw new Exception("wrong strength: "+key.getStrength()); } return key; } public SymmetricKey genPBAKey(KeyGenAlgorithm alg, SymmetricKey.Type keyType, int keyStrength) throws Exception { SymmetricKey key = null; byte[] keyData; KeyGenerator kg = token.getKeyGenerator(alg); try { //this is debug code you don't initialize //PBE algs with key Strength doing this should throw //InvalidAlgorithmParameterException kg.initialize(keyStrength); throw new Exception("ERROR: Initializing PBE key with strength "+ keyStrength + " succeeded"); } catch( InvalidAlgorithmParameterException e) { } Password pass = new Password( ("passwd1").toCharArray() ); byte[] salt = genSalt(8); PBEKeyGenParams kgp = new PBEKeyGenParams(pass, salt, 2); pass.clear(); kg.initialize(kgp); key = kg.generate(); kgp.clear(); if( key.getType() != keyType ) { throw new Exception("Wrong key type: "+key.getType()); } if( ! key.getOwningToken().equals( token ) ) { throw new Exception("wrong token"); } if( key.getStrength() != keyStrength ) { throw new Exception("wrong strength: "+key.getStrength()); } return key; } public SymmetricKey genSymKey(KeyGenAlgorithm alg, SymmetricKey.Type keyType , int keyStrength, int keyLength) throws Exception { SymmetricKey key = null; byte[] keyData; KeyGenerator kg = token.getKeyGenerator(alg); if (alg == KeyGenAlgorithm.AES || alg == KeyGenAlgorithm.RC4 || alg == KeyGenAlgorithm.RC2) { kg.initialize (keyStrength); } key = kg.generate(); if( key.getType() != keyType ) { throw new Exception("wrong algorithm"); } if( ! key.getOwningToken().equals( token ) ) { throw new Exception("wrong token"); } if( key.getStrength() != keyStrength ) { throw new Exception("wrong strength"); } keyData = key.getKeyData(); if( keyData.length != keyLength ) { throw new Exception("key data wrong length: " + keyData.length); } return key; } public boolean cipherTest(SymmetricKey key, EncryptionAlgorithm eAlg ) throws Exception { boolean bStatus = false; int ivLength = 0; AlgorithmParameterSpec algParSpec = null; Cipher cipher = null; cipher = token.getCipherContext(eAlg); // if no padding is used plainText needs to be fixed length // block divisable by 8 bytes byte[] plaintext = plainText18Bytes; if ((eAlg.getMode() == EncryptionAlgorithm.Mode.CBC || eAlg.getMode() == EncryptionAlgorithm.Mode.ECB ) && eAlg.getPadding() == EncryptionAlgorithm.Padding.NONE) { plaintext = plainText16Bytes; } // size 0 means this algorithm does not take an IV. // you need to use the same IV for Encrypt/Decrypt ivLength = eAlg.getIVLength(); if (ivLength != 0 ) { algParSpec = genIV(ivLength); } if (key.getType() == (SymmetricKey.Type) SymmetricKey.RC2) { byte[] iv = new byte[ivLength]; PK11SecureRandom rng = new PK11SecureRandom(); rng.nextBytes(iv); algParSpec = new RC2ParameterSpec(40, iv); } if (algParSpec == null) { cipher.initEncrypt(key); } else { cipher.initEncrypt(key, algParSpec); } byte[] ciphertext = cipher.doFinal(plaintext); if (ivLength == 0) { cipher.initDecrypt(key); } else { cipher.initDecrypt(key, algParSpec); } byte[] recovered = cipher.doFinal(ciphertext); if( recovered.length != plaintext.length ) { throw new Exception("Recovered plaintext has different length ("+ recovered.length+") than original ("+plaintext.length+")"); } if (java.util.Arrays.equals(plaintext, recovered) ) { bStatus = true; } else { throw new Exception("ERROR: unable to recover plaintext"); } return bStatus; // no exception was thrown. } private SymKeyGen( String certDbLoc) { try { CryptoManager.initialize(certDbLoc); CryptoManager cm = CryptoManager.getInstance(); token = cm.getInternalCryptoToken(); } catch (AlreadyInitializedException ex) { ex.printStackTrace(); } catch (CertDatabaseException ex) { ex.printStackTrace(); } catch (CryptoManager.NotInitializedException ex) { ex.printStackTrace(); } catch (GeneralSecurityException ex) { ex.printStackTrace(); } catch (KeyDatabaseException ex) { ex.printStackTrace(); } } public IVParameterSpec genIV(int blockSize) throws Exception { // generate an IV byte[] iv = new byte[blockSize]; PK11SecureRandom rng = new PK11SecureRandom(); rng.nextBytes(iv); return new IVParameterSpec(iv); } public byte[] genSalt(int saltSize) throws Exception { byte[] salt = new byte[saltSize]; PK11SecureRandom rng = new PK11SecureRandom(); rng.nextBytes(salt); return salt; } class alg { public KeyGenAlgorithm sAlg; public SymmetricKey.Type keyType; public int size; public int blkSize; List ciphers = new LinkedList(); public alg (KeyGenAlgorithm alg, SymmetricKey.Type kType, int sz, int bSize) { sAlg = alg; keyType = kType; size = sz; blkSize = bSize; } public void setEncAlgs(List c) { ciphers = c; } } public static void main(String args[]) { try { if ( args.length < 1 ) { System.out.println("Usage: java org.mozilla.jss.tests." + "SymKeyGen "); System.exit(1); } SymKeyGen skg = new SymKeyGen(args[0]); SymmetricKey key = null; //DES Key key = skg.genSymKey(KeyGenAlgorithm.DES, SymmetricKey.DES, 56, 8); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); System.out.println("DES key and cipher tests correct"); // DES3 key key = skg.genSymKey(KeyGenAlgorithm.DES3, SymmetricKey.DES3, 168, 24); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES3_ECB); System.out.println("DESede key and cipher tests correct"); // AES 128 key key = skg.genSymKey(KeyGenAlgorithm.AES, SymmetricKey.AES, 128, 128/8); skg.cipherTest(key, EncryptionAlgorithm.AES_128_CBC); skg.cipherTest(key, EncryptionAlgorithm.AES_128_ECB); skg.cipherTest(key, EncryptionAlgorithm.AES_128_CBC_PAD); System.out.println("AES 128 key and cipher tests correct"); // AES 192 key key = skg.genSymKey(KeyGenAlgorithm.AES, SymmetricKey.AES, 192, 192/8); skg.cipherTest(key, EncryptionAlgorithm.AES_192_CBC); skg.cipherTest(key, EncryptionAlgorithm.AES_192_ECB); skg.cipherTest(key, EncryptionAlgorithm.AES_192_CBC_PAD); System.out.println("AES 192 key and cipher tests correct"); // AES 256 key key = skg.genSymKey(KeyGenAlgorithm.AES, SymmetricKey.AES, 256, 256/8); skg.cipherTest(key, EncryptionAlgorithm.AES_256_CBC); skg.cipherTest(key, EncryptionAlgorithm.AES_256_ECB); skg.cipherTest(key, EncryptionAlgorithm.AES_256_CBC_PAD); System.out.println("AES 256 key and cipher tests correct"); // RC2 Key key = skg.genSymKey(KeyGenAlgorithm.RC2, SymmetricKey.RC2, 40, 5); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC_PAD); System.out.println("RC2 key and cipher tests correct"); // RC4 key key = skg.genSymKey(KeyGenAlgorithm.RC4, SymmetricKey.RC4, 128, 128/8); skg.cipherTest(key, EncryptionAlgorithm.RC4); System.out.println("RC4 key and cipher tests correct"); //Todo //KeyGenAlgorithm.PBA_SHA1_HMAC, SymmetricKey.SHA1_HMAC, 160); //PBE key gen test. // PBEAlgorithm.PBE_MD2_DES_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_MD2_DES_CBC, SymmetricKey.DES, 56); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); //PBEAlgorithm.PBE_MD5_DES_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_MD5_DES_CBC, SymmetricKey.DES, 56); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); //PBEAlgorithm.PBE_SHA1_DES_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_DES_CBC, SymmetricKey.DES, 64); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES_ECB); //PBEAlgorithm.PBE_SHA1_DES3_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_DES3_CBC, SymmetricKey.DES3, 168); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC_PAD); skg.cipherTest(key, EncryptionAlgorithm.DES3_CBC); skg.cipherTest(key, EncryptionAlgorithm.DES3_ECB); //PBEAlgorithm.PBE_SHA1_RC2_40_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC2_40_CBC, SymmetricKey.RC2, 40); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC_PAD); //PBEAlgorithm.PBE_SHA1_RC2_128_CBC key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC2_128_CBC, SymmetricKey.RC2, 128); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC); skg.cipherTest(key, EncryptionAlgorithm.RC2_CBC_PAD); //PBEAlgorithm.PBE_SHA1_RC4_40 key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC4_40, SymmetricKey.RC4, 40); skg.cipherTest(key, EncryptionAlgorithm.RC4); //PBEAlgorithm.PBE_SHA1_RC4_128 key = skg.genPBEKey(PBEAlgorithm.PBE_SHA1_RC4_128, SymmetricKey.RC4, 128); skg.cipherTest(key, EncryptionAlgorithm.RC4); System.out.println("Password Based key generation tests correct"); } catch(Exception e) { e.printStackTrace(); } } } jss-4.4.3/jss/org/mozilla/jss/tests/TestCertificateApprovalCallback.java000066400000000000000000000064631326145000000263660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.util.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.ssl.SSLCertificateApprovalCallback; /** * This is a test implementation of the certificate approval callback which * gets invoked when the server presents a certificate which is not * trusted by the client. * * Note this implementation accepts all certificates! */ public class TestCertificateApprovalCallback implements SSLCertificateApprovalCallback { public boolean approve( org.mozilla.jss.crypto.X509Certificate servercert, SSLCertificateApprovalCallback.ValidityStatus status) { SSLCertificateApprovalCallback.ValidityItem item; if (Constants.debug_level > 3) { System.out.println("in TestCertificateApprovalCallback.approve()"); /* dump out server cert details */ System.out.println("Peer cert details: "+ "\n subject: "+servercert.getSubjectDN().toString()+ "\n issuer: "+servercert.getIssuerDN().toString()+ "\n serial: "+servercert.getSerialNumber().toString() ); } /* iterate through all the problems */ boolean trust_the_server_cert=false; Enumeration errors = status.getReasons(); int i=0; while (errors.hasMoreElements()) { i++; item = (SSLCertificateApprovalCallback.ValidityItem) errors.nextElement(); if (Constants.debug_level > 3) { System.out.println("item "+i+ " reason="+item.getReason()+ " depth="+item.getDepth()); } org.mozilla.jss.crypto.X509Certificate cert = item.getCert(); if (item.getReason() == SSLCertificateApprovalCallback.ValidityStatus.UNTRUSTED_ISSUER) { trust_the_server_cert = true; } if (Constants.debug_level > 3) { System.out.println(" cert details: "+ "\n subject: "+cert.getSubjectDN().toString()+ "\n issuer: "+cert.getIssuerDN().toString()+ "\n serial: "+cert.getSerialNumber().toString() ); } } if (trust_the_server_cert) { if (Constants.debug_level > 3) { System.out.println("importing certificate."); } try { InternalCertificate newcert = org.mozilla.jss.CryptoManager.getInstance(). importCertToPerm(servercert,"testnick"); newcert.setSSLTrust(InternalCertificate.TRUSTED_PEER | InternalCertificate.VALID_PEER); } catch (Exception e) { System.out.println("thrown exception: "+e); } } /* allow the connection to continue. */ /* returning false here would abort the connection */ /* don't do this in production code! */ return true; } } jss-4.4.3/jss/org/mozilla/jss/tests/TestKeyGen.java000066400000000000000000000204501326145000000221740ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * Note: when this program is run, it must have a key3.db WITH A PASSWORD * SET in the directory specified by the argument. The first time the * program is run, a key3.db file will be created, but it will not have * a password. This will result in the error: * Token error: org.mozilla.jss.crypto.TokenException: unable to login to token * * To create a database with a password, you can: * use the modutil or keyutil tool, * use the JSS API CryptoToken.changePassword() to set the password * run the test 'TokenAccessTest' * which will create db with a password. */ package org.mozilla.jss.tests; import org.mozilla.jss.pkcs11.*; import org.mozilla.jss.util.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.*; import org.mozilla.jss.pkcs11.PK11KeyPairGenerator; import java.io.*; import java.awt.*; import java.security.cert.*; import java.security.interfaces.*; import java.math.BigInteger; public class TestKeyGen { public static void main(String[] args) { try { CryptoManager manager; java.security.KeyPair keyPair; Base64OutputStream base64; if(args.length != 2) { System.err.println("Usage: java org.mozilla.jss.pkcs11." + "TestKeyGen "); System.exit(1); } CryptoManager.initialize(args[0]); manager = CryptoManager.getInstance(); manager.setPasswordCallback( new FilePasswordCallback(args[1]) ); java.util.Enumeration tokens = manager.getTokensSupportingAlgorithm(KeyPairAlgorithm.RSA); System.out.println("The following tokens support RSA keygen:"); while(tokens.hasMoreElements()) { System.out.println("\t"+ ((CryptoToken)tokens.nextElement()).getName() ); } tokens = manager.getTokensSupportingAlgorithm(KeyPairAlgorithm.DSA); System.out.println("The following tokens support DSA keygen:"); while(tokens.hasMoreElements()) { System.out.println("\t"+ ((CryptoToken)tokens.nextElement()).getName() ); } RSAPublicKey rsaPubKey; DSAPublicKey dsaPubKey; DSAParams dsaParams; RSAParameterSpec rsaParams; java.security.KeyPairGenerator kpg = java.security.KeyPairGenerator.getInstance("RSA", "Mozilla-JSS"); // 512-bit RSA with default exponent System.out.println("Generating 512-bit RSA KeyPair!"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(512); keyPair = kpg.genKeyPair(); Assert._assert( keyPair.getPublic() instanceof RSAPublicKey); rsaPubKey = (RSAPublicKey) keyPair.getPublic(); System.out.println("Generated 512-bit RSA KeyPair!"); System.out.println("Modulus: "+rsaPubKey.getModulus()); System.out.println("Exponent: "+rsaPubKey.getPublicExponent()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExRSA512) { if (cntr==5) { System.out.println("Generation of 512-bit RSA KeyPair Failed\n"); TRExRSA512.printStackTrace(); } } } // 1024-bit RSA with default exponent System.out.println("Generating 1024-bit RSA KeyPair!"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(1024); keyPair = kpg.genKeyPair(); Assert._assert( keyPair.getPublic() instanceof RSAPublicKey); rsaPubKey = (RSAPublicKey) keyPair.getPublic(); System.out.println("Generated 1024-bit RSA KeyPair!"); System.out.println("Modulus: "+rsaPubKey.getModulus()); System.out.println("Exponent: "+rsaPubKey.getPublicExponent()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExRSA1024) { if (cntr==5) { System.out.println("Generation of 1024-bit RSA KeyPair Failed\n"); TRExRSA1024.printStackTrace(); } } } // 512-bit RSA with exponent = 3 System.out.println("Generating 512-bit RSA KeyPair with public exponent=3!"); for (int cntr=0; cntr<5; cntr++ ) { try { rsaParams = new RSAParameterSpec(512, BigInteger.valueOf(3)); kpg.initialize(rsaParams); keyPair = kpg.genKeyPair(); Assert._assert( keyPair.getPublic() instanceof RSAPublicKey); rsaPubKey = (RSAPublicKey) keyPair.getPublic(); System.out.println("Generated 512-bit RSA KeyPair with public exponent=3!"); System.out.println("Modulus: "+rsaPubKey.getModulus()); System.out.println("Exponent: "+rsaPubKey.getPublicExponent()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExRSA512Exp3) { if (cntr==5) { System.out.println("Generation of 512-bit RSA KeyPair with public exponent=3 Failed\n"); TRExRSA512Exp3.printStackTrace(); } } } // 512-bit DSA System.out.println("Generating 512-bit DSA KeyPair!"); kpg = java.security.KeyPairGenerator.getInstance("DSA", "Mozilla-JSS"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(512); keyPair = kpg.genKeyPair(); Assert._assert( keyPair.getPublic() instanceof DSAPublicKey); dsaPubKey = (DSAPublicKey) keyPair.getPublic(); System.out.println("Generated 512-bit DSA KeyPair!"); dsaParams = dsaPubKey.getParams(); System.out.println("P: "+dsaParams.getP()); System.out.println("Q: "+dsaParams.getQ()); System.out.println("G: "+dsaParams.getG()); System.out.println("Y: "+dsaPubKey.getY()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExDSA512) { if (cntr==5) { System.out.println("Generation of 512-bit DSA KeyPair Failed\n"); TRExDSA512.printStackTrace(); } } } // 1024-bit DSA, passing in PQG params System.out.println("Generating 1024-bit DSA KeyPair with PQG params!"); for (int cntr=0; cntr<5; cntr++ ) { try { kpg.initialize(PK11KeyPairGenerator.PQG1024); keyPair = kpg.genKeyPair(); Assert._assert( keyPair.getPublic() instanceof DSAPublicKey); dsaPubKey = (DSAPublicKey) keyPair.getPublic(); System.out.println("Generated 1024-bit DSA KeyPair with PQG params!"); dsaParams = dsaPubKey.getParams(); System.out.println("P: "+dsaParams.getP()); System.out.println("Q: "+dsaParams.getQ()); System.out.println("G: "+dsaParams.getG()); System.out.println("Y: "+dsaPubKey.getY()); break; } catch (org.mozilla.jss.crypto.TokenRuntimeException TRExDSA1024) { if (cntr==5) { System.out.println("Generation of 1024-bit DSA KeyPair with PQG params Failed\n"); TRExDSA1024.printStackTrace(); } } } // 256-bit EC kpg = java.security.KeyPairGenerator.getInstance("EC", "Mozilla-JSS"); kpg.initialize(256); keyPair = kpg.genKeyPair(); System.out.println("Generated 256-bit EC KeyPair!"); kpg.initialize(384); keyPair = kpg.genKeyPair(); System.out.println("Generated 384-bit EC KeyPair!"); kpg.initialize(521); keyPair = kpg.genKeyPair(); System.out.println("Generated 521-bit EC KeyPair!"); System.out.println("TestKeyGen passed"); System.exit(0); } catch (Exception e) { e.printStackTrace(); System.exit(1); } } } jss-4.4.3/jss/org/mozilla/jss/tests/TestSDR.java000066400000000000000000000063611326145000000214470ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import java.security.*; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.SecretDecoderRing.*; import java.io.*; import javax.crypto.*; /** * Secret Decoder ring tests. */ public class TestSDR { public static final EncryptionAlgorithm encAlg = EncryptionAlgorithm.DES3_CBC; public static final KeyGenAlgorithm keyGenAlg = KeyGenAlgorithm.DES3; public static void main(String[] args) throws Exception { if( args.length != 2 ) { throw new Exception("Usage: java TestSDR "); } CryptoManager.initialize(args[0]); CryptoManager cm = CryptoManager.getInstance(); cm.setPasswordCallback( new FilePasswordCallback(args[1]) ); CryptoToken ksToken = cm.getInternalKeyStorageToken(); // // test key management // KeyManager km = new KeyManager(ksToken); byte[] keyID = km.generateKey(keyGenAlg, 0); System.out.println("Successfully generated key"); SecretKey key = km.lookupKey(encAlg, keyID); if( key == null ) { throw new Exception("Error: generated key not found"); } System.out.println("Successfully looked up key"); km.deleteKey(keyID); System.out.println("Successfully deleted key"); key = km.lookupKey(encAlg, keyID); if( key != null ) { throw new Exception("Deleted key still found"); } System.out.println("Good: deleted key not found"); // // test encryption/decryption // keyID = km.generateKey(keyGenAlg, 0); Encryptor encryptor = new Encryptor(ksToken, keyID, encAlg); byte[] plaintext = "Hello, world!".getBytes("UTF-8"); byte[] ciphertext = encryptor.encrypt(plaintext); System.out.println("Successfully encrypted plaintext"); Decryptor decryptor = new Decryptor(ksToken); byte[] recovered = decryptor.decrypt(ciphertext); System.out.println("Decrypted ciphertext"); if( plaintext.length != recovered.length ) { throw new Exception( "Recovered plaintext does not match original plaintext"); } for(int i=0; i < plaintext.length; ++i) { if( plaintext[i] != recovered[i] ) { throw new Exception( "Recovered plaintext does not match original plaintext"); } } System.out.println("Decrypted ciphertext matches original plaintext"); // delete the key and try to decrypt. Decryption should fail. km.deleteKey(keyID); try { recovered = decryptor.decrypt(ciphertext); throw new Exception( "Error: successfully decrypted with deleted key"); } catch (InvalidKeyException ike) { } System.out.println( "Good: as expected did not decrypt plaintext with a " + "deleted key"); System.out.println("TestSDR: Success"); System.exit(0); } } jss-4.4.3/jss/org/mozilla/jss/tests/VerifyCert.java000066400000000000000000000154741326145000000222460ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.tests; import org.mozilla.jss.CryptoManager; import org.mozilla.jss.crypto.*; import org.mozilla.jss.util.*; import org.mozilla.jss.pkix.cert.*; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.util.ArrayList; import java.util.Iterator; /** * Verify Certificate test. */ public class VerifyCert { public void showCert( String certFile) { //Read the cert try { BufferedInputStream bis = new BufferedInputStream( new FileInputStream(certFile) ); Certificate cert = (Certificate) Certificate.getTemplate().decode(bis); //output the cert CertificateInfo info = cert.getInfo(); info.print(System.out); //verify the signature of the cert only // cert.verify(); } catch (Exception ex) { ex.printStackTrace(); System.exit(1); } } private void usage() { System.out.println("Usage: java org.mozilla.jss.tests.VerifyCert"); System.out.println("\noptions:\n\n " + " " + "\n"); System.out.println(" " + " " + "\n"); System.out.println("Note: and " + " are optional.\n But if used, " + "both Url/nickname must be specified."); } public static void main(String args[]) { try { VerifyCert vc = new VerifyCert(); if ( args.length < 3 ) { vc.usage(); return; } String dbdir = args[0]; String password = args[1]; String name = args[2]; String ResponderURL = null; String ResponderNickname = null; //if OCSPResponderURL than must have OCSPCertificateNickname if (args.length == 4 || args.length > 5) vc.usage(); else if (args.length == 5) { ResponderURL= args[3]; ResponderNickname = args[4]; } //initialize JSS CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues(dbdir); //enable PKIX verify rather than the old NSS cert library, //to verify certificates. vals.PKIXVerify = true; // as a JSS test set the initialize for cooperate to true // One would set this to true if one configured NSS with // to use other PKCS11 modules. vals.cooperate = true; // configure OCSP vals.ocspCheckingEnabled = true; if (ResponderURL != null && ResponderNickname != null) { vals.ocspResponderCertNickname = ResponderNickname; vals.ocspResponderURL = ResponderURL; } CryptoManager.initialize(vals); CryptoManager cm = CryptoManager.getInstance(); PasswordCallback pwd = new Password(password.toCharArray()); cm.setPasswordCallback(pwd); try { FileInputStream fin = new FileInputStream(name); byte[] pkg = new byte[fin.available()]; fin.read(pkg); //display the cert vc.showCert(name); //validate the cert vc.validateDerCert(pkg, cm); } catch (java.io.FileNotFoundException e) { //assume name is a nickname of cert in the db vc.validateCertInDB(name, cm); } } catch ( Exception e ) { e.printStackTrace(); System.exit(1); } } public void validateDerCert(byte[] pkg, CryptoManager cm){ ArrayList usageList = new ArrayList(); try { Iterator list = CryptoManager.CertUsage.getCertUsages(); CryptoManager.CertUsage certUsage; while(list.hasNext()) { certUsage = (CryptoManager.CertUsage) list.next(); if ( !certUsage.equals(CryptoManager.CertUsage.UserCertImport) && !certUsage.equals(CryptoManager.CertUsage.ProtectedObjectSigner) && !certUsage.equals(CryptoManager.CertUsage.AnyCA) ) { if (cm.isCertValid(pkg, true, certUsage) == true) { usageList.add(certUsage.toString()); } } } } catch (Exception e) { e.printStackTrace(); } if (usageList.isEmpty()) { System.out.println("The certificate is not valid."); } else { System.out.println("The certificate is valid for " + "the following usages:\n"); Iterator iterateUsage = usageList.iterator(); while (iterateUsage.hasNext()) { System.out.println(" " + iterateUsage.next()); } } } public void validateCertInDB(String nickname, CryptoManager cm){ ArrayList usageList = new ArrayList(); try { Iterator list = CryptoManager.CertUsage.getCertUsages(); CryptoManager.CertUsage certUsage; while(list.hasNext()) { certUsage = (CryptoManager.CertUsage) list.next(); if ( !certUsage.equals(CryptoManager.CertUsage.UserCertImport) && !certUsage.equals(CryptoManager.CertUsage.ProtectedObjectSigner) && !certUsage.equals(CryptoManager.CertUsage.AnyCA) ) { if (cm.isCertValid(nickname, true, certUsage) == true) { usageList.add(certUsage.toString()); } } } } catch (Exception e) { e.printStackTrace(); } if (usageList.isEmpty()) { System.out.println("The certificate is not valid."); } else { System.out.println("The certificate is valid for the " + "following usages:\n"); Iterator iterateUsage = usageList.iterator(); while (iterateUsage.hasNext()) { System.out.println(" " + iterateUsage.next()); } } } } jss-4.4.3/jss/org/mozilla/jss/tests/all.pl000066400000000000000000000557551326145000000204340ustar00rootroot00000000000000#!/usr/bin/perl # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. use Socket; use File::Basename; use Cwd; use Cwd 'abs_path'; use POSIX 'uname'; # dist # release # auto (test the current build directory) sub usage { print "Usage:\n"; print "$0 dist \n"; print "$0 release " . "\n"; print "$0 auto\n"; exit(1); } # Force Perl to do unbuffered output # to avoid having Java and Perl output out of sync. $| = 1; # Global variables my $java = ""; my $testdir = ""; my $testrun = 0; my $testpass = 0; my $nss_lib_dir = ""; my $dist_dir = ""; my $pathsep = ":"; my $scriptext = "sh"; my $exe_suffix = ""; my $lib_suffix = ".so"; my $lib_jss = "libjss"; my $jss_rel_dir = ""; my $jss_classpath = ""; my $serverPort = 2876; my $hostname = localhost; my $dbPwd = "m1oZilla"; my $configfile = ""; my $keystore = ""; my $certSN_file = ""; my $certSN = 0; ($osname,$host,$release) = uname; # checkPort will return a free Port number # otherwise it will die after trying 10 times. sub checkPort { my ($p) = @_; my $localhost = inet_aton("localhost"); my $max = $p + 20; # try to find a port 10 times my $port = sockaddr_in($p, $localhost); #create a socket socket(SOCKET, PF_INET, SOCK_STREAM, getprotobyname('tcp')) || die "Unable to create socket: $!\n"; #loop until you find a free port while (connect(SOCKET, $port) && $p < $max) { print "$p is in use trying to find another port.\n"; $p = $p + 1; $port = sockaddr_in($p, $localhost); } close SOCKET || die "Unable to close socket: $!\n"; if ($p == $max) { die "Unable to find a free port..\n"; } return $p; } sub setup_vars { my $argv = shift; my $truncate_lib_path = 1; $run_shell = ""; if( $osname =~ /HP/ ) { $ld_lib_path = "SHLIB_PATH"; $scriptext = "sh"; $lib_suffix = ".sl"; } elsif( $osname =~ /Darwin/) { $ld_lib_path = "DYLD_LIBRARY_PATH"; $lib_suffix = ".jnilib"; } elsif( $osname =~ /mingw/i ) { print "We are mingw\n"; $ld_lib_path = "PATH"; $truncate_lib_path = 0; $pathsep = ":"; $exe_suffix = ".exe"; $lib_suffix = ".dll"; $lib_jss = "jss"; $scriptext = "sh"; $run_shell = "sh.exe"; } elsif( $osname =~ /win/i ) { $ld_lib_path = "PATH"; $truncate_lib_path = 0; $pathsep = ";"; $exe_suffix = ".exe"; $lib_suffix = ".dll"; $lib_jss = "jss"; $run_shell = "sh.exe"; } else { $ld_lib_path = "LD_LIBRARY_PATH"; $scriptext = "sh"; } my $jar_dbg_suffix = "_dbg"; my $dbg_suffix = "_DBG"; $ENV{BUILD_OPT} and $dbg_suffix = ""; $ENV{BUILD_OPT} and $jar_dbg_suffix = ""; $ENV{CLASSPATH} = ""; $ENV{$ld_lib_path} = "" if $truncate_lib_path; if( $$argv[0] eq "dist" ) { shift @$argv; $dist_dir = shift @$argv or usage("did not provide dist_dir"); $ENV{CLASSPATH} .= "$dist_dir/../xpclass$jar_dbg_suffix.jar"; ( -f $ENV{CLASSPATH} ) or die "$ENV{CLASSPATH} does not exist"; $ENV{$ld_lib_path} = $ENV{$ld_lib_path} . $pathsep . "$dist_dir/lib"; $nss_lib_dir = "$dist_dir/lib"; $jss_rel_dir = "$dist_dir/../classes$dbg_suffix/org"; $jss_classpath = "$dist_dir/../xpclass$jar_dbg_suffix.jar"; } elsif( $$argv[0] eq "auto" ) { my $dist_dir = `make dist_dir`; my $obj_dir = `make obj_dir`; chomp($dist_dir); chomp($obj_dir); chomp( $dist_dir = `(cd $dist_dir ; pwd)`); chomp( $obj_dir = `(cd $obj_dir ; pwd)`); $nss_lib_dir = "$obj_dir/lib"; $jss_rel_dir = "$dist_dir/classes$dbg_suffix/org"; $jss_classpath = "$dist_dir/xpclass$jar_dbg_suffix.jar"; $ENV{CLASSPATH} .= "$dist_dir/xpclass$jar_dbg_suffix.jar"; ( -f $ENV{CLASSPATH} ) or die "$ENV{CLASSPATH} does not exist"; #$ENV{$ld_lib_path} = $ENV{$ld_lib_path} . $pathsep . "$obj_dir/lib"; $ENV{$ld_lib_path} = "$obj_dir/lib"; } elsif( $$argv[0] eq "release" ) { shift @$argv; $jss_rel_dir = shift @$argv or usage(); my $nss_rel_dir = shift @$argv or usage(); my $nspr_rel_dir = shift @$argv or usage(); $ENV{CLASSPATH} .= "$jss_rel_dir/../xpclass$jar_dbg_suffix.jar"; $ENV{$ld_lib_path} = "$jss_rel_dir/lib$pathsep$nss_rel_dir/lib$pathsep$nspr_rel_dir/lib" . $pathsep . $ENV{$ld_lib_path}; print "LD_LIBRARY_PATH is $ld_lib_path\n"; print "$ld_lib_path=$ENV{$ld_lib_path}\n"; $nss_lib_dir = "$nss_rel_dir/lib"; $jss_classpath = "$jss_rel_dir/../xpclass$jar_dbg_suffix.jar"; } else { usage(); } if ($ENV{PORT_JSSE_SERVER}) { $serverPort = $ENV{PORT_JSSE_SERVER}; } if ($ENV{PORT_JSS_SERVER}) { $serverPort = $ENV{PORT_JSS_SERVER}; } unless( $ENV{JAVA_HOME} ) { print "Must set JAVA_HOME environment variable\n"; exit(1); } if ($osname =~ /Darwin/) { $java = "$ENV{JAVA_HOME}/bin/java"; } else { $java = "$ENV{JAVA_HOME}/jre/bin/java$exe_suffix"; } # # Use 64-bit Java on AMD64. # my $java_64bit = 0; if ($osname eq "SunOS") { if ($ENV{USE_64}) { my $cpu = `/usr/bin/isainfo -n`; chomp $cpu; if ($cpu eq "amd64") { $java = "$ENV{JAVA_HOME}/jre/bin/amd64/java$exe_suffix"; $java_64bit = 1; } } } if ( $osname =~ /_NT/i ) { $java_64bit = 1; } (-f $java) or die "'$java' does not exist\n"; $java = $java . $ENV{NATIVE_FLAG}; if ($ENV{USE_64} && !$java_64bit) { $java = $java . " -d64"; } #MAC OS X have the -Djava.library.path for the JSS JNI library if ($osname =~ /Darwin/) { $java = $java . " -Djava.library.path=$nss_lib_dir"; } $pwfile = "passwords"; # testdir = //mozilla/tests_results/jss/. # $all_dir = Directory where all.pl is my $all_dir = dirname($0); # Find where mozilla directory is my $base_mozilla = $all_dir . "/../../../../.."; my $abs_base_mozilla = abs_path($base_mozilla); # $result_dir = Directory where the results are (mozilla/tests_results/jss) my $result_dir = $abs_base_mozilla . "/tests_results"; if (! -d $result_dir) { mkdir( $result_dir, 0755 ) or die; } my $result_dir = $abs_base_mozilla . "/tests_results/jss"; if( ! -d $result_dir ) { mkdir( $result_dir, 0755 ) or die; } # $host = hostname # $version = test run number (first = 1). Stored in $result_dir/$host my $version_file = $result_dir ."/" . $host; if ( -f $version_file) { open (VERSION, "< $version_file") || die "couldn't open " . $version_file . " for read"; $version = ; close (VERSION); chomp $version; $version = $version + 1; } else { $version = 1; } # write the version in the file open (VERSION, "> $version_file") || die "couldn't open " . $version_file . " for write"; print VERSION $version . "\n"; close (VERSION); # Finally, set $testdir $testdir = $result_dir . "/" . $host . "." . $version; #in case multiple tests are being run on the same machine increase #the port numbers with version number * 10 $serverPort = $serverPort + ($version * 10); outputEnv(); } sub updateCertSN() { # $certSN = certificate serial number (first = 100). Stored in $testdir/cert-SN $certSN_file = $testdir ."/" . "cert-SN"; if ( -f $certSN_file) { open (CERT_SN, "< $certSN_file") || die "couldn't open " . $certSN_file . " for read"; $certSN = ; close (CERT_SN); chomp $certSN; $certSN = $certSN + 10; } else { $certSN = 100; } # write the version in the file open (CERT_SN, "> $certSN_file") || die "couldn't open " . $certSN_file . " for write"; print CERT_SN $certSN . "\n"; close (CERT_SN); } sub outputEnv { print "*****ENVIRONMENT*****\n"; print "java=$java\n"; print "NATIVE_FLAG=$ENV{NATIVE_FLAG}\n"; print "$ld_lib_path=$ENV{$ld_lib_path}\n"; print "CLASSPATH=$ENV{CLASSPATH}\n"; print "BUILD_OPT=$ENV{BUILD_OPT}\n"; print "USE_64=$ENV{USE_64}\n"; print "testdir=$testdir\n"; print "serverPort=$serverPort\n"; print "LIB_SUFFIX=$lib_suffix\n"; print "osname=$osname\n"; print "release=$release\n"; print "which perl="; system ("which perl"); system ("perl -version | grep \"This is perl\""); system ("$java -version"); } sub createpkcs11_cfg { $configfile = $testdir . "/" . "nsspkcs11.cfg"; $keystore = $testdir . "/" . "keystore"; if ( -f $configfile ) { print "configfile all ready exists"; return; } my $nsslibdir = $nss_lib_dir; my $tdir = $testdir; #On windows make sure the path starts with c: if ($osname =~ /_NT/i) { substr($nsslibdir, 0, 2) = 'c:'; substr($tdir, 0, 2) = 'c:'; } #the test for java 1.5 or 1.6 relies on the JAVA_HOME path to have the version #this is the case for all the build machines and tinderboxes. if ( $java =~ /1.6/i) { # java 6 # http://java.sun.com/javase/6/docs/technotes/guides/security/p11guide.html # note some OS can read the 1.5 configuration but not all can. open (CONFIG, "> $configfile") || die "couldn't open " . $configfile . " for write"; print CONFIG "name=NSS\n"; print CONFIG "nssLibraryDirectory=" . "$nsslibdir\n"; print CONFIG "nssSecmodDirectory=$tdir\n"; print CONFIG "nssDbMode=readWrite\n"; print CONFIG "nssModule=keystore\n"; close (CONFIG); } else { # default # java 5 #http://java.sun.com/j2se/1.5.0/docs/guide/security/p11guide.html open (CONFIG, "> $configfile") || die "couldn't open " . $configfile . " for write"; print CONFIG "name=NSS\n"; if ($lib_suffix eq ".jnilib") { print CONFIG "library=" . $nsslibdir . "/libsoftokn3.dylib\n"; } else { print CONFIG "library=" . $nsslibdir . "/libsoftokn3$lib_suffix\n"; } print CONFIG "nssArgs=\"configdir=\'". $tdir . "\' "; print CONFIG "certPrefix=\'\' keyPrefix=\'\' secmod=\'secmod.db\'\"\n"; print CONFIG "slot=2\n"; close (CONFIG); } print "nsspkcs11=$configfile\n"; } sub run_ssl_test { my $testname = shift; my $serverCommand = shift; my $clientCommand = shift; print "\n============= $testname \n"; print "$serverCommand \n"; $result = system("$serverCommand"); if ($result != 0) { print "launching server FAILED with return value $result\n"; return; } sleep 5; print "\nSSL Server is invoked using port $serverPort \n" ; print "$clientCommand \n"; $result = system("$clientCommand"); $result >>=8; print_case_result ($result, $testname); $serverPort=$serverPort+1; $serverPort = checkPort($serverPort); } sub run_test { my $testname = shift; my $command = shift; print "\n============= $testname \n"; print "$command \n"; $result = system("$command"); $result >>=8; print_case_result ($result, $testname); } sub print_case_result { my $result = shift; my $testname = shift; $testrun++; if ($result == 0) { $testpass++; print "JSSTEST_CASE $testrun ($testname): PASS\n"; } else { print "JSSTEST_CASE $testrun ($testname): FAILED return value $result\n"; } } setup_vars(\@ARGV); my $signingToken = "Internal Key Storage Token"; print "*********************\n"; # # Make the test database directory # if( ! -d $testdir ) { mkdir( $testdir, 0755 ) or die; } { my @dbfiles = ("$testdir/cert8.db", "$testdir/key3.db", "$testdir/secmod.db", "$testdir/rsa.pfx"); (grep{ -f } @dbfiles) and die "There is already an old database in $testdir"; my $result = system("cp $nss_lib_dir/*nssckbi* $testdir"); $result >>= 8; $result and die "Failed to copy built-ins library"; } print "creating pkcs11config file\n"; createpkcs11_cfg; my $result; my $command; my $serverCommand; $testname = "Setup DBs"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.SetupDBs $testdir $pwfile"; run_test($testname, $command); updateCertSN(); $testname = "Generate known RSA cert pair"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.GenerateTestCert $testdir $pwfile $certSN localhost SHA-256/RSA CA_RSA Server_RSA Client_RSA"; run_test($testname, $command); updateCertSN(); $testname = "Generate known ECDSA cert pair"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.GenerateTestCert $testdir $pwfile $certSN localhost SHA-256/EC CA_ECDSA Server_ECDSA Client_ECDSA"; run_test($testname, $command); updateCertSN(); $testname = "Generate known DSS cert pair"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.GenerateTestCert $testdir $pwfile $certSN localhost SHA-1/DSA CA_DSS Server_DSS Client_DSS"; run_test($testname, $command); $testname = "Create PKCS11 cert to PKCS12 rsa.pfx"; $command = "$nss_lib_dir/../bin/pk12util$exe_suffix -o $testdir/rsa.pfx -n CA_RSA -d $testdir -K $dbPwd -W $dbPwd"; run_test($testname, $command); $testname = "Create PKCS11 cert to PKCS12 ecdsa.pfx"; $command = "$nss_lib_dir/../bin/pk12util$exe_suffix -o $testdir/ecdsa.pfx -n CA_ECDSA -d $testdir -K $dbPwd -W $dbPwd"; run_test($testname, $command); $testname = "Create PKCS11 cert to PKCS12 dss.pfx"; $command = "$nss_lib_dir/../bin/pk12util$exe_suffix -o $testdir/dss.pfx -n CA_DSS -d $testdir -K $dbPwd -W $dbPwd"; run_test($testname, $command); #$testname = "Convert nss db to Java keystore"; #$command = "$java -cp $jss_classpath org.mozilla.jss.tests.NSS2JKS $keystore $dbPwd $configfile $dbPwd"; #run_test($testname, $command); $testname = "List CA certs"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.ListCACerts $testdir"; run_test($testname, $command); updateCertSN(); $serverPort = checkPort($serverPort); $testname = "SSLClientAuth"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.SSLClientAuth $testdir $pwfile $serverPort $certSN"; run_test($testname, $command); $testname = "Key Generation"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.TestKeyGen $testdir $pwfile"; run_test($testname, $command); $testname = "Key Factory"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.KeyFactoryTest $testdir $pwfile"; run_test($testname, $command); $testname = "Digest"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.DigestTest $testdir $pwfile"; run_test($testname, $command); $testname = "HMAC "; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.HMACTest $testdir $pwfile"; run_test($testname, $command); $testname = "HMAC Unwrap"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.HmacTest $testdir $pwfile"; run_test($testname, $command); $testname = "KeyWrapping "; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JCAKeyWrap $testdir $pwfile"; run_test($testname, $command); $testname = "Mozilla-JSS JCA Signature "; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JCASigTest $testdir $pwfile"; run_test($testname, $command); $testname = "Mozilla-JSS NSS Signature "; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.SigTest $testdir $pwfile"; run_test($testname, $command); $testname = "JSS Signature test"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.SigTest $testdir $pwfile"; run_test($testname, $command); $testname = "Secret Decoder Ring"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.TestSDR $testdir $pwfile"; run_test($testname, $command); $testname = "List cert by certnick"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.ListCerts $testdir Server_RSA"; run_test($testname, $command); $testname = "Verify cert by certnick"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.VerifyCert $testdir $pwfile Server_RSA"; run_test($testname, $command); $testname = "Secret Key Generation"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.SymKeyGen $testdir"; run_test($testname, $command); $testname = "Mozilla-JSS Secret Key Generation"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JCASymKeyGen $testdir"; run_test($testname, $command); # # SSLServer and SSLClient Ciphersuite tests # # Servers are kicked off by the shell script and are told to shutdown by the client test # $serverPort = checkPort($serverPort); $testname = "SSL Ciphersuite JSS Server and JSS client both"; $serverCommand = "$run_shell ./startJssSelfServ.$scriptext $jss_classpath $testdir $hostname $serverPort $java"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSS_SelfServClient 2 -1 $testdir $pwfile $hostname $serverPort verboseoff JSS"; # To be restored when bug 1321594 is fixed # run_ssl_test($testname, $serverCommand, $command); $serverPort = checkPort($serverPort); $testname = "SSL Ciphersuite JSS Server and JSSE client"; $serverCommand = "$run_shell ./startJssSelfServ.$scriptext $jss_classpath $testdir $hostname $serverPort $java"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSSE_SSLClient $testdir $serverPort $hostname JSS"; # To be restored when bug 1321594 is fixed #run_ssl_test($testname, $serverCommand, $command); $serverPort = checkPort($serverPort); $testname = "SSL Ciphersuite JSSE Server using default provider and JSS client"; $serverCommand = "$run_shell ./startJsseServ.$scriptext $jss_classpath $serverPort false $testdir rsa.pfx default $configfile $pwfile $java"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSS_SelfServClient 2 -1 $testdir $pwfile $hostname $serverPort verboseoff JSSE"; # To be restored when bug 1321594 is fixed #run_ssl_test($testname, $serverCommand, $command); if ($java =~ /1.4/i || $osname =~ /HP/ || ( ($osname =~ /Linux/) && $java =~ /1.5/i && ($ENV{USE_64}) )) { print "don't run the SunJSSE with Mozilla-JSS provider with Java4 need java5 or higher"; print "don't run the JSSE Server tests on HP or Linux 64 bit with java5.\n"; print "Java 5 on HP does not have SunPKCS11 class\n"; } else { #with JSS is being build with JDK 1.5 add the Sunpkcs11-NSS support back in! #$serverPort = checkPort($serverPort); #$testname = "SSL Ciphersuite JSSE Server using Sunpkcs11-NSS provider and JSS client"; #$serverCommand = "./startJsseServ.$scriptext $jss_classpath $serverPort false $testdir rsa.pfx Sunpkcs11 $configfile $pwfile $java"; #$command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSS_SelfServClient 2 -1 $testdir $pwfile $hostname $serverPort verboseoff JSSE"; #run_ssl_test($testname, $serverCommand, $command); #$serverPort = checkPort($serverPort); #$testname = "SSL Ciphersuite JSSE Server using Sunpkcs11-NSS provider and JSS client"; #$serverCommand = "./startJsseServ.$scriptext $jss_classpath $serverPort false $testdir rsa.pfx Sunpkcs11 $configfile $pwfile $java"; #$command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSS_SelfServClient 2 -1 $testdir $pwfile $hostname $serverPort verboseoff JSSE"; #run_ssl_test($testname, $serverCommand, $command); #Mozilla-JSS only works with JDK 1.5 or higher when used as provider for SunJSSE $serverPort = checkPort($serverPort); $testname = "SSL Ciphersuite JSSE Server using Mozilla-JSS provider and JSS client"; $serverCommand = "$run_shell ./startJsseServ.$scriptext $jss_classpath $serverPort false $testdir rsa.pfx Mozilla-JSS $configfile $pwfile $java"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSS_SelfServClient 2 -1 $testdir $pwfile $hostname $serverPort verboseoff Mozilla-JSS"; # To be restored when bug 1321594 is fixed #run_ssl_test($testname, $serverCommand, $command); } # # FIPSMODE tests # $testname = "Enable FipsMODE"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.FipsTest $testdir enable"; run_test($testname, $command); $testname = "check FipsMODE"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.FipsTest $testdir chkfips"; run_test($testname, $command); updateCertSN(); $testname = "SSLClientAuth FIPSMODE"; $serverPort = checkPort(++$serverPort); $command = "$java -cp $jss_classpath org.mozilla.jss.tests.SSLClientAuth $testdir $pwfile $serverPort $certSN"; run_test($testname, $command); $testname = "HMAC FIPSMODE"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.HMACTest $testdir $pwfile"; run_test($testname, $command); $testname = "KeyWrapping FIPSMODE"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JCAKeyWrap $testdir $pwfile"; run_test($testname, $command); $testname = "Mozilla-JSS JCA Signature FIPSMODE"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JCASigTest $testdir $pwfile"; run_test($testname, $command); $testname = "JSS Signature test FipsMODE"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.SigTest $testdir $pwfile"; run_test($testname, $command); $serverPort = checkPort($serverPort); $testname = "SSL Ciphersuite FIPSMODE JSS Server and JSS client both"; $serverCommand = "$run_shell ./startJssSelfServ.$scriptext $jss_classpath $testdir $hostname $serverPort $java"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSS_SelfServClient 2 -1 $testdir $pwfile $hostname $serverPort verboseoff JSS"; # To be restored when bug 1321594 is fixed #run_ssl_test($testname, $serverCommand, $command); $testname = "Disable FipsMODE"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.FipsTest $testdir disable"; run_test($testname, $command); # # Test for JSS jar and library revision # $testname = "Check JSS jar version"; $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JSSPackageTest $testdir"; run_test($testname, $command); my $LIB = "$lib_jss"."4"."$lib_suffix"; my $strings_exist = `which strings`; chomp($strings_exist); if ($strings_exist ne "") { (-f "$nss_lib_dir/$LIB") or die "$nss_lib_dir/$LIB does not exist\n"; my $jsslibver = `strings $nss_lib_dir/$LIB | grep Header`; chomp($jsslibver); if ($jsslibver ne "") { print "$LIB = $jsslibver\n"; } else { print "Could not fetch Header information from $nss_lib_dir/$LIB\n"; } } else { print "Could not fetch Header information from $nss_lib_dir/$LIB\n"; $result=1; } print "\n================= Test Results\n"; print "JSSTEST_SUITE: $testpass / $testrun\n"; my $rate = $testpass / $testrun * 100; printf "JSSTEST_RATE: %.0f %\n",$rate; if ($testpass ne $testrun) { printf "Test Status: FAILURE\n"; system("false"); printf "to test failed tests set the classpath and run the command(s)\n"; outputEnv(); } else { printf "Test Status: SUCCESS\n"; system("true"); } jss-4.4.3/jss/org/mozilla/jss/tests/bbenvSample.sh000066400000000000000000000050161326145000000221020ustar00rootroot00000000000000#! /bin/bash ############################################################################## # Update java-1.8.0-openjdk to the latest and then do # sudo /usr/sbin/alternatives --config java and hit enter # # For example, to check/select your Java version on Linux: # # sudo /usr/sbin/alternatives --config java # # There is 1 program that provides 'java'. # # Selection Command # ----------------------------------------------- # *+ 1 java-1.8.0-openjdk.x86_64 (/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc24.x86_64/jre/bin/java) # # Hit Enter to keep the current selection[+], or type selection number: # # You may have multiple entries (like on RHEl-7.x) or only one # This is for linux. On macOS you'll have something like this # JAVA_HOME_64=/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home # ############################################################################## # Each buildbot-slave requires a bbenv.sh file that defines # machine specific variables. This is an example file. HOST=$(hostname | cut -d. -f1) export HOST # if your machine's IP isn't registered in DNS, # you must set appropriate environment variables # that can be resolved locally. # For example, if localhost.localdomain works on your system, set: DOMSUF=localdomain export DOMSUF ARCH=$(uname -s) ulimit -c unlimited 2> /dev/null export NSPR_LOG_MODULES="pkix:1" #export JAVA_HOME_32= #export JAVA_HOME_64= #enable if you have PKITS data export PKITS_DATA=$HOME/pkits/ NSS_BUILD_TARGET="clean nss_build_all" JSS_BUILD_TARGET="clean all" MAKE=make AWK=awk PATCH=patch if [ "${ARCH}" = "SunOS" ]; then AWK=nawk PATCH=gpatch ARCH=SunOS/$(uname -p) fi if [ "${ARCH}" = "Linux" -a -f /etc/system-release ]; then #VERSION=`sed -e 's; release ;;' -e 's; (.*)$;;' -e 's;Red Hat Enterprise Linux Server;RHEL;' -e 's;Red Hat Enterprise Linux Workstation;RHEL;' /etc/system-release` VERSION=$(uname -r | awk -F"." '{ print $1 "." $2 }') ARCH=Linux/4.8 echo ${ARCH} fi PROCESSOR=$(uname -p) if [ "${PROCESSOR}" = "ppc64" ]; then ARCH="${ARCH}/ppc64" fi if [ "${PROCESSOR}" = "powerpc" ]; then ARCH="${ARCH}/ppc" fi PORT_64_DBG=8543 PORT_64_OPT=8544 PORT_32_DBG=8545 PORT_32_OPT=8546 if [ "${NSS_TESTS}" = "memleak" ]; then PORT_64_DBG=8547 PORT_64_OPT=8548 PORT_32_DBG=8549 PORT_32_OPT=8550 fi # change to suit your environent, refer to the instructions on how to do it # at the top of this file JAVA_HOME_64=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.111-3.b16.fc25.x86_64 export NSS_FORCE_FIPS=1 jss-4.4.3/jss/org/mozilla/jss/tests/passwords000066400000000000000000000001251326145000000212540ustar00rootroot00000000000000Internal\ Key\ Storage\ Token=m1oZilla NSS\ FIPS\ 140-2\ User\ Private\ Key=m1oZilla jss-4.4.3/jss/org/mozilla/jss/tests/runSample.sh000066400000000000000000000006621326145000000216140ustar00rootroot00000000000000#!/usr/bin/bash # NOTE: Read the notes at the top of bbenv.sh on how to set things up for # different systems # define a COMPILER_TAG to sync NSS and JSS 'OBJDIR_NAME' directory names export COMPILER_TAG=_gcc export NSPR_DS_INCLUDE=`pwd`/hg/nspr/lib/ds export RUN_BITS=64 export RUN_OPT=DBG export ENVVARS=`pwd`/bbenv.sh # --test-nss ./hg/nss/automation/buildbot-slave/build.sh --build-nss --build-jss --test-jss --nojsssign jss-4.4.3/jss/org/mozilla/jss/tests/startJssSelfServ.sh000077500000000000000000000014431326145000000231360ustar00rootroot00000000000000#!/bin/sh # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ######################################################################## # # "Starting JSS JSS_SelfServServer..." # JSS_CLASSPATH=$1 TESTDIR=$2 HOSTNAME=$3 PORT=$4 shift 4 JAVA_BIN_AND_OPT=$@ if [ -z "$JAVA_BIN_AND_OPT" ] ; then JAVA_BIN_AND_OPT=${JAVA_HOME}/bin/java fi echo "${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSS_SelfServServer ${TESTDIR} passwords ${HOSTNAME} false ${PORT} verboseoff &" ${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSS_SelfServServer ${TESTDIR} passwords ${HOSTNAME} false ${PORT} verboseoff & jss-4.4.3/jss/org/mozilla/jss/tests/startJssServ.sh000077500000000000000000000012141326145000000223200ustar00rootroot00000000000000#!/bin/sh # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ######################################################################## # # "Starting JSS JAA_SSLServer..." # JSS_CLASSPATH=$1 TESTDIR=$2 Port=$3 FipsMode=$4 shift 4 JAVA_BIN_AND_OPT=$@ if [ -z "$JAVA_BIN_AND_OPT" ] ; then JAVA_BIN_AND_OPT=${JAVA_HOME}/bin/java fi ${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSS_SSLServer ${TESTDIR} passwords localhost JSSTestServerCert true ${Port} ${FipsMode} & jss-4.4.3/jss/org/mozilla/jss/tests/startJsseServ.sh000077500000000000000000000023101326145000000224630ustar00rootroot00000000000000#!/bin/sh # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ######################################################################## # # "Starting JSSE JSSE_SSLServer Test..." # JSS_CLASSPATH=$1 Port=$2 ClientAuth=$3 TestDir=$4 dbFile=$5 provider=$6 nssConfigFile=$7 nssPWFile=$8 shift 8 JAVA_BIN_AND_OPT=$@ if [ -z "$JAVA_BIN_AND_OPT" ] ; then JAVA_BIN_AND_OPT=${JAVA_HOME}/bin/java fi #echo "command" #echo "JSS_CLASSPATH=${JSS_CLASSPATH}" #echo "Port=${Port}" #echo "ClientAuth=${ClientAuth}" #echo "TestDir=${TestDir}" #echo "dbFile=${dbFile}" #echo "provider=${provider}" #echo "nssConfigFile=${nssConfigFile}" #echo "nssPWFile=${nssPWFile}" #echo "JAVA_BIN_AND_OPT=${JAVA_BIN_AND_OPT}" echo "${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSSE_SSLServer ${Port} TLS ${ClientAuth} ${TestDir} ${dbFile} ${provider} ${nssConfigFile} ${nssPWFile}&" echo "command" ${JAVA_BIN_AND_OPT} -classpath ${JSS_CLASSPATH} org.mozilla.jss.tests.JSSE_SSLServer ${Port} TLS ${ClientAuth} ${TestDir} ${dbFile} ${provider} ${nssConfigFile} ${nssPWFile}& jss-4.4.3/jss/org/mozilla/jss/tests/unix.sh000066400000000000000000000150021326145000000206230ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. #!/usr/bin/tcsh if ( `uname` == "AIX" ) then setenv LIBPATH ../../../../../dist/AIX4.2_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/AIX/lib/aix/native_threads echo Testing \"jssjava\" on `uname` `uname -v`.`uname -r` DBG platform . . . ../../../../../dist/AIX4.2_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.6/AIX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -v`.`uname -r` DBG platform . . . ../../../../../dist/AIX4.2_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.6/AIX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LIBPATH ../../../../../dist/AIX4.2_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/AIX/lib/aix/native_threads echo Testing \"jssjava\" on `uname` `uname -v`.`uname -r` OPT platform . . . ../../../../../dist/AIX4.2_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/AIX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( `uname` == "HP-UX" ) then setenv SHLIB_PATH ../../../../../dist/HP-UXB.11.00_DBG.OBJ/lib:/share/builds/components/jdk/1.1.5/HP-UX/lib/PA_RISC/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/HP-UXB.11.00_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.5/HP-UX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/HP-UXB.11.00_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.5/HP-UX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv SHLIB_PATH ../../../../../dist/HP-UXB.11.00_OPT.OBJ/lib:/share/builds/components/jdk/1.1.5/HP-UX/lib/PA_RISC/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/HP-UXB.11.00_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/HP-UX/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( ( `uname` == "IRIX" ) || ( `uname` == "IRIX64" ) ) then setenv LD_LIBRARY_PATH ../../../../../dist/IRIX6.2_PTH_DBG.OBJ/lib:/share/builds/components/jdk/1.1.5/IRIX/lib32/sgi/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/IRIX6.2_PTH_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.5/IRIX/lib/rt.jar org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/IRIX6.2_PTH_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.5/IRIX/lib/rt.jar org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/IRIX6.2_PTH_OPT.OBJ/lib:/share/builds/components/jdk/1.1.5/IRIX/lib32/sgi/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/IRIX6.2_PTH_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/IRIX/lib/rt.jar org.mozilla.jss.crypto.PQGGen 512 else if ( `uname` == "OSF1" ) then setenv LD_LIBRARY_PATH ../../../../../dist/OSF1V4.0D_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/OSF1/lib/alpha echo Testing \"jssjava\" on `uname` `uname -r`D DBG platform . . . ../../../../../dist/OSF1V4.0D_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.5/OSF1/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r`D DBG platform . . . ../../../../../dist/OSF1V4.0D_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.5/OSF1/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/OSF1V4.0D_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/OSF1/lib/alpha echo Testing \"jssjava\" on `uname` `uname -r`D OPT platform . . . ../../../../../dist/OSF1V4.0D_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.5/OSF1/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( ( `uname` == "SunOS" ) && ( `uname -r` == "5.5.1" ) ) then setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.5.1_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.5.1_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.5.1_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.5.1_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/SunOS5.5.1_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 else if ( ( `uname` == "SunOS" ) && ( `uname -r` == "5.6" ) ) then setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.6_DBG.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.6_DBG.OBJ/bin/jssjava -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 echo Testing \"jssjava_g\" on `uname` `uname -r` DBG platform . . . ../../../../../dist/SunOS5.6_DBG.OBJ/bin/jssjava_g -classpath ../../../../../dist/classes_DBG:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 setenv LD_LIBRARY_PATH ../../../../../dist/SunOS5.6_OPT.OBJ/lib:/share/builds/components/jdk/1.1.6/SunOS/lib/sparc/native_threads echo Testing \"jssjava\" on `uname` `uname -r` OPT platform . . . ../../../../../dist/SunOS5.6_OPT.OBJ/bin/jssjava -classpath ../../../../../dist/classes:/share/builds/components/jdk/1.1.6/SunOS/lib/classes.zip org.mozilla.jss.crypto.PQGGen 512 endif jss-4.4.3/jss/org/mozilla/jss/util/000077500000000000000000000000001326145000000171215ustar00rootroot00000000000000jss-4.4.3/jss/org/mozilla/jss/util/Assert.java000066400000000000000000000042211326145000000212240ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; import org.mozilla.jss.util.*; /** * C-style assertions in Java. * These methods are only active in debug mode * (org.mozilla.jss.Debug.DEBUG==true). * * @see org.mozilla.jss.util.Debug * @see org.mozilla.jss.util.AssertionException * @version $Revision$ $Date$ */ public class Assert { /** * Assert that a condition is true. If it is not true, abort by * throwing an AssertionException. * * @param cond The condition that is being tested. */ public static void _assert(boolean cond) { if(Debug.DEBUG && !cond) { throw new org.mozilla.jss.util.AssertionException( "assertion failure!"); } } /** * Assert that a condition is true. If it is not true, abort by throwing * an AssertionException. * * @param cond The condition that is being tested. * @param msg A message describing what is wrong if the condition is false. */ public static void _assert(boolean cond, String msg) { if(Debug.DEBUG && !cond) { throw new org.mozilla.jss.util.AssertionException(msg); } } /** * Throw an AssertionException if this statement is reached. * * @param msg A message describing what was reached. */ public static void notReached(String msg) { if(Debug.DEBUG) { throw new AssertionException("should not be reached: " + msg); } } /** * Throw an AssertionException if this statement is reached. */ public static void notReached() { if(Debug.DEBUG) { throw new AssertionException(); } } /** * Throw an AssertionException because functionality is not yet implemented. * * @param msg A message describing what is not implemented. */ public static void notYetImplemented(String msg) { if(Debug.DEBUG) { throw new AssertionException("not yet implemented: " + msg); } } } jss-4.4.3/jss/org/mozilla/jss/util/AssertionException.java000066400000000000000000000013651326145000000236170ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** * Assertion exceptions are thrown when assertion code is invoked * and fails to operate properly. They subclass Error, so they will * not be caught by exception handlers. Instead, they will cause the * VM to halt and print a stack trace. * * @see org.mozilla.jss.util.Assert * @see org.mozilla.jss.util.Debug * @version $Revision$ $Date$ */ public class AssertionException extends RuntimeException { public AssertionException() {} public AssertionException(String msg) { super(msg); } } jss-4.4.3/jss/org/mozilla/jss/util/Base64InputStream.java000066400000000000000000000166151326145000000232150ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; import java.io.*; import java.util.Arrays; /** * Reads in base-64 encoded input and spits out the raw binary decoding. */ public class Base64InputStream extends FilterInputStream { private static final int WOULD_BLOCK = -2; // // decoding table // private static int[] table = new int[256]; // one-time initialization of decoding table static { int i; for( i=0; i < 256; ++i) { table[i] = -1; } int c; for( c = 'A', i=0; c <= 'Z'; ++c, ++i) { table[c] = i; } for( c = 'a'; c <= 'z'; ++c, ++i) { table[c] = i; } for( c='0'; c <= '9'; ++c, ++i) { table[c] = i; } table['+'] = 62; table['/'] = 63; } // prev is the previous significant character read from the in stream. // Significant characters are those that are part of the encoded data, // as opposed to whitespace. private int prev, savedPrev; // state is the current state of our state machine. The states are 1-5. // State 5 represents end-of-file, which occurs when we read the last // character from the input stream, or a base64 padding character ('='). // States 1-4 indicate which character of the current 4-character block we // are looking for. After state 4 we wrap back to state 1. The state // is not advanced when we read an insignificant character (such as // whitespace). private int state = 1, savedState; public Base64InputStream(InputStream in) { super(in); } public long skip(long n) throws IOException { long count = 0; while( (count < n) && (read() != -1) ) { ++count; } return count; } /** * param block Whether or not to block waiting for input. */ private int read(boolean block) throws IOException { int cur, ret=0; boolean done = false; while(!done) { if( in.available() < 1 && !block) { return WOULD_BLOCK; } cur = in.read(); switch(state) { case 1: if( cur == -1 ) { // end of file state = 5; return -1; } if( cur == '=' ) { state = 5; throw new IOException("Invalid pad character"); } if( table[cur] != -1 ) { prev = cur; state = 2; } break; case 2: if( cur == -1 ) { state = 5; throw new EOFException("Unexpected end-of-file"); } if( cur == '=' ) { state = 5; throw new IOException("Invalid pad character"); } if( table[cur] != -1 ) { ret = (table[prev]<<2) | ((table[cur]&0x30)>>4); prev = cur; state = 3; done = true; } break; case 3: if( cur == -1 ) { state = 5; throw new EOFException("Unexpected end-of-file"); } if( cur == '=' ) { // pad character state = 5; return -1; } if( table[cur] != -1 ) { ret = ((table[prev]&0x0f)<<4) | ((table[cur]&0x3c)>>2); prev = cur; state = 4; done = true; } break; case 4: if( cur == -1 ) { state = 5; throw new EOFException("Unexpected end-of-file"); } if( cur == '=' ) { // pad character state = 5; return -1; } if( table[cur] != -1 ) { ret = ((table[prev]&0x03)<<6) | table[cur]; state = 1; done = true; } break; case 5: // end of file return -1; //break; default: Assert._assert(false); break; } } return ret; } public int read() throws IOException { return read(true); } public int read(byte[] b, int off, int len) throws IOException { int count = 0; if( len < 0 ) { throw new IndexOutOfBoundsException("len is negative"); } if( off < 0 ) { throw new IndexOutOfBoundsException("off is negative"); } while( count < len ) { int cur = read(count==0); if( cur == -1 ) { // end-of-file if( count == 0 ) { return -1; } else { return count; } } if( cur == WOULD_BLOCK ) { Assert._assert(count>0); return count; } Assert._assert( cur >= 0 && cur <= 255); b[off+(count++)] = (byte) cur; } return count; } public int available() throws IOException { // We really don't know how much is left. in.available() could all // be whitespace. return 0; } public boolean markSupported() { return in.markSupported(); } public void mark(int readlimit) { in.mark(readlimit); savedPrev = prev; savedState = state; } public void close() throws IOException { in.close(); } public void reset() throws IOException { in.reset(); prev = savedPrev; state = savedState; } public static void main(String args[]) throws Exception { String infile = args[0]; String b64file = infile.concat(".b64"); String newfile = infile.concat(".recov"); FileInputStream fis = new FileInputStream(infile); ByteArrayOutputStream origStream = new ByteArrayOutputStream(); ByteArrayOutputStream b64OStream = new ByteArrayOutputStream(); Base64OutputStream b64Stream = new Base64OutputStream( new PrintStream(b64OStream), 18); int numread; byte []data = new byte[1024]; while( (numread = fis.read(data, 0, 1024)) != -1 ) { origStream.write(data, 0, numread); b64Stream.write(data, 0, numread); } b64Stream.close(); origStream.close(); Base64InputStream bis = new Base64InputStream( new ByteArrayInputStream(b64OStream.toByteArray())); ByteArrayOutputStream newStream = new ByteArrayOutputStream(); while( (numread = bis.read(data, 0, 1024)) != -1 ) { newStream.write(data, 0, numread); } newStream.close(); if( ! Arrays.equals(origStream.toByteArray(), newStream.toByteArray())){ throw new Exception("Did not recover original data"); } } } jss-4.4.3/jss/org/mozilla/jss/util/Base64OutputStream.java000066400000000000000000000107521326145000000234120ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * We would like to eventually use Sun's base64 encoder, but it is not * public yet. It is in the sun.misc package in JDK1.2. */ package org.mozilla.jss.util; import java.io.FilterOutputStream; import java.io.PrintStream; import java.io.IOException; /** * An output stream filter that takes arbitrary bytes and outputs their * base64 encoding. Call flush() or close() to write out the final padding. * The class also automatically puts line breaks in the output stream. */ public class Base64OutputStream extends FilterOutputStream { /** * Create a stream that does not insert line breaks. To have line * breaks, use the other constructor. */ public Base64OutputStream(PrintStream out) { super(out); charsOnLine = 0; inputCount = 0; input = new byte[3]; doLineBreaks = false; } /** * @param quadsPerLine Number of 4-character blocks to write before * outputting a line break. For example, for 76-characters per line, * pass in 76/4 = 19. */ public Base64OutputStream(PrintStream out, int quadsPerLine) { this(out); doLineBreaks = true; Assert._assert(quadsPerLine>0, "quadsPerLine must be > 0"); charsPerLine = quadsPerLine*4; } public void write(int oneByte) throws IOException { input[inputCount++] = (byte)(0xff & oneByte); if(inputCount==3) { outputOneAtom(); if(doLineBreaks) { if(charsOnLine==charsPerLine) { ((PrintStream)out).println(); charsOnLine=0; } Assert._assert(charsOnLine < charsPerLine); } } Assert._assert(inputCount < 3); } /** * This flushes the stream and closes the next stream downstream. */ public void close() throws IOException { flush(); out.close(); } /** * Calling this will put the ending padding on the base64 stream, * so don't call it until you have no data left. The class does no * unnecessary buffering, so you probably shouldn't call it at all. */ public void flush() throws IOException { if(inputCount > 0) { outputOneAtom(); } if(doLineBreaks) { ((PrintStream)out).println(); charsOnLine = 0; } } public void write(byte[] buffer) throws IOException { write(buffer, 0, buffer.length); } public void write(byte[] buffer, int offset, int count) throws IOException { int i; int byteCount; for(i=offset, byteCount=0; byteCount < count; i++, byteCount++) { write(buffer[i]); } } private final static char encoding[] = { // 0 1 2 3 4 5 6 7 'A','B','C','D','E','F','G','H', // 0 'I','J','K','L','M','N','O','P', // 1 'Q','R','S','T','U','V','W','X', // 2 'Y','Z','a','b','c','d','e','f', // 3 'g','h','i','j','k','l','m','n', // 4 'o','p','q','r','s','t','u','v', // 5 'w','x','y','z','0','1','2','3', // 6 '4','5','6','7','8','9','+','/' // 7 }; /** * Output 3 bytes of input as 4 bytes of base-64 encoded output. * If there are fewer than 3 bytes available, the output will be * padded according to the spec. Padding should only happen at the end * of the stream. */ private void outputOneAtom() throws IOException { byte[] output = new byte[4]; if(inputCount==0) { return; } // If we have fewer than 3 bytes, pad the rest with zeroes if(inputCount<3) { input[2]=0; if(inputCount<2) { input[1]=0; } } // Do a base64 encoding output[0] = (byte) encoding[ (input[0]>>>2) & 0x3f ]; output[1] = (byte) encoding[ (input[0]<<4)&0x30 | (input[1]>>>4)&0xf ]; output[2] = (byte) encoding[ (input[1]<<2)&0x3c | (input[2]>>>6)&0x3 ]; output[3] = (byte) encoding[ input[2]&0x3f ]; // add padding if(inputCount<3) { output[3] = (byte)'='; if(inputCount<2) { output[2] = (byte)'='; } } out.write(output); inputCount=0; if(doLineBreaks) { charsOnLine += 4; } } ////////////////////////////////////////////////////////////////////// // Private data ////////////////////////////////////////////////////////////////////// private byte[] input; // buffered input, max 3 bytes (after 3 we write // them out base64-encoded) private short inputCount; // number of bytes in input buffer private short charsOnLine; // number of bytes on the current line private int charsPerLine; // maximum characters per line private static final int DEFAULT_QUADS_PER_LINE=16; //64 chars private boolean doLineBreaks; } jss-4.4.3/jss/org/mozilla/jss/util/ConsolePasswordCallback.java000066400000000000000000000016561326145000000245360ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** * A password callback that obtains its password from the console. * Asterisks are echoed at the prompt. */ public class ConsolePasswordCallback implements PasswordCallback { public ConsolePasswordCallback() {} public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { System.out.println("Enter password for "+info.getName()); return Password.readPasswordFromConsole(); } public Password getPasswordAgain(PasswordCallbackInfo token) throws PasswordCallback.GiveUpException { System.out.println("Password incorrect, try again"); return getPasswordFirstAttempt(token); } } jss-4.4.3/jss/org/mozilla/jss/util/Debug_debug.jnot000066400000000000000000000070751326145000000222220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /********************************************************************** * --------------------------- W A R N I N G -------------------------- * * This file is the same as Debug_ship.jnot, except the static final * constants have been set to enable debugging and tracing. You must * double-edit any changes in this file into Debug_ship.jnot, and * vice-versa. **********************************************************************/ package org.mozilla.jss.util; /** * Controls debug-mode operation of JSS classes, and allows for printing * trace statements to standard output. * * @see org.mozilla.jss.util.Assert * @version $Revision$ $Date$ */ public class Debug { /** * Controls debug mode for JSS. If DEBUG==true, debugging * code will be enabled. If DEBUG==false, debugging code will not be * executed. This variable does not influence the printing of trace * statements; their execution depends on the debug level, which can * be accessed through setLevel and getLevel. * * @see org.mozilla.jss.util.Assert */ public static final boolean DEBUG = true; public static final int OBNOXIOUS = 10; public static final int VERBOSE = 5; public static final int ERROR = 1; public static final int QUIET = 0; /** * The debug level of the application. This gives the level of detail * trace messages will contain. A level of 0 means no debugging * statements will be printed. * * !!If you change this, change it in the native code too!! */ private static int mDebugLevel = VERBOSE; /** * Print a trace statement to standard output. * * @param level The detail level of the statement. * The level must be greater than 0. * @param str The trace statement. */ public synchronized static void trace(int level, String str) { // validate arguments in debug mode if(DEBUG && (level < 0) ) { throw new AssertionException("invalid debugging level "+level+ " in trace"); } if (level <= mDebugLevel) { System.out.println(Thread.currentThread().getName() + ": " + str); System.out.flush(); } } /** * Print a trace statement to standard output. * Uses the VERBOSE detail level. * * @param str The trace statement. */ public synchronized static void trace(String str) { trace(VERBOSE, str); } /** * Set the debugging level of the application. * The level must not be negative. */ public synchronized static void setLevel(int level) { // In debugging mode, validate argument if( DEBUG && (level < 0) ) { throw new AssertionException("invalid debugging level set"); } mDebugLevel = level; setNativeLevel(level); } private static native void setNativeLevel(int level); /** * Get debugging level of the application. * * @return The current debugging level of the application. */ public synchronized static int getLevel() { return mDebugLevel; } public synchronized static String getLevelStr() { switch(mDebugLevel) { case QUIET: return "QUIET"; case ERROR: return "ERROR"; case VERBOSE: return "VERBOSE"; case OBNOXIOUS: return "OBNOXIOUS"; default: return String.valueOf(mDebugLevel); } } } jss-4.4.3/jss/org/mozilla/jss/util/Debug_ship.jnot000066400000000000000000000071001326145000000220640ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /********************************************************************** * --------------------------- W A R N I N G -------------------------- * * This file is the same as Debug_debug.jnot, except the static final * constants have been set to disable debugging and tracing. You must * double-edit any changes in this file into Debug_debug.jnot, and * vice-versa. **********************************************************************/ package org.mozilla.jss.util; /** * Controls debug-mode operation of JSS classes, and allows for printing * trace statements to standard output. * * @see org.mozilla.jss.util.Assert * @version $Revision$ $Date$ */ public class Debug { /** * Controls debug mode for JSS. If DEBUG==true, debugging * code will be enabled. If DEBUG==false, debugging code will not be * executed. This variable does not influence the printing of trace * statements; their execution depends on the debug level, which can * be accessed through setLevel and getLevel. * * @see org.mozilla.jss.util.Assert */ public static final boolean DEBUG = false; public static final int OBNOXIOUS = 10; public static final int VERBOSE = 5; public static final int ERROR = 1; public static final int QUIET = 0; /** * The debug level of the application. This gives the level of detail * trace messages will contain. A level of 0 means no debugging * statements will be printed. * * !!If you change this, change it in the native code too!! */ private static int mDebugLevel = ERROR; /** * Print a trace statement to standard output. * * @param level The detail level of the statement. * The level must be greater than 0. * @param str The trace statement. */ public synchronized static void trace(int level, String str) { // validate arguments in debug mode if(DEBUG && (level < 0) ) { throw new AssertionException("invalid debugging level "+level+ " in trace"); } if (level <= mDebugLevel) { System.out.println(Thread.currentThread().getName() + ": " + str); System.out.flush(); } } /** * Print a trace statement to standard output. * Uses the VERBOSE detail level. * * @param str The trace statement. */ public synchronized static void trace(String str) { trace(VERBOSE, str); } /** * Set the debugging level of the application. * The level must not be negative. */ public synchronized static void setLevel(int level) { // In debugging mode, validate argument if( DEBUG && (level < 0) ) { throw new AssertionException("invalid debugging level set"); } mDebugLevel = level; setNativeLevel(level); } private static native void setNativeLevel(int level); /** * Get debugging level of the application. * * @return The current debugging level of the application. */ public synchronized static int getLevel() { return mDebugLevel; } public synchronized static String getLevelStr() { switch(mDebugLevel) { case QUIET: return "QUIET"; case ERROR: return "ERROR"; case VERBOSE: return "VERBOSE"; case OBNOXIOUS: return "OBNOXIOUS"; default: return String.valueOf(mDebugLevel); } } } jss-4.4.3/jss/org/mozilla/jss/util/IncorrectPasswordException.java000066400000000000000000000006441326145000000253220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; public class IncorrectPasswordException extends Exception { public IncorrectPasswordException() { super(); } public IncorrectPasswordException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/util/InvalidNicknameException.java000066400000000000000000000006361326145000000247040ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; public class InvalidNicknameException extends Exception { public InvalidNicknameException() { super(); } public InvalidNicknameException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/util/Makefile000066400000000000000000000036031326145000000205630ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. ####################################################################### # (1) Include initial platform-independent assignments (MANDATORY). # ####################################################################### include manifest.mn ####################################################################### # (2) Include "global" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/config.mk ####################################################################### # (3) Include "component" configuration information. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/config/config.mk ####################################################################### # (4) Include "local" platform-dependent assignments (OPTIONAL). # ####################################################################### include config.mk ALL_TRASH += Debug.java ####################################################################### # (5) Execute "global" rules. (OPTIONAL) # ####################################################################### include $(CORE_DEPTH)/coreconf/rules.mk ####################################################################### # (6) Execute "component" rules. (OPTIONAL) # ####################################################################### ####################################################################### # (7) Execute "local" rules. (OPTIONAL). # ####################################################################### jss-4.4.3/jss/org/mozilla/jss/util/NSPRerrs.h000066400000000000000000000133111326145000000207470ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* General NSPR 2.0 errors */ /* Caller must #include "prerror.h" */ ER2( PR_OUT_OF_MEMORY_ERROR, "Memory allocation attempt failed." ) ER2( PR_BAD_DESCRIPTOR_ERROR, "Invalid file descriptor." ) ER2( PR_WOULD_BLOCK_ERROR, "The operation would have blocked." ) ER2( PR_ACCESS_FAULT_ERROR, "Invalid memory address argument." ) ER2( PR_INVALID_METHOD_ERROR, "Invalid function for file type." ) ER2( PR_ILLEGAL_ACCESS_ERROR, "Invalid memory address argument." ) ER2( PR_UNKNOWN_ERROR, "Some unknown error has occurred." ) ER2( PR_PENDING_INTERRUPT_ERROR,"Operation interrupted by another thread." ) ER2( PR_NOT_IMPLEMENTED_ERROR, "function not implemented." ) ER2( PR_IO_ERROR, "I/O function error." ) ER2( PR_IO_TIMEOUT_ERROR, "I/O operation timed out." ) ER2( PR_IO_PENDING_ERROR, "I/O operation on busy file descriptor." ) ER2( PR_DIRECTORY_OPEN_ERROR, "The directory could not be opened." ) ER2( PR_INVALID_ARGUMENT_ERROR, "Invalid function argument." ) ER2( PR_ADDRESS_NOT_AVAILABLE_ERROR, "Network address not available (in use?)." ) ER2( PR_ADDRESS_NOT_SUPPORTED_ERROR, "Network address type not supported." ) ER2( PR_IS_CONNECTED_ERROR, "Already connected." ) ER2( PR_BAD_ADDRESS_ERROR, "Network address is invalid." ) ER2( PR_ADDRESS_IN_USE_ERROR, "Local Network address is in use." ) ER2( PR_CONNECT_REFUSED_ERROR, "Connection refused by peer." ) ER2( PR_NETWORK_UNREACHABLE_ERROR, "Network address is presently unreachable." ) ER2( PR_CONNECT_TIMEOUT_ERROR, "Connection attempt timed out." ) ER2( PR_NOT_CONNECTED_ERROR, "Network file descriptor is not connected." ) ER2( PR_LOAD_LIBRARY_ERROR, "Failure to load dynamic library." ) ER2( PR_UNLOAD_LIBRARY_ERROR, "Failure to unload dynamic library." ) ER2( PR_FIND_SYMBOL_ERROR, "Symbol not found in any of the loaded dynamic libraries." ) ER2( PR_INSUFFICIENT_RESOURCES_ERROR, "Insufficient system resources." ) ER2( PR_DIRECTORY_LOOKUP_ERROR, "A directory lookup on a network address has failed." ) ER2( PR_TPD_RANGE_ERROR, "Attempt to access a TPD key that is out of range." ) ER2( PR_PROC_DESC_TABLE_FULL_ERROR, "Process open FD table is full." ) ER2( PR_SYS_DESC_TABLE_FULL_ERROR, "System open FD table is full." ) ER2( PR_NOT_SOCKET_ERROR, "Network operation attempted on non-network file descriptor." ) ER2( PR_NOT_TCP_SOCKET_ERROR, "TCP-specific function attempted on a non-TCP file descriptor." ) ER2( PR_SOCKET_ADDRESS_IS_BOUND_ERROR, "TCP file descriptor is already bound." ) ER2( PR_NO_ACCESS_RIGHTS_ERROR, "Access Denied." ) ER2( PR_OPERATION_NOT_SUPPORTED_ERROR, "The requested operation is not supported by the platform." ) ER2( PR_PROTOCOL_NOT_SUPPORTED_ERROR, "The host operating system does not support the protocol requested." ) ER2( PR_REMOTE_FILE_ERROR, "Access to the remote file has been severed." ) ER2( PR_BUFFER_OVERFLOW_ERROR, "The value requested is too large to be stored in the data buffer provided." ) ER2( PR_CONNECT_RESET_ERROR, "TCP connection reset by peer." ) ER2( PR_RANGE_ERROR, "Unused." ) ER2( PR_DEADLOCK_ERROR, "The operation would have deadlocked." ) ER2( PR_FILE_IS_LOCKED_ERROR, "The file is already locked." ) ER2( PR_FILE_TOO_BIG_ERROR, "Write would result in file larger than the system allows." ) ER2( PR_NO_DEVICE_SPACE_ERROR, "The device for storing the file is full." ) ER2( PR_PIPE_ERROR, "Unused." ) ER2( PR_NO_SEEK_DEVICE_ERROR, "Unused." ) ER2( PR_IS_DIRECTORY_ERROR, "Cannot perform a normal file operation on a directory." ) ER2( PR_LOOP_ERROR, "Symbolic link loop." ) ER2( PR_NAME_TOO_LONG_ERROR, "File name is too long." ) ER2( PR_FILE_NOT_FOUND_ERROR, "File not found." ) ER2( PR_NOT_DIRECTORY_ERROR, "Cannot perform directory operation on a normal file." ) ER2( PR_READ_ONLY_FILESYSTEM_ERROR, "Cannot write to a read-only file system." ) ER2( PR_DIRECTORY_NOT_EMPTY_ERROR, "Cannot delete a directory that is not empty." ) ER2( PR_FILESYSTEM_MOUNTED_ERROR, "Cannot delete or rename a file object while the file system is busy." ) ER2( PR_NOT_SAME_DEVICE_ERROR, "Cannot rename a file to a file system on another device." ) ER2( PR_DIRECTORY_CORRUPTED_ERROR, "The directory object in the file system is corrupted." ) ER2( PR_FILE_EXISTS_ERROR, "Cannot create or rename a filename that already exists." ) ER2( PR_MAX_DIRECTORY_ENTRIES_ERROR, "Directory is full. No additional filenames may be added." ) ER2( PR_INVALID_DEVICE_STATE_ERROR, "The required device was in an invalid state." ) ER2( PR_DEVICE_IS_LOCKED_ERROR, "The device is locked." ) ER2( PR_NO_MORE_FILES_ERROR, "No more entries in the directory." ) ER2( PR_END_OF_FILE_ERROR, "Encountered end of file." ) ER2( PR_FILE_SEEK_ERROR, "Seek error." ) ER2( PR_FILE_IS_BUSY_ERROR, "The file is busy." ) ER2( PR_IN_PROGRESS_ERROR, "Operation is still in progress (probably a non-blocking connect)." ) ER2( PR_ALREADY_INITIATED_ERROR, "Operation has already been initiated (probably a non-blocking connect)." ) #ifdef PR_GROUP_EMPTY_ERROR ER2( PR_GROUP_EMPTY_ERROR, "The wait group is empty." ) #endif #ifdef PR_INVALID_STATE_ERROR ER2( PR_INVALID_STATE_ERROR, "Object state improper for request." ) #endif #ifdef PR_NETWORK_DOWN_ERROR ER2( PR_NETWORK_DOWN_ERROR, "Network is down." ) #endif #ifdef PR_SOCKET_SHUTDOWN_ERROR ER2( PR_SOCKET_SHUTDOWN_ERROR, "The socket was previously shut down." ) #endif #ifdef PR_CONNECT_ABORTED_ERROR ER2( PR_CONNECT_ABORTED_ERROR, "TCP Connection aborted." ) #endif #ifdef PR_HOST_UNREACHABLE_ERROR ER2( PR_HOST_UNREACHABLE_ERROR, "Host is unreachable." ) #endif /* always last */ ER2( PR_MAX_ERROR, "Placeholder for the end of the list" ) jss-4.4.3/jss/org/mozilla/jss/util/NativeErrcodes.c000066400000000000000000000347751326145000000222220ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include typedef struct { PRErrorCode native; int java; } Errcode; /* * This table correlates NSPR and NSS error codes to the enums defined * in o.m.util.NativeErrcodes. It must be kept in sync with that class. */ static Errcode errcodeTable[] = { {PR_OUT_OF_MEMORY_ERROR, 1}, {PR_BAD_DESCRIPTOR_ERROR, 2}, {PR_WOULD_BLOCK_ERROR, 3}, {PR_ACCESS_FAULT_ERROR, 4}, {PR_INVALID_METHOD_ERROR, 5}, {PR_ILLEGAL_ACCESS_ERROR, 6}, {PR_UNKNOWN_ERROR, 7}, {PR_PENDING_INTERRUPT_ERROR, 8}, {PR_NOT_IMPLEMENTED_ERROR, 9}, {PR_IO_ERROR, 10}, {PR_IO_TIMEOUT_ERROR, 11}, {PR_IO_PENDING_ERROR, 12}, {PR_DIRECTORY_OPEN_ERROR, 13}, {PR_INVALID_ARGUMENT_ERROR, 14}, {PR_ADDRESS_NOT_AVAILABLE_ERROR, 15}, {PR_ADDRESS_NOT_SUPPORTED_ERROR, 16}, {PR_IS_CONNECTED_ERROR, 17}, {PR_BAD_ADDRESS_ERROR, 18}, {PR_ADDRESS_IN_USE_ERROR, 19}, {PR_CONNECT_REFUSED_ERROR, 20}, {PR_NETWORK_UNREACHABLE_ERROR, 21}, {PR_CONNECT_TIMEOUT_ERROR, 22}, {PR_NOT_CONNECTED_ERROR, 23}, {PR_LOAD_LIBRARY_ERROR, 24}, {PR_UNLOAD_LIBRARY_ERROR, 25}, {PR_FIND_SYMBOL_ERROR, 26}, {PR_INSUFFICIENT_RESOURCES_ERROR, 27}, {PR_DIRECTORY_LOOKUP_ERROR, 28}, {PR_TPD_RANGE_ERROR, 29}, {PR_PROC_DESC_TABLE_FULL_ERROR, 30}, {PR_SYS_DESC_TABLE_FULL_ERROR, 31}, {PR_NOT_SOCKET_ERROR, 32}, {PR_NOT_TCP_SOCKET_ERROR, 33}, {PR_SOCKET_ADDRESS_IS_BOUND_ERROR, 34}, {PR_NO_ACCESS_RIGHTS_ERROR, 35}, {PR_OPERATION_NOT_SUPPORTED_ERROR, 36}, {PR_PROTOCOL_NOT_SUPPORTED_ERROR, 37}, {PR_REMOTE_FILE_ERROR, 38}, {PR_BUFFER_OVERFLOW_ERROR, 39}, {PR_CONNECT_RESET_ERROR, 40}, {PR_RANGE_ERROR, 41}, {PR_DEADLOCK_ERROR, 42}, {PR_FILE_IS_LOCKED_ERROR, 43}, {PR_FILE_TOO_BIG_ERROR, 44}, {PR_NO_DEVICE_SPACE_ERROR, 45}, {PR_PIPE_ERROR, 46}, {PR_NO_SEEK_DEVICE_ERROR, 47}, {PR_IS_DIRECTORY_ERROR, 48}, {PR_LOOP_ERROR, 49}, {PR_NAME_TOO_LONG_ERROR, 50}, {PR_FILE_NOT_FOUND_ERROR, 51}, {PR_NOT_DIRECTORY_ERROR, 52}, {PR_READ_ONLY_FILESYSTEM_ERROR, 53}, {PR_DIRECTORY_NOT_EMPTY_ERROR, 54}, {PR_FILESYSTEM_MOUNTED_ERROR, 55}, {PR_NOT_SAME_DEVICE_ERROR, 56}, {PR_DIRECTORY_CORRUPTED_ERROR, 57}, {PR_FILE_EXISTS_ERROR, 58}, {PR_MAX_DIRECTORY_ENTRIES_ERROR, 59}, {PR_INVALID_DEVICE_STATE_ERROR, 60}, {PR_DEVICE_IS_LOCKED_ERROR, 61}, {PR_NO_MORE_FILES_ERROR, 62}, {PR_END_OF_FILE_ERROR, 63}, {PR_FILE_SEEK_ERROR, 64}, {PR_FILE_IS_BUSY_ERROR, 65}, {PR_OPERATION_ABORTED_ERROR, 66}, {PR_IN_PROGRESS_ERROR, 67}, {PR_ALREADY_INITIATED_ERROR, 68}, {PR_GROUP_EMPTY_ERROR, 69}, {PR_INVALID_STATE_ERROR, 70}, {PR_NETWORK_DOWN_ERROR, 71}, {PR_SOCKET_SHUTDOWN_ERROR, 72}, {PR_CONNECT_ABORTED_ERROR, 73}, {PR_HOST_UNREACHABLE_ERROR, 74}, {SSL_ERROR_BASE, 77}, {SSL_ERROR_EXPORT_ONLY_SERVER, 78}, {SSL_ERROR_US_ONLY_SERVER, 79}, {SSL_ERROR_NO_CYPHER_OVERLAP, 80}, {SSL_ERROR_NO_CERTIFICATE, 81}, {SSL_ERROR_BAD_CERTIFICATE, 82}, {SSL_ERROR_BAD_CLIENT, 83}, {SSL_ERROR_BAD_SERVER, 84}, {SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, 85}, {SSL_ERROR_UNSUPPORTED_VERSION, 86}, {SSL_ERROR_WRONG_CERTIFICATE, 87}, {SSL_ERROR_BAD_CERT_DOMAIN, 88}, {SSL_ERROR_POST_WARNING, 89}, {SSL_ERROR_SSL2_DISABLED, 90}, {SSL_ERROR_BAD_MAC_READ, 91}, {SSL_ERROR_BAD_MAC_ALERT, 92}, {SSL_ERROR_BAD_CERT_ALERT, 93}, {SSL_ERROR_REVOKED_CERT_ALERT, 94}, {SSL_ERROR_EXPIRED_CERT_ALERT, 95}, {SSL_ERROR_SSL_DISABLED, 96}, {SSL_ERROR_FORTEZZA_PQG, 97}, {SSL_ERROR_UNKNOWN_CIPHER_SUITE, 98}, {SSL_ERROR_NO_CIPHERS_SUPPORTED, 99}, {SSL_ERROR_BAD_BLOCK_PADDING, 100}, {SSL_ERROR_RX_RECORD_TOO_LONG, 101}, {SSL_ERROR_TX_RECORD_TOO_LONG, 102}, {SSL_ERROR_RX_MALFORMED_HELLO_REQUEST, 103}, {SSL_ERROR_RX_MALFORMED_CLIENT_HELLO, 104}, {SSL_ERROR_RX_MALFORMED_SERVER_HELLO, 105}, {SSL_ERROR_RX_MALFORMED_CERTIFICATE, 106}, {SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH, 107}, {SSL_ERROR_RX_MALFORMED_CERT_REQUEST, 108}, {SSL_ERROR_RX_MALFORMED_HELLO_DONE, 109}, {SSL_ERROR_RX_MALFORMED_CERT_VERIFY, 110}, {SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH, 111}, {SSL_ERROR_RX_MALFORMED_FINISHED, 112}, {SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER, 113}, {SSL_ERROR_RX_MALFORMED_ALERT, 114}, {SSL_ERROR_RX_MALFORMED_HANDSHAKE, 115}, {SSL_ERROR_RX_MALFORMED_APPLICATION_DATA, 116}, {SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST, 117}, {SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO, 118}, {SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO, 119}, {SSL_ERROR_RX_UNEXPECTED_CERTIFICATE, 120}, {SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH, 121}, {SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST, 122}, {SSL_ERROR_RX_UNEXPECTED_HELLO_DONE, 123}, {SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY, 124}, {SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH, 125}, {SSL_ERROR_RX_UNEXPECTED_FINISHED, 126}, {SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER, 127}, {SSL_ERROR_RX_UNEXPECTED_ALERT, 128}, {SSL_ERROR_RX_UNEXPECTED_HANDSHAKE, 129}, {SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, 130}, {SSL_ERROR_RX_UNKNOWN_RECORD_TYPE, 131}, {SSL_ERROR_RX_UNKNOWN_HANDSHAKE, 132}, {SSL_ERROR_RX_UNKNOWN_ALERT, 133}, {SSL_ERROR_CLOSE_NOTIFY_ALERT, 134}, {SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, 135}, {SSL_ERROR_DECOMPRESSION_FAILURE_ALERT, 136}, {SSL_ERROR_HANDSHAKE_FAILURE_ALERT, 137}, {SSL_ERROR_ILLEGAL_PARAMETER_ALERT, 138}, {SSL_ERROR_UNSUPPORTED_CERT_ALERT, 139}, {SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT, 140}, {SSL_ERROR_GENERATE_RANDOM_FAILURE, 141}, {SSL_ERROR_SIGN_HASHES_FAILURE, 142}, {SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE, 143}, {SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE, 144}, {SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE, 145}, {SSL_ERROR_ENCRYPTION_FAILURE, 146}, {SSL_ERROR_DECRYPTION_FAILURE, 147}, {SSL_ERROR_SOCKET_WRITE_FAILURE, 148}, {SSL_ERROR_MD5_DIGEST_FAILURE, 149}, {SSL_ERROR_SHA_DIGEST_FAILURE, 150}, {SSL_ERROR_MAC_COMPUTATION_FAILURE, 151}, {SSL_ERROR_SYM_KEY_CONTEXT_FAILURE, 152}, {SSL_ERROR_SYM_KEY_UNWRAP_FAILURE, 153}, {SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED, 154}, {SSL_ERROR_IV_PARAM_FAILURE, 155}, {SSL_ERROR_INIT_CIPHER_SUITE_FAILURE, 156}, {SSL_ERROR_SESSION_KEY_GEN_FAILURE, 157}, {SSL_ERROR_NO_SERVER_KEY_FOR_ALG, 158}, {SSL_ERROR_TOKEN_INSERTION_REMOVAL, 159}, {SSL_ERROR_TOKEN_SLOT_NOT_FOUND, 160}, {SSL_ERROR_NO_COMPRESSION_OVERLAP, 161}, {SSL_ERROR_HANDSHAKE_NOT_COMPLETED, 162}, {SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE, 163}, {SSL_ERROR_CERT_KEA_MISMATCH, 164}, {SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA, 165}, {SSL_ERROR_SESSION_NOT_FOUND, 166}, {SSL_ERROR_DECRYPTION_FAILED_ALERT, 167}, {SSL_ERROR_RECORD_OVERFLOW_ALERT, 168}, {SSL_ERROR_UNKNOWN_CA_ALERT, 169}, {SSL_ERROR_ACCESS_DENIED_ALERT, 170}, {SSL_ERROR_DECODE_ERROR_ALERT, 171}, {SSL_ERROR_DECRYPT_ERROR_ALERT, 172}, {SSL_ERROR_EXPORT_RESTRICTION_ALERT, 173}, {SSL_ERROR_PROTOCOL_VERSION_ALERT, 174}, {SSL_ERROR_INSUFFICIENT_SECURITY_ALERT, 175}, {SSL_ERROR_INTERNAL_ERROR_ALERT, 176}, {SSL_ERROR_USER_CANCELED_ALERT, 177}, {SSL_ERROR_NO_RENEGOTIATION_ALERT, 178}, {SEC_ERROR_IO, 179}, {SEC_ERROR_LIBRARY_FAILURE, 180}, {SEC_ERROR_BAD_DATA, 181}, {SEC_ERROR_OUTPUT_LEN, 182}, {SEC_ERROR_INPUT_LEN, 183}, {SEC_ERROR_INVALID_ARGS, 184}, {SEC_ERROR_INVALID_ALGORITHM, 185}, {SEC_ERROR_INVALID_AVA, 186}, {SEC_ERROR_INVALID_TIME, 187}, {SEC_ERROR_BAD_DER, 188}, {SEC_ERROR_BAD_SIGNATURE, 189}, {SEC_ERROR_EXPIRED_CERTIFICATE, 190}, {SEC_ERROR_REVOKED_CERTIFICATE, 191}, {SEC_ERROR_UNKNOWN_ISSUER, 192}, {SEC_ERROR_BAD_KEY, 193}, {SEC_ERROR_BAD_PASSWORD, 194}, {SEC_ERROR_RETRY_PASSWORD, 195}, {SEC_ERROR_NO_NODELOCK, 196}, {SEC_ERROR_BAD_DATABASE, 197}, {SEC_ERROR_NO_MEMORY, 198}, {SEC_ERROR_UNTRUSTED_ISSUER, 199}, {SEC_ERROR_UNTRUSTED_CERT, 200}, {SEC_ERROR_DUPLICATE_CERT, 201}, {SEC_ERROR_DUPLICATE_CERT_NAME, 202}, {SEC_ERROR_ADDING_CERT, 203}, {SEC_ERROR_FILING_KEY, 204}, {SEC_ERROR_NO_KEY, 205}, {SEC_ERROR_CERT_VALID, 206}, {SEC_ERROR_CERT_NOT_VALID, 207}, {SEC_ERROR_CERT_NO_RESPONSE, 208}, {SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, 209}, {SEC_ERROR_CRL_EXPIRED, 210}, {SEC_ERROR_CRL_BAD_SIGNATURE, 211}, {SEC_ERROR_CRL_INVALID, 212}, {SEC_ERROR_EXTENSION_VALUE_INVALID, 213}, {SEC_ERROR_EXTENSION_NOT_FOUND, 214}, {SEC_ERROR_CA_CERT_INVALID, 215}, {SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, 216}, {SEC_ERROR_CERT_USAGES_INVALID, 217}, {SEC_INTERNAL_ONLY, 218}, {SEC_ERROR_INVALID_KEY, 219}, {SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, 220}, {SEC_ERROR_OLD_CRL, 221}, {SEC_ERROR_NO_EMAIL_CERT, 222}, {SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, 223}, {SEC_ERROR_NOT_A_RECIPIENT, 224}, {SEC_ERROR_PKCS7_KEYALG_MISMATCH, 225}, {SEC_ERROR_PKCS7_BAD_SIGNATURE, 226}, {SEC_ERROR_UNSUPPORTED_KEYALG, 227}, {SEC_ERROR_DECRYPTION_DISALLOWED, 228}, {XP_SEC_FORTEZZA_BAD_CARD, 229}, {XP_SEC_FORTEZZA_NO_CARD, 230}, {XP_SEC_FORTEZZA_NONE_SELECTED, 231}, {XP_SEC_FORTEZZA_MORE_INFO, 232}, {XP_SEC_FORTEZZA_PERSON_NOT_FOUND, 233}, {XP_SEC_FORTEZZA_NO_MORE_INFO, 234}, {XP_SEC_FORTEZZA_BAD_PIN, 235}, {XP_SEC_FORTEZZA_PERSON_ERROR, 236}, {SEC_ERROR_NO_KRL, 237}, {SEC_ERROR_KRL_EXPIRED, 238}, {SEC_ERROR_KRL_BAD_SIGNATURE, 239}, {SEC_ERROR_REVOKED_KEY, 240}, {SEC_ERROR_KRL_INVALID, 241}, {SEC_ERROR_NEED_RANDOM, 242}, {SEC_ERROR_NO_MODULE, 243}, {SEC_ERROR_NO_TOKEN, 244}, {SEC_ERROR_READ_ONLY, 245}, {SEC_ERROR_NO_SLOT_SELECTED, 246}, {SEC_ERROR_CERT_NICKNAME_COLLISION, 247}, {SEC_ERROR_KEY_NICKNAME_COLLISION, 248}, {SEC_ERROR_SAFE_NOT_CREATED, 249}, {SEC_ERROR_BAGGAGE_NOT_CREATED, 250}, {XP_JAVA_REMOVE_PRINCIPAL_ERROR, 251}, {XP_JAVA_DELETE_PRIVILEGE_ERROR, 252}, {XP_JAVA_CERT_NOT_EXISTS_ERROR, 253}, {SEC_ERROR_BAD_EXPORT_ALGORITHM, 254}, {SEC_ERROR_EXPORTING_CERTIFICATES, 255}, {SEC_ERROR_IMPORTING_CERTIFICATES, 256}, {SEC_ERROR_PKCS12_DECODING_PFX, 257}, {SEC_ERROR_PKCS12_INVALID_MAC, 258}, {SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, 259}, {SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE, 260}, {SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, 261}, {SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, 262}, {SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, 263}, {SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT, 264}, {SEC_ERROR_PKCS12_CERT_COLLISION, 265}, {SEC_ERROR_USER_CANCELLED, 266}, {SEC_ERROR_PKCS12_DUPLICATE_DATA, 267}, {SEC_ERROR_MESSAGE_SEND_ABORTED, 268}, {SEC_ERROR_INADEQUATE_KEY_USAGE, 269}, {SEC_ERROR_INADEQUATE_CERT_TYPE, 270}, {SEC_ERROR_CERT_ADDR_MISMATCH, 271}, {SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, 272}, {SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, 273}, {SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, 274}, {SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, 275}, {SEC_ERROR_PKCS12_UNABLE_TO_WRITE, 276}, {SEC_ERROR_PKCS12_UNABLE_TO_READ, 277}, {SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, 278}, {SEC_ERROR_KEYGEN_FAIL, 279}, {SEC_ERROR_INVALID_PASSWORD, 280}, {SEC_ERROR_RETRY_OLD_PASSWORD, 281}, {SEC_ERROR_BAD_NICKNAME, 282}, {SEC_ERROR_NOT_FORTEZZA_ISSUER, 283}, {SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, 284}, {SEC_ERROR_JS_INVALID_MODULE_NAME, 285}, {SEC_ERROR_JS_INVALID_DLL, 286}, {SEC_ERROR_JS_ADD_MOD_FAILURE, 287}, {SEC_ERROR_JS_DEL_MOD_FAILURE, 288}, {SEC_ERROR_OLD_KRL, 289}, {SEC_ERROR_CKL_CONFLICT, 290}, {SEC_ERROR_CERT_NOT_IN_NAME_SPACE, 291}, {SEC_ERROR_KRL_NOT_YET_VALID, 292}, {SEC_ERROR_CRL_NOT_YET_VALID, 293}, {SEC_ERROR_UNKNOWN_CERT, 294}, {SEC_ERROR_UNKNOWN_SIGNER, 295}, {SEC_ERROR_CERT_BAD_ACCESS_LOCATION, 296}, {SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, 297}, {SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, 298}, {SEC_ERROR_OCSP_MALFORMED_REQUEST, 299}, {SEC_ERROR_OCSP_SERVER_ERROR, 300}, {SEC_ERROR_OCSP_TRY_SERVER_LATER, 301}, {SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, 302}, {SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, 303}, {SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, 304}, {SEC_ERROR_OCSP_UNKNOWN_CERT, 305}, {SEC_ERROR_OCSP_NOT_ENABLED, 306}, {SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, 307}, {SEC_ERROR_OCSP_MALFORMED_RESPONSE, 308}, {SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, 309}, {SEC_ERROR_OCSP_FUTURE_RESPONSE, 310}, {SEC_ERROR_OCSP_OLD_RESPONSE, 311}, {SEC_ERROR_DIGEST_NOT_FOUND, 312}, {SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, 313} }; #define numErrcodes (sizeof(errcodeTable)/sizeof(Errcode)) static int errcodeCompare(const void *elem1, const void *elem2) { Errcode *ec1, *ec2; ec1 = (Errcode*) elem1; ec2 = (Errcode*) elem2; if( ec1->native < ec2->native ) { return -1; } else if( ec1->native == ec2->native ) { return 0; } else { /* ec1->native > ec2->native */ return 1; } } #ifdef DEBUG static int initialized = 0; #endif /************************************************************************ ** ** J S S _ i n i t E r r c o d e T r a n s l a t i o n T a b l e. ** ** Initializes the error code translation table. This should be called ** by CryptoManager.initialize(), and must be called before any calls to ** JSS_ConvertNativeErrcodeToJava. ** */ void JSS_initErrcodeTranslationTable() { /* sort the table by native errcode */ qsort(errcodeTable, numErrcodes, sizeof(Errcode), errcodeCompare); #ifdef DEBUG initialized = 1; #endif } /************************************************************************ ** ** J S S _ C o n v e r t N a t i v e E r r c o d e T o J a v a ** ** Converts an NSPR or NSS error code to a Java error code. ** (defined in the class o.m.util.NativeErrcodes) ** ** Returns ** The Java error code, or -1 if a corresponding Java error code could ** not be found. */ int JSS_ConvertNativeErrcodeToJava(PRErrorCode nativeErrcode) { Errcode key; Errcode *target; #ifdef DEBUG PR_ASSERT(initialized); #endif key.native = nativeErrcode; key.java = -1; target = bsearch( &key, errcodeTable, numErrcodes, sizeof(Errcode), errcodeCompare ); if( target == NULL ) { return -1; } else { return target->java; } } jss-4.4.3/jss/org/mozilla/jss/util/NativeErrcodes.java000066400000000000000000000506151326145000000227100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** An enumeration of all error codes from NSS and NSPR. The integer values associated with each error code are subject to change, so DO NOT DEPEND ON THEM. Only use the symbolic names. */ public class NativeErrcodes { public static final int PR_OUT_OF_MEMORY_ERROR = 1; public static final int PR_BAD_DESCRIPTOR_ERROR = 2; public static final int PR_WOULD_BLOCK_ERROR = 3; public static final int PR_ACCESS_FAULT_ERROR = 4; public static final int PR_INVALID_METHOD_ERROR = 5; public static final int PR_ILLEGAL_ACCESS_ERROR = 6; public static final int PR_UNKNOWN_ERROR = 7; public static final int PR_PENDING_INTERRUPT_ERROR = 8; public static final int PR_NOT_IMPLEMENTED_ERROR = 9; public static final int PR_IO_ERROR = 10; public static final int PR_IO_TIMEOUT_ERROR = 11; public static final int PR_IO_PENDING_ERROR = 12; public static final int PR_DIRECTORY_OPEN_ERROR = 13; public static final int PR_INVALID_ARGUMENT_ERROR = 14; public static final int PR_ADDRESS_NOT_AVAILABLE_ERROR = 15; public static final int PR_ADDRESS_NOT_SUPPORTED_ERROR = 16; public static final int PR_IS_CONNECTED_ERROR = 17; public static final int PR_BAD_ADDRESS_ERROR = 18; public static final int PR_ADDRESS_IN_USE_ERROR = 19; public static final int PR_CONNECT_REFUSED_ERROR = 20; public static final int PR_NETWORK_UNREACHABLE_ERROR = 21; public static final int PR_CONNECT_TIMEOUT_ERROR = 22; public static final int PR_NOT_CONNECTED_ERROR = 23; public static final int PR_LOAD_LIBRARY_ERROR = 24; public static final int PR_UNLOAD_LIBRARY_ERROR = 25; public static final int PR_FIND_SYMBOL_ERROR = 26; public static final int PR_INSUFFICIENT_RESOURCES_ERROR = 27; public static final int PR_DIRECTORY_LOOKUP_ERROR = 28; public static final int PR_TPD_RANGE_ERROR = 29; public static final int PR_PROC_DESC_TABLE_FULL_ERROR = 30; public static final int PR_SYS_DESC_TABLE_FULL_ERROR = 31; public static final int PR_NOT_SOCKET_ERROR = 32; public static final int PR_NOT_TCP_SOCKET_ERROR = 33; public static final int PR_SOCKET_ADDRESS_IS_BOUND_ERROR = 34; public static final int PR_NO_ACCESS_RIGHTS_ERROR = 35; public static final int PR_OPERATION_NOT_SUPPORTED_ERROR = 36; public static final int PR_PROTOCOL_NOT_SUPPORTED_ERROR = 37; public static final int PR_REMOTE_FILE_ERROR = 38; public static final int PR_BUFFER_OVERFLOW_ERROR = 39; public static final int PR_CONNECT_RESET_ERROR = 40; public static final int PR_RANGE_ERROR = 41; public static final int PR_DEADLOCK_ERROR = 42; public static final int PR_FILE_IS_LOCKED_ERROR = 43; public static final int PR_FILE_TOO_BIG_ERROR = 44; public static final int PR_NO_DEVICE_SPACE_ERROR = 45; public static final int PR_PIPE_ERROR = 46; public static final int PR_NO_SEEK_DEVICE_ERROR = 47; public static final int PR_IS_DIRECTORY_ERROR = 48; public static final int PR_LOOP_ERROR = 49; public static final int PR_NAME_TOO_LONG_ERROR = 50; public static final int PR_FILE_NOT_FOUND_ERROR = 51; public static final int PR_NOT_DIRECTORY_ERROR = 52; public static final int PR_READ_ONLY_FILESYSTEM_ERROR = 53; public static final int PR_DIRECTORY_NOT_EMPTY_ERROR = 54; public static final int PR_FILESYSTEM_MOUNTED_ERROR = 55; public static final int PR_NOT_SAME_DEVICE_ERROR = 56; public static final int PR_DIRECTORY_CORRUPTED_ERROR = 57; public static final int PR_FILE_EXISTS_ERROR = 58; public static final int PR_MAX_DIRECTORY_ENTRIES_ERROR = 59; public static final int PR_INVALID_DEVICE_STATE_ERROR = 60; public static final int PR_DEVICE_IS_LOCKED_ERROR = 61; public static final int PR_NO_MORE_FILES_ERROR = 62; public static final int PR_END_OF_FILE_ERROR = 63; public static final int PR_FILE_SEEK_ERROR = 64; public static final int PR_FILE_IS_BUSY_ERROR = 65; public static final int PR_OPERATION_ABORTED_ERROR = 66; public static final int PR_IN_PROGRESS_ERROR = 67; public static final int PR_ALREADY_INITIATED_ERROR = 68; public static final int PR_GROUP_EMPTY_ERROR = 69; public static final int PR_INVALID_STATE_ERROR = 70; public static final int PR_NETWORK_DOWN_ERROR = 71; public static final int PR_SOCKET_SHUTDOWN_ERROR = 72; public static final int PR_CONNECT_ABORTED_ERROR = 73; public static final int PR_HOST_UNREACHABLE_ERROR = 74; public static final int SSL_ERROR_BASE = 77; public static final int SSL_ERROR_EXPORT_ONLY_SERVER = 78; public static final int SSL_ERROR_US_ONLY_SERVER = 79; public static final int SSL_ERROR_NO_CYPHER_OVERLAP = 80; public static final int SSL_ERROR_NO_CERTIFICATE = 81; public static final int SSL_ERROR_BAD_CERTIFICATE = 82; public static final int SSL_ERROR_BAD_CLIENT = 83; public static final int SSL_ERROR_BAD_SERVER = 84; public static final int SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE = 85; public static final int SSL_ERROR_UNSUPPORTED_VERSION = 86; public static final int SSL_ERROR_WRONG_CERTIFICATE = 87; public static final int SSL_ERROR_BAD_CERT_DOMAIN = 88; public static final int SSL_ERROR_POST_WARNING = 89; public static final int SSL_ERROR_SSL2_DISABLED = 90; public static final int SSL_ERROR_BAD_MAC_READ = 91; public static final int SSL_ERROR_BAD_MAC_ALERT = 92; public static final int SSL_ERROR_BAD_CERT_ALERT = 93; public static final int SSL_ERROR_REVOKED_CERT_ALERT = 94; public static final int SSL_ERROR_EXPIRED_CERT_ALERT = 95; public static final int SSL_ERROR_SSL_DISABLED = 96; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * SSL_ERROR_FORTEZZA_PQG is a placeholder for backward * compatibility. */ public static final int SSL_ERROR_FORTEZZA_PQG = 97; public static final int SSL_ERROR_UNKNOWN_CIPHER_SUITE = 98; public static final int SSL_ERROR_NO_CIPHERS_SUPPORTED = 99; public static final int SSL_ERROR_BAD_BLOCK_PADDING = 100; public static final int SSL_ERROR_RX_RECORD_TOO_LONG = 101; public static final int SSL_ERROR_TX_RECORD_TOO_LONG = 102; public static final int SSL_ERROR_RX_MALFORMED_HELLO_REQUEST = 103; public static final int SSL_ERROR_RX_MALFORMED_CLIENT_HELLO = 104; public static final int SSL_ERROR_RX_MALFORMED_SERVER_HELLO = 105; public static final int SSL_ERROR_RX_MALFORMED_CERTIFICATE = 106; public static final int SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH = 107; public static final int SSL_ERROR_RX_MALFORMED_CERT_REQUEST = 108; public static final int SSL_ERROR_RX_MALFORMED_HELLO_DONE = 109; public static final int SSL_ERROR_RX_MALFORMED_CERT_VERIFY = 110; public static final int SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH = 111; public static final int SSL_ERROR_RX_MALFORMED_FINISHED = 112; public static final int SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER = 113; public static final int SSL_ERROR_RX_MALFORMED_ALERT = 114; public static final int SSL_ERROR_RX_MALFORMED_HANDSHAKE = 115; public static final int SSL_ERROR_RX_MALFORMED_APPLICATION_DATA = 116; public static final int SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST = 117; public static final int SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO = 118; public static final int SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO = 119; public static final int SSL_ERROR_RX_UNEXPECTED_CERTIFICATE = 120; public static final int SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH = 121; public static final int SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST = 122; public static final int SSL_ERROR_RX_UNEXPECTED_HELLO_DONE = 123; public static final int SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY = 124; public static final int SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH = 125; public static final int SSL_ERROR_RX_UNEXPECTED_FINISHED = 126; public static final int SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER = 127; public static final int SSL_ERROR_RX_UNEXPECTED_ALERT = 128; public static final int SSL_ERROR_RX_UNEXPECTED_HANDSHAKE = 129; public static final int SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA = 130; public static final int SSL_ERROR_RX_UNKNOWN_RECORD_TYPE = 131; public static final int SSL_ERROR_RX_UNKNOWN_HANDSHAKE = 132; public static final int SSL_ERROR_RX_UNKNOWN_ALERT = 133; public static final int SSL_ERROR_CLOSE_NOTIFY_ALERT = 134; public static final int SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT = 135; public static final int SSL_ERROR_DECOMPRESSION_FAILURE_ALERT = 136; public static final int SSL_ERROR_HANDSHAKE_FAILURE_ALERT = 137; public static final int SSL_ERROR_ILLEGAL_PARAMETER_ALERT = 138; public static final int SSL_ERROR_UNSUPPORTED_CERT_ALERT = 139; public static final int SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT = 140; public static final int SSL_ERROR_GENERATE_RANDOM_FAILURE = 141; public static final int SSL_ERROR_SIGN_HASHES_FAILURE = 142; public static final int SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE = 143; public static final int SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE = 144; public static final int SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE = 145; public static final int SSL_ERROR_ENCRYPTION_FAILURE = 146; public static final int SSL_ERROR_DECRYPTION_FAILURE = 147; public static final int SSL_ERROR_SOCKET_WRITE_FAILURE = 148; public static final int SSL_ERROR_MD5_DIGEST_FAILURE = 149; public static final int SSL_ERROR_SHA_DIGEST_FAILURE = 150; public static final int SSL_ERROR_MAC_COMPUTATION_FAILURE = 151; public static final int SSL_ERROR_SYM_KEY_CONTEXT_FAILURE = 152; public static final int SSL_ERROR_SYM_KEY_UNWRAP_FAILURE = 153; public static final int SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED = 154; public static final int SSL_ERROR_IV_PARAM_FAILURE = 155; public static final int SSL_ERROR_INIT_CIPHER_SUITE_FAILURE = 156; public static final int SSL_ERROR_SESSION_KEY_GEN_FAILURE = 157; public static final int SSL_ERROR_NO_SERVER_KEY_FOR_ALG = 158; public static final int SSL_ERROR_TOKEN_INSERTION_REMOVAL = 159; public static final int SSL_ERROR_TOKEN_SLOT_NOT_FOUND = 160; public static final int SSL_ERROR_NO_COMPRESSION_OVERLAP = 161; public static final int SSL_ERROR_HANDSHAKE_NOT_COMPLETED = 162; public static final int SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE = 163; public static final int SSL_ERROR_CERT_KEA_MISMATCH = 164; public static final int SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA = 165; public static final int SSL_ERROR_SESSION_NOT_FOUND = 166; public static final int SSL_ERROR_DECRYPTION_FAILED_ALERT = 167; public static final int SSL_ERROR_RECORD_OVERFLOW_ALERT = 168; public static final int SSL_ERROR_UNKNOWN_CA_ALERT = 169; public static final int SSL_ERROR_ACCESS_DENIED_ALERT = 170; public static final int SSL_ERROR_DECODE_ERROR_ALERT = 171; public static final int SSL_ERROR_DECRYPT_ERROR_ALERT = 172; public static final int SSL_ERROR_EXPORT_RESTRICTION_ALERT = 173; public static final int SSL_ERROR_PROTOCOL_VERSION_ALERT = 174; public static final int SSL_ERROR_INSUFFICIENT_SECURITY_ALERT = 175; public static final int SSL_ERROR_INTERNAL_ERROR_ALERT = 176; public static final int SSL_ERROR_USER_CANCELED_ALERT = 177; public static final int SSL_ERROR_NO_RENEGOTIATION_ALERT = 178; public static final int SEC_ERROR_IO = 179; public static final int SEC_ERROR_LIBRARY_FAILURE = 180; public static final int SEC_ERROR_BAD_DATA = 181; public static final int SEC_ERROR_OUTPUT_LEN = 182; public static final int SEC_ERROR_INPUT_LEN = 183; public static final int SEC_ERROR_INVALID_ARGS = 184; public static final int SEC_ERROR_INVALID_ALGORITHM = 185; public static final int SEC_ERROR_INVALID_AVA = 186; public static final int SEC_ERROR_INVALID_TIME = 187; public static final int SEC_ERROR_BAD_DER = 188; public static final int SEC_ERROR_BAD_SIGNATURE = 189; public static final int SEC_ERROR_EXPIRED_CERTIFICATE = 190; public static final int SEC_ERROR_REVOKED_CERTIFICATE = 191; public static final int SEC_ERROR_UNKNOWN_ISSUER = 192; public static final int SEC_ERROR_BAD_KEY = 193; public static final int SEC_ERROR_BAD_PASSWORD = 194; public static final int SEC_ERROR_RETRY_PASSWORD = 195; public static final int SEC_ERROR_NO_NODELOCK = 196; public static final int SEC_ERROR_BAD_DATABASE = 197; public static final int SEC_ERROR_NO_MEMORY = 198; public static final int SEC_ERROR_UNTRUSTED_ISSUER = 199; public static final int SEC_ERROR_UNTRUSTED_CERT = 200; public static final int SEC_ERROR_DUPLICATE_CERT = 201; public static final int SEC_ERROR_DUPLICATE_CERT_NAME = 202; public static final int SEC_ERROR_ADDING_CERT = 203; public static final int SEC_ERROR_FILING_KEY = 204; public static final int SEC_ERROR_NO_KEY = 205; public static final int SEC_ERROR_CERT_VALID = 206; public static final int SEC_ERROR_CERT_NOT_VALID = 207; public static final int SEC_ERROR_CERT_NO_RESPONSE = 208; public static final int SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = 209; public static final int SEC_ERROR_CRL_EXPIRED = 210; public static final int SEC_ERROR_CRL_BAD_SIGNATURE = 211; public static final int SEC_ERROR_CRL_INVALID = 212; public static final int SEC_ERROR_EXTENSION_VALUE_INVALID = 213; public static final int SEC_ERROR_EXTENSION_NOT_FOUND = 214; public static final int SEC_ERROR_CA_CERT_INVALID = 215; public static final int SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID = 216; public static final int SEC_ERROR_CERT_USAGES_INVALID = 217; public static final int SEC_INTERNAL_ONLY = 218; public static final int SEC_ERROR_INVALID_KEY = 219; public static final int SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION = 220; public static final int SEC_ERROR_OLD_CRL = 221; public static final int SEC_ERROR_NO_EMAIL_CERT = 222; public static final int SEC_ERROR_NO_RECIPIENT_CERTS_QUERY = 223; public static final int SEC_ERROR_NOT_A_RECIPIENT = 224; public static final int SEC_ERROR_PKCS7_KEYALG_MISMATCH = 225; public static final int SEC_ERROR_PKCS7_BAD_SIGNATURE = 226; public static final int SEC_ERROR_UNSUPPORTED_KEYALG = 227; public static final int SEC_ERROR_DECRYPTION_DISALLOWED = 228; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * XP_SEC_FORTEZZA_BAD_CARD, XP_SEC_FORTEZZA_NO_CARD, * XP_SEC_FORTEZZA_NONE_SELECTED, XP_SEC_FORTEZZA_MORE_INFO * XP_SEC_FORTEZZA_PERSON_NOT_FOUND, XP_SEC_FORTEZZA_NO_MORE_INFO * XP_SEC_FORTEZZA_BAD_PIN and XP_SEC_FORTEZZA_PERSON_ERROR are * placeholder for backward compatibility. */ public static final int XP_SEC_FORTEZZA_BAD_CARD = 229; public static final int XP_SEC_FORTEZZA_NO_CARD = 230; public static final int XP_SEC_FORTEZZA_NONE_SELECTED = 231; public static final int XP_SEC_FORTEZZA_MORE_INFO = 232; public static final int XP_SEC_FORTEZZA_PERSON_NOT_FOUND = 233; public static final int XP_SEC_FORTEZZA_NO_MORE_INFO = 234; public static final int XP_SEC_FORTEZZA_BAD_PIN = 235; public static final int XP_SEC_FORTEZZA_PERSON_ERROR = 236; public static final int SEC_ERROR_NO_KRL = 237; public static final int SEC_ERROR_KRL_EXPIRED = 238; public static final int SEC_ERROR_KRL_BAD_SIGNATURE = 239; public static final int SEC_ERROR_REVOKED_KEY = 240; public static final int SEC_ERROR_KRL_INVALID = 241; public static final int SEC_ERROR_NEED_RANDOM = 242; public static final int SEC_ERROR_NO_MODULE = 243; public static final int SEC_ERROR_NO_TOKEN = 244; public static final int SEC_ERROR_READ_ONLY = 245; public static final int SEC_ERROR_NO_SLOT_SELECTED = 246; public static final int SEC_ERROR_CERT_NICKNAME_COLLISION = 247; public static final int SEC_ERROR_KEY_NICKNAME_COLLISION = 248; public static final int SEC_ERROR_SAFE_NOT_CREATED = 249; public static final int SEC_ERROR_BAGGAGE_NOT_CREATED = 250; public static final int XP_JAVA_REMOVE_PRINCIPAL_ERROR = 251; public static final int XP_JAVA_DELETE_PRIVILEGE_ERROR = 252; public static final int XP_JAVA_CERT_NOT_EXISTS_ERROR = 253; public static final int SEC_ERROR_BAD_EXPORT_ALGORITHM = 254; public static final int SEC_ERROR_EXPORTING_CERTIFICATES = 255; public static final int SEC_ERROR_IMPORTING_CERTIFICATES = 256; public static final int SEC_ERROR_PKCS12_DECODING_PFX = 257; public static final int SEC_ERROR_PKCS12_INVALID_MAC = 258; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM = 259; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE = 260; public static final int SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE = 261; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM = 262; public static final int SEC_ERROR_PKCS12_UNSUPPORTED_VERSION = 263; public static final int SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT = 264; public static final int SEC_ERROR_PKCS12_CERT_COLLISION = 265; public static final int SEC_ERROR_USER_CANCELLED = 266; public static final int SEC_ERROR_PKCS12_DUPLICATE_DATA = 267; public static final int SEC_ERROR_MESSAGE_SEND_ABORTED = 268; public static final int SEC_ERROR_INADEQUATE_KEY_USAGE = 269; public static final int SEC_ERROR_INADEQUATE_CERT_TYPE = 270; public static final int SEC_ERROR_CERT_ADDR_MISMATCH = 271; public static final int SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY = 272; public static final int SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN = 273; public static final int SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME = 274; public static final int SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY = 275; public static final int SEC_ERROR_PKCS12_UNABLE_TO_WRITE = 276; public static final int SEC_ERROR_PKCS12_UNABLE_TO_READ = 277; public static final int SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED = 278; public static final int SEC_ERROR_KEYGEN_FAIL = 279; public static final int SEC_ERROR_INVALID_PASSWORD = 280; public static final int SEC_ERROR_RETRY_OLD_PASSWORD = 281; public static final int SEC_ERROR_BAD_NICKNAME = 282; /** * @deprecated As of NSS 3.11, FORTEZZA is no longer supported. * SEC_ERROR_NOT_FORTEZZA_ISSUER is a placeholder for backward * compatibility. */ public static final int SEC_ERROR_NOT_FORTEZZA_ISSUER = 283; public static final int SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY = 284; public static final int SEC_ERROR_JS_INVALID_MODULE_NAME = 285; public static final int SEC_ERROR_JS_INVALID_DLL = 286; public static final int SEC_ERROR_JS_ADD_MOD_FAILURE = 287; public static final int SEC_ERROR_JS_DEL_MOD_FAILURE = 288; public static final int SEC_ERROR_OLD_KRL = 289; public static final int SEC_ERROR_CKL_CONFLICT = 290; public static final int SEC_ERROR_CERT_NOT_IN_NAME_SPACE = 291; public static final int SEC_ERROR_KRL_NOT_YET_VALID = 292; public static final int SEC_ERROR_CRL_NOT_YET_VALID = 293; public static final int SEC_ERROR_UNKNOWN_CERT = 294; public static final int SEC_ERROR_UNKNOWN_SIGNER = 295; public static final int SEC_ERROR_CERT_BAD_ACCESS_LOCATION = 296; public static final int SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE = 297; public static final int SEC_ERROR_OCSP_BAD_HTTP_RESPONSE = 298; public static final int SEC_ERROR_OCSP_MALFORMED_REQUEST = 299; public static final int SEC_ERROR_OCSP_SERVER_ERROR = 300; public static final int SEC_ERROR_OCSP_TRY_SERVER_LATER = 301; public static final int SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = 302; public static final int SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = 303; public static final int SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS = 304; public static final int SEC_ERROR_OCSP_UNKNOWN_CERT = 305; public static final int SEC_ERROR_OCSP_NOT_ENABLED = 306; public static final int SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER = 307; public static final int SEC_ERROR_OCSP_MALFORMED_RESPONSE = 308; public static final int SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE = 309; public static final int SEC_ERROR_OCSP_FUTURE_RESPONSE = 310; public static final int SEC_ERROR_OCSP_OLD_RESPONSE = 311; public static final int SEC_ERROR_DIGEST_NOT_FOUND = 312; public static final int SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE = 313; } jss-4.4.3/jss/org/mozilla/jss/util/NativeProxy.c000066400000000000000000000054601326145000000215620ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* This file does not contain native methods of NativeProxy; rather, it * provides utility functions for using NativeProxys in C code */ #include #include #include "nativeUtil.h" /* * Given a NativeProxy, extract the pointer and store it at the given * address. * * nativeProxy: a JNI reference to a NativeProxy. * ptr: address of a void* that will receive the pointer extracted from * the NativeProxy. * Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown. * * Example: * DataStructure *recovered; * jobject proxy; * JNIEnv *env; * [...] * if(JSS_getPtrFromProxy(env, proxy, (void**)&recovered) != PR_SUCCESS) { * return; // exception was thrown! * } */ PRStatus JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr) { jclass nativeProxyClass; jfieldID byteArrayField; jbyteArray byteArray; int size; PR_ASSERT(env!=NULL && nativeProxy != NULL && ptr != NULL); nativeProxyClass = (*env)->FindClass(env, "org/mozilla/jss/util/NativeProxy"); if(nativeProxyClass == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } #ifdef DEBUG /* make sure what we got was really a NativeProxy object */ PR_ASSERT( (*env)->IsInstanceOf(env, nativeProxy, nativeProxyClass) ); #endif byteArrayField = (*env)->GetFieldID(env, nativeProxyClass, "mPointer", "[B"); if(byteArrayField==NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } byteArray = (jbyteArray) (*env)->GetObjectField(env, nativeProxy, byteArrayField); PR_ASSERT(byteArray != NULL); size = sizeof(*ptr); PR_ASSERT((*env)->GetArrayLength(env, byteArray) == size); (*env)->GetByteArrayRegion(env, byteArray, 0, size, (void*)ptr); if( (*env)->ExceptionOccurred(env) ) { PR_ASSERT(PR_FALSE); return PR_FAILURE; } else { return PR_SUCCESS; } } /* * Turn a C pointer into a Java byte array. The byte array can be passed * into a NativeProxy constructor. * * Returns a byte array containing the pointer, or NULL if an exception * was thrown. */ jbyteArray JSS_ptrToByteArray(JNIEnv *env, void *ptr) { jbyteArray byteArray; /* Construct byte array from the pointer */ byteArray = (*env)->NewByteArray(env, sizeof(ptr)); if(byteArray==NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return NULL; } (*env)->SetByteArrayRegion(env, byteArray, 0, sizeof(ptr), (jbyte*)&ptr); if((*env)->ExceptionOccurred(env) != NULL) { PR_ASSERT(PR_FALSE); return NULL; } return byteArray; } jss-4.4.3/jss/org/mozilla/jss/util/NativeProxy.h000066400000000000000000000023451326145000000215660ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef NATIVE_PROXY_H #define NATIVE_PROXY_H /* Need to include these headers before this one: #include #include */ PR_BEGIN_EXTERN_C /* * Given a NativeProxy, extract the pointer and store it at the given * address. * * nativeProxy: a JNI reference to a NativeProxy. * ptr: address of a void* that will receive the pointer extracted from * the NativeProxy. * Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown. * * Example: * DataStructure *recovered; * jobject proxy; * JNIEnv *env; * [...] * if(JSS_getPtrFromProxy(env, proxy, (void**)&recovered) != PR_SUCCESS) { * return; // exception was thrown! * } */ PRStatus JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr); /* * Turn a C pointer into a Java byte array. The byte array can be passed * into a NativeProxy constructor. * * Returns a byte array containing the pointer, or NULL if an exception * was thrown. */ jbyteArray JSS_ptrToByteArray(JNIEnv *env, void *ptr); PR_END_EXTERN_C #endif jss-4.4.3/jss/org/mozilla/jss/util/NativeProxy.java000066400000000000000000000137661326145000000222710ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; import org.mozilla.jss.util.*; import java.util.Hashtable; import java.util.Random; import java.util.Enumeration; /** * NativeProxy, a superclass for Java classes that mirror C data structures. * * It contains some code to help make sure that native memory is getting * freed properly. * * @author nicolson * @version $Revision$ $Date$ */ public abstract class NativeProxy { /** * Default constructor. Should not be called. */ private NativeProxy() { Assert._assert(false); } /** * Create a NativeProxy from a byte array representing a C pointer. * This is the only way to create a NativeProxy, it should be called * from the constructor of your subclass. * * @param pointer A byte array, created with JSS_ptrToByteArray, that * contains a pointer pointing to a native data structure. The * NativeProxy instance acts as a proxy for that native data structure. */ public NativeProxy(byte[] pointer) { Assert._assert(pointer!=null); if(Debug.DEBUG) { registryIndex = register(); } mPointer = pointer; } /** * Deep comparison operator. * @return true if obj has the same underlying native * pointer. false if the obj is null or has * a different underlying native pointer. */ public boolean equals(Object obj) { if(obj==null) { return false; } if( ! (obj instanceof NativeProxy) ) { return false; } if( ((NativeProxy)obj).mPointer.length != mPointer.length) { return false; } for(int i=0; i < mPointer.length; i++) { if(mPointer[i] != ((NativeProxy)obj).mPointer[i]) { return false; } } return true; } /** * Release the native resources used by this proxy. * Subclasses of NativeProxy must define this method to clean up * data structures in C code that are referenced by this proxy. * releaseNativeResources() will usually be implemented as a native method. *

You don't call this method; NativeProxy.finalize() calls it for you. *

You must declare a finalize() method which calls super.finalize(). */ protected abstract void releaseNativeResources(); /** * Finalize this NativeProxy by releasing its native resources. * The finalizer calls releaseNativeResources() so you don't have to. * This finalizer should be called from the finalize() method of all * subclasses: * class MyProxy extends NativeProxy { * [...] * protected void finalize() throws Throwable { * // do any object-specific finalization other than * // releasing native resources * [...] * super.finalize(); * } * } */ protected void finalize() throws Throwable { if(Debug.DEBUG) { unregister(registryIndex); } releaseNativeResources(); } /** * Byte array containing native pointer bytes. */ private byte mPointer[]; /** *

Native Proxy Registry *

In debug mode, we keep track of all NativeProxy objects in a * static registry. Whenever a NativeProxy is constructed, it * registers. Whenever it finalizes, it unregisters. At the end of * the game, we should be able to garbage collect and then assert that * the registry is empty. This could be done, for example, in the * jssjava JVM after main() completes. * This registration process verifies that people are calling * NativeProxy.finalize() from their subclasses of NativeProxy, so that * releaseNativeResources() gets called. */ private long registryIndex; static Hashtable registry; static Random indexGenerator; static { registry = new Hashtable(); indexGenerator = new Random(); } /** * Register a NativeProxy instance. * * @return The unique index of this object in the registry. */ private synchronized static long register() { Long index; // Get a unique index do { index = new Long(indexGenerator.nextLong()); } while( registry.containsKey(index) ); registry.put(index, index); return index.longValue(); } /** * Unregister a NativeProxy instance. * * @param index The index of this object in the registry, as returned * from the previous call to register(). */ private synchronized static void unregister(long index) { Long Lindex = new Long(index); Long element; element = (Long) registry.remove(Lindex); Assert._assert(element != null); } /** * @return A list of the indices in the registry. Each element is a Long. * @see NativeProxy#getRegistryIndex */ public synchronized static Enumeration getRegistryIndices() { return registry.keys(); } /** * @return The index of this NativeProxy in the NativeProxy registry. * @see NativeProxy#getRegistryIndices */ public long getRegistryIndex() { return registryIndex; } /** * Assert that the Registry is empty. Only works in debug mode; in * ship mode, it is a no-op. If the Registry is not empty when this * is called, an assertion (org.mozilla.jss.util.AssertionException) * is thrown. */ public synchronized static void assertRegistryEmpty() { if( Debug.DEBUG ) { if(! registry.isEmpty()) { Debug.trace(Debug.VERBOSE, "Warning: "+ String.valueOf(registry.size())+ " NativeProxys are still registered."); } else { Debug.trace(Debug.OBNOXIOUS, "NativeProxy registry is empty"); } } } } jss-4.4.3/jss/org/mozilla/jss/util/NotImplementedException.java000066400000000000000000000007451326145000000245750ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** * This exception is thrown whenever something isn't implemented. */ public class NotImplementedException extends Exception { public NotImplementedException() { super(); } public NotImplementedException(String mesg) { super(mesg); } } jss-4.4.3/jss/org/mozilla/jss/util/NullPasswordCallback.java000066400000000000000000000017231326145000000240410ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** * A PasswordCallback that immediately gives up. This should be used * when a user is not available to enter a password. Any operations * that require a password will fail if this is used, unless the token * has already been logged in manually. * * @see org.mozilla.jss.crypto.CryptoToken#login */ public class NullPasswordCallback implements PasswordCallback { public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } public Password getPasswordAgain(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } } jss-4.4.3/jss/org/mozilla/jss/util/Password.java000066400000000000000000000170271326145000000215750ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; import java.io.CharConversionException; import java.io.Console; /** * Stores a password. clear should be * called when the password is no longer needed so that the sensitive * information is not left in memory. *

A Password can be used as a hard-coded * PasswordCallback. * @see PasswordCallback */ public class Password implements PasswordCallback, Cloneable, java.io.Serializable { /** * Don't use this if you aren't Password. */ private Password() { cleared = true; } /** * Creates a Password from a char array, then wipes the char array. * @param pw A char[] containing the password. This array will be * cleared (set to zeroes) by the constructor. */ public Password(char[] pw) { int i; int length = pw.length; cleared = false; password = new char[length]; for(i=0; i < length; i++) { password[i] = pw[i]; pw[i] = 0; } } /** * An implementation of * PasswordCallback.getPasswordFirstAttempt. This allows * a Password object to be treated as a * PasswordCallback. This method simply returns a clone * of the password. * * @return A copy of the password. The caller is responsible for * clearing this copy. */ public synchronized Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { if(cleared) { throw new PasswordCallback.GiveUpException(); } return (Password)this.clone(); } /** * Compares this password to another and returns true if they * are the same. */ public synchronized boolean equals(Object obj) { if(obj == null || !(obj instanceof Password)) { return false; } Password pw = (Password)obj; if( pw.password==null || password==null) { return false; } if( pw.password.length != password.length ) { return false; } for(int i=0; i < password.length; i++) { if(pw.password[i] != password[i]) { return false; } } return true; } /** * An implementation of PasswordCallback.getPasswordAgain. * This allows a Password object to be used as a * PasswordCallback. This method is only called after * a call to getPasswordFirstAttempt returned the wrong * password. This means the password is incorrect and there's no * sense returning it again, so a GiveUpException is thrown. */ public synchronized Password getPasswordAgain(PasswordCallbackInfo info) throws PasswordCallback.GiveUpException { throw new PasswordCallback.GiveUpException(); } /** * Returns the char array underlying this password. It must not be * modified in any way. */ public synchronized char[] getChars() { return password; } /** * Returns a char array that is a copy of the password. * The caller is responsible for wiping the returned array, * for example using wipeChars. */ public synchronized char[] getCharCopy() { return password.clone(); } /** * Returns a null-terminated byte array that is the byte-encoding of * this password. * The returned array is a copy of the password. * The caller is responsible for wiping the returned array, * for example using wipeChars. */ synchronized byte[] getByteCopy() { return charToByte( password.clone() ); } /** * Clears the password so that sensitive data is no longer present * in memory. This should be called as soon as the password is no * longer needed. */ public synchronized void clear() { int i; int len = password.length; for(i=0; i < len; i++) { password[i] = 0; } cleared = true; } /** * Clones the password. The resulting clone will be completely independent * of the parent, which means it will have to be separately cleared. */ public synchronized Object clone() { Password dolly = new Password(); dolly.password = password.clone(); dolly.cleared = cleared; return dolly; } /** * The finalizer clears the sensitive information before releasing * it to the garbage collector, but it should have been cleared manually * before this point anyway. */ protected void finalize() throws Throwable { if(Debug.DEBUG && !cleared) { System.err.println("ERROR: Password was garbage collected before"+ " it was cleared."); } clear(); } /** * Converts a char array to a null-terminated byte array using a standard * encoding, which is currently UTF8. The caller is responsible for * clearing the copy (with wipeBytes, for example). * * @param charArray A character array, which should not be null. It will * be wiped with zeroes. * @return A copy of the charArray, converted from Unicode to UTF8. It * is the responsibility of the caller to clear the output byte array; * wipeBytes is ideal for this purpose. * @see Password#wipeBytes */ public static byte[] charToByte(char[] charArray) { byte[] byteArray; Assert._assert(charArray != null); try { byteArray = UTF8Converter.UnicodeToUTF8NullTerm(charArray); } catch(CharConversionException e) { Assert.notReached("Password could not be converted from" +" Unicode"); byteArray = new byte[] {0}; } finally { wipeChars(charArray); } return byteArray; } /** * Wipes a byte array by setting all its elements to zero. * null must not be passed in. */ public static void wipeBytes(byte[] byteArray) { Assert._assert(byteArray != null); UTF8Converter.wipeBytes(byteArray); } /** * Wipes a char array by setting all its elements to zero. * null must not be passed in. */ public static void wipeChars(char[] charArray) { int i; Assert._assert(charArray != null); for(i=0; i < charArray.length; i++) { charArray[i] = 0; } } /** * Reads a password from the console with echo disabled. This is a blocking * call which will return after the user types a newline. * It only works with ASCII password characters. * The call is synchronized because it alters terminal settings in * a way that is not thread-safe. * * @exception org.mozilla.jss.util.PasswordCallback.GiveUpException * If the user enters no password (just hits * <enter>). * @return The password the user entered at the command line. */ public static Password readPasswordFromConsole() throws PasswordCallback.GiveUpException { Console console = System.console(); char[] password = console.readPassword(); if (password == null || password.length == 0) { throw new PasswordCallback.GiveUpException(); } return new Password(password); } // The password, stored as a char[] so we can clear it. Passwords // should never be stored in Strings because Strings can't be cleared. private char[] password; // true if the char[] has been cleared of sensitive information private boolean cleared; } jss-4.4.3/jss/org/mozilla/jss/util/PasswordCallback.java000066400000000000000000000043231326145000000232050ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** * Represents a password callback, which is called to login to the key * database and to PKCS #11 tokens. *

The simplest implementation of a PasswordCallback is a Password object. * * @see org.mozilla.jss.util.Password * @see org.mozilla.jss.util.NullPasswordCallback * @see org.mozilla.jss.util.ConsolePasswordCallback * @see org.mozilla.jss.CryptoManager#setPasswordCallback */ public interface PasswordCallback { /** * This exception is thrown if the PasswordCallback * wants to stop guessing passwords. */ public static class GiveUpException extends Exception { public GiveUpException() { super(); } public GiveUpException(String mesg) { super(mesg); } } /** * Supplies a password. This is called on the first attempt; if it * returns the wrong password, getPasswordAgain will * be called on subsequent attempts. * * @param info Information about the token that is being logged into. * @return The password. This password object is owned by and will * be cleared by the caller. * @exception GiveUpException If the callback does not want to supply * a password. */ public Password getPasswordFirstAttempt(PasswordCallbackInfo info) throws GiveUpException; /** * Tries supplying a password again. This callback will be called if * the first callback returned an invalid password. It will be called * repeatedly until it returns a correct password, or it gives up by * throwing a GiveUpException. * * @param info Information about the token that is being logged into. * @return The password. This password object is owned by and will * be cleared by the caller. * @exception GiveUpException If the callback does not want to supply * a password. This may often be the case if the first attempt failed. */ public Password getPasswordAgain(PasswordCallbackInfo info) throws GiveUpException; } jss-4.4.3/jss/org/mozilla/jss/util/PasswordCallbackInfo.java000066400000000000000000000023571326145000000240260ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** * An object of this class is passed to a PasswordCallback to give it * information about the token that is being logged into. */ public class PasswordCallbackInfo { /** * @param name The name of the file or token that is being logged into. * @param type The type of object (FILE or * TOKEN) that is being logged into. */ public PasswordCallbackInfo(String name, int type) { Assert._assert(type==FILE || type==TOKEN); this.name = name; this.type = type; } /** * The name of the file or token that is being logged into. */ public String getName() { return name; } /** * The type of object that is being logged into, FILE * or TOKEN. */ public int getType() { return type; } protected String name; protected int type; /** * Logging into a file. */ static public final int FILE = 0; /** * Logging into a PKCS #11 token. */ static public final int TOKEN = 1; } jss-4.4.3/jss/org/mozilla/jss/util/SECerrs.h000066400000000000000000000470521326145000000206100ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* General security error codes */ /* Caller must #include "secerr.h" */ ER3(SEC_ERROR_IO, SEC_ERROR_BASE + 0, "An I/O error occurred during security authorization.") ER3(SEC_ERROR_LIBRARY_FAILURE, SEC_ERROR_BASE + 1, "security library failure.") ER3(SEC_ERROR_BAD_DATA, SEC_ERROR_BASE + 2, "security library: received bad data.") ER3(SEC_ERROR_OUTPUT_LEN, SEC_ERROR_BASE + 3, "security library: output length error.") ER3(SEC_ERROR_INPUT_LEN, SEC_ERROR_BASE + 4, "security library has experienced an input length error.") ER3(SEC_ERROR_INVALID_ARGS, SEC_ERROR_BASE + 5, "security library: invalid arguments.") ER3(SEC_ERROR_INVALID_ALGORITHM, SEC_ERROR_BASE + 6, "security library: invalid algorithm.") ER3(SEC_ERROR_INVALID_AVA, SEC_ERROR_BASE + 7, "security library: invalid AVA.") ER3(SEC_ERROR_INVALID_TIME, SEC_ERROR_BASE + 8, "Improperly formatted time string.") ER3(SEC_ERROR_BAD_DER, SEC_ERROR_BASE + 9, "security library: improperly formatted DER-encoded message.") ER3(SEC_ERROR_BAD_SIGNATURE, SEC_ERROR_BASE + 10, "Peer's certificate has an invalid signature.") ER3(SEC_ERROR_EXPIRED_CERTIFICATE, SEC_ERROR_BASE + 11, "Peer's Certificate has expired.") ER3(SEC_ERROR_REVOKED_CERTIFICATE, SEC_ERROR_BASE + 12, "Peer's Certificate has been revoked.") ER3(SEC_ERROR_UNKNOWN_ISSUER, SEC_ERROR_BASE + 13, "Peer's Certificate issuer is not recognized.") ER3(SEC_ERROR_BAD_KEY, SEC_ERROR_BASE + 14, "Peer's public key is invalid.") ER3(SEC_ERROR_BAD_PASSWORD, SEC_ERROR_BASE + 15, "The security password entered is incorrect.") ER3(SEC_ERROR_RETRY_PASSWORD, SEC_ERROR_BASE + 16, "New password entered incorrectly. Please try again.") ER3(SEC_ERROR_NO_NODELOCK, SEC_ERROR_BASE + 17, "security library: no nodelock.") ER3(SEC_ERROR_BAD_DATABASE, SEC_ERROR_BASE + 18, "security library: bad database.") ER3(SEC_ERROR_NO_MEMORY, SEC_ERROR_BASE + 19, "security library: memory allocation failure.") ER3(SEC_ERROR_UNTRUSTED_ISSUER, SEC_ERROR_BASE + 20, "Peer's certificate issuer has been marked as not trusted by the user.") ER3(SEC_ERROR_UNTRUSTED_CERT, SEC_ERROR_BASE + 21, "Peer's certificate has been marked as not trusted by the user.") ER3(SEC_ERROR_DUPLICATE_CERT, (SEC_ERROR_BASE + 22), "Certificate already exists in your database.") ER3(SEC_ERROR_DUPLICATE_CERT_NAME, (SEC_ERROR_BASE + 23), "Downloaded certificate's name duplicates one already in your database.") ER3(SEC_ERROR_ADDING_CERT, (SEC_ERROR_BASE + 24), "Error adding certificate to database.") ER3(SEC_ERROR_FILING_KEY, (SEC_ERROR_BASE + 25), "Error refiling the key for this certificate.") ER3(SEC_ERROR_NO_KEY, (SEC_ERROR_BASE + 26), "The private key for this certificate cannot be found in key database") ER3(SEC_ERROR_CERT_VALID, (SEC_ERROR_BASE + 27), "This certificate is valid.") ER3(SEC_ERROR_CERT_NOT_VALID, (SEC_ERROR_BASE + 28), "This certificate is not valid.") ER3(SEC_ERROR_CERT_NO_RESPONSE, (SEC_ERROR_BASE + 29), "Cert Library: No Response") ER3(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE, (SEC_ERROR_BASE + 30), "The certificate issuer's certificate has expired. Check your system date and time.") ER3(SEC_ERROR_CRL_EXPIRED, (SEC_ERROR_BASE + 31), "The CRL for the certificate's issuer has expired. Update it or check your system date and time.") ER3(SEC_ERROR_CRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 32), "The CRL for the certificate's issuer has an invalid signature.") ER3(SEC_ERROR_CRL_INVALID, (SEC_ERROR_BASE + 33), "New CRL has an invalid format.") ER3(SEC_ERROR_EXTENSION_VALUE_INVALID, (SEC_ERROR_BASE + 34), "Certificate extension value is invalid.") ER3(SEC_ERROR_EXTENSION_NOT_FOUND, (SEC_ERROR_BASE + 35), "Certificate extension not found.") ER3(SEC_ERROR_CA_CERT_INVALID, (SEC_ERROR_BASE + 36), "Issuer certificate is invalid.") ER3(SEC_ERROR_PATH_LEN_CONSTRAINT_INVALID, (SEC_ERROR_BASE + 37), "Certificate path length constraint is invalid.") ER3(SEC_ERROR_CERT_USAGES_INVALID, (SEC_ERROR_BASE + 38), "Certificate usages field is invalid.") ER3(SEC_INTERNAL_ONLY, (SEC_ERROR_BASE + 39), "**Internal ONLY module**") ER3(SEC_ERROR_INVALID_KEY, (SEC_ERROR_BASE + 40), "The key does not support the requested operation.") ER3(SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 41), "Certificate contains unknown critical extension.") ER3(SEC_ERROR_OLD_CRL, (SEC_ERROR_BASE + 42), "New CRL is not later than the current one.") ER3(SEC_ERROR_NO_EMAIL_CERT, (SEC_ERROR_BASE + 43), "Not encrypted or signed: you do not yet have an email certificate.") ER3(SEC_ERROR_NO_RECIPIENT_CERTS_QUERY, (SEC_ERROR_BASE + 44), "Not encrypted: you do not have certificates for each of the recipients.") ER3(SEC_ERROR_NOT_A_RECIPIENT, (SEC_ERROR_BASE + 45), "Cannot decrypt: you are not a recipient, or matching certificate and \ private key not found.") ER3(SEC_ERROR_PKCS7_KEYALG_MISMATCH, (SEC_ERROR_BASE + 46), "Cannot decrypt: key encryption algorithm does not match your certificate.") ER3(SEC_ERROR_PKCS7_BAD_SIGNATURE, (SEC_ERROR_BASE + 47), "Signature verification failed: no signer found, too many signers found, \ or improper or corrupted data.") ER3(SEC_ERROR_UNSUPPORTED_KEYALG, (SEC_ERROR_BASE + 48), "Unsupported or unknown key algorithm.") ER3(SEC_ERROR_DECRYPTION_DISALLOWED, (SEC_ERROR_BASE + 49), "Cannot decrypt: encrypted using a disallowed algorithm or key size.") /* Fortezza Alerts */ ER3(XP_SEC_FORTEZZA_BAD_CARD, (SEC_ERROR_BASE + 50), "Fortezza card has not been properly initialized. \ Please remove it and return it to your issuer.") ER3(XP_SEC_FORTEZZA_NO_CARD, (SEC_ERROR_BASE + 51), "No Fortezza cards Found") ER3(XP_SEC_FORTEZZA_NONE_SELECTED, (SEC_ERROR_BASE + 52), "No Fortezza card selected") ER3(XP_SEC_FORTEZZA_MORE_INFO, (SEC_ERROR_BASE + 53), "Please select a personality to get more info on") ER3(XP_SEC_FORTEZZA_PERSON_NOT_FOUND, (SEC_ERROR_BASE + 54), "Personality not found") ER3(XP_SEC_FORTEZZA_NO_MORE_INFO, (SEC_ERROR_BASE + 55), "No more information on that Personality") ER3(XP_SEC_FORTEZZA_BAD_PIN, (SEC_ERROR_BASE + 56), "Invalid Pin") ER3(XP_SEC_FORTEZZA_PERSON_ERROR, (SEC_ERROR_BASE + 57), "Couldn't initialize Fortezza personalities.") /* end fortezza alerts. */ ER3(SEC_ERROR_NO_KRL, (SEC_ERROR_BASE + 58), "No KRL for this site's certificate has been found.") ER3(SEC_ERROR_KRL_EXPIRED, (SEC_ERROR_BASE + 59), "The KRL for this site's certificate has expired.") ER3(SEC_ERROR_KRL_BAD_SIGNATURE, (SEC_ERROR_BASE + 60), "The KRL for this site's certificate has an invalid signature.") ER3(SEC_ERROR_REVOKED_KEY, (SEC_ERROR_BASE + 61), "The key for this site's certificate has been revoked.") ER3(SEC_ERROR_KRL_INVALID, (SEC_ERROR_BASE + 62), "New KRL has an invalid format.") ER3(SEC_ERROR_NEED_RANDOM, (SEC_ERROR_BASE + 63), "security library: need random data.") ER3(SEC_ERROR_NO_MODULE, (SEC_ERROR_BASE + 64), "security library: no security module can perform the requested operation.") ER3(SEC_ERROR_NO_TOKEN, (SEC_ERROR_BASE + 65), "The security card or token does not exist, needs to be initialized, or has been removed.") ER3(SEC_ERROR_READ_ONLY, (SEC_ERROR_BASE + 66), "security library: read-only database.") ER3(SEC_ERROR_NO_SLOT_SELECTED, (SEC_ERROR_BASE + 67), "No slot or token was selected.") ER3(SEC_ERROR_CERT_NICKNAME_COLLISION, (SEC_ERROR_BASE + 68), "A certificate with the same nickname already exists.") ER3(SEC_ERROR_KEY_NICKNAME_COLLISION, (SEC_ERROR_BASE + 69), "A key with the same nickname already exists.") ER3(SEC_ERROR_SAFE_NOT_CREATED, (SEC_ERROR_BASE + 70), "error while creating safe object") ER3(SEC_ERROR_BAGGAGE_NOT_CREATED, (SEC_ERROR_BASE + 71), "error while creating baggage object") ER3(XP_JAVA_REMOVE_PRINCIPAL_ERROR, (SEC_ERROR_BASE + 72), "Couldn't remove the principal") ER3(XP_JAVA_DELETE_PRIVILEGE_ERROR, (SEC_ERROR_BASE + 73), "Couldn't delete the privilege") ER3(XP_JAVA_CERT_NOT_EXISTS_ERROR, (SEC_ERROR_BASE + 74), "This principal doesn't have a certificate") ER3(SEC_ERROR_BAD_EXPORT_ALGORITHM, (SEC_ERROR_BASE + 75), "Required algorithm is not allowed.") ER3(SEC_ERROR_EXPORTING_CERTIFICATES, (SEC_ERROR_BASE + 76), "Error attempting to export certificates.") ER3(SEC_ERROR_IMPORTING_CERTIFICATES, (SEC_ERROR_BASE + 77), "Error attempting to import certificates.") ER3(SEC_ERROR_PKCS12_DECODING_PFX, (SEC_ERROR_BASE + 78), "Unable to import. Decoding error. File not valid.") ER3(SEC_ERROR_PKCS12_INVALID_MAC, (SEC_ERROR_BASE + 79), "Unable to import. Invalid MAC. Incorrect password or corrupt file.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_MAC_ALGORITHM, (SEC_ERROR_BASE + 80), "Unable to import. MAC algorithm not supported.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_TRANSPORT_MODE,(SEC_ERROR_BASE + 81), "Unable to import. Only password integrity and privacy modes supported.") ER3(SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE, (SEC_ERROR_BASE + 82), "Unable to import. File structure is corrupt.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_PBE_ALGORITHM, (SEC_ERROR_BASE + 83), "Unable to import. Encryption algorithm not supported.") ER3(SEC_ERROR_PKCS12_UNSUPPORTED_VERSION, (SEC_ERROR_BASE + 84), "Unable to import. File version not supported.") ER3(SEC_ERROR_PKCS12_PRIVACY_PASSWORD_INCORRECT,(SEC_ERROR_BASE + 85), "Unable to import. Incorrect privacy password.") ER3(SEC_ERROR_PKCS12_CERT_COLLISION, (SEC_ERROR_BASE + 86), "Unable to import. Same nickname already exists in database.") ER3(SEC_ERROR_USER_CANCELLED, (SEC_ERROR_BASE + 87), "The user pressed cancel.") ER3(SEC_ERROR_PKCS12_DUPLICATE_DATA, (SEC_ERROR_BASE + 88), "Not imported, already in database.") ER3(SEC_ERROR_MESSAGE_SEND_ABORTED, (SEC_ERROR_BASE + 89), "Message not sent.") ER3(SEC_ERROR_INADEQUATE_KEY_USAGE, (SEC_ERROR_BASE + 90), "Certificate key usage inadequate for attempted operation.") ER3(SEC_ERROR_INADEQUATE_CERT_TYPE, (SEC_ERROR_BASE + 91), "Certificate type not approved for application.") ER3(SEC_ERROR_CERT_ADDR_MISMATCH, (SEC_ERROR_BASE + 92), "Address in signing certificate does not match address in message headers.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_IMPORT_KEY, (SEC_ERROR_BASE + 93), "Unable to import. Error attempting to import private key.") ER3(SEC_ERROR_PKCS12_IMPORTING_CERT_CHAIN, (SEC_ERROR_BASE + 94), "Unable to import. Error attempting to import certificate chain.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_LOCATE_OBJECT_BY_NAME, (SEC_ERROR_BASE + 95), "Unable to export. Unable to locate certificate or key by nickname.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_EXPORT_KEY, (SEC_ERROR_BASE + 96), "Unable to export. Private Key could not be located and exported.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_WRITE, (SEC_ERROR_BASE + 97), "Unable to export. Unable to write the export file.") ER3(SEC_ERROR_PKCS12_UNABLE_TO_READ, (SEC_ERROR_BASE + 98), "Unable to import. Unable to read the import file.") ER3(SEC_ERROR_PKCS12_KEY_DATABASE_NOT_INITIALIZED, (SEC_ERROR_BASE + 99), "Unable to export. Key database corrupt or deleted.") ER3(SEC_ERROR_KEYGEN_FAIL, (SEC_ERROR_BASE + 100), "Unable to generate public/private key pair.") ER3(SEC_ERROR_INVALID_PASSWORD, (SEC_ERROR_BASE + 101), "Password entered is invalid. Please pick a different one.") ER3(SEC_ERROR_RETRY_OLD_PASSWORD, (SEC_ERROR_BASE + 102), "Old password entered incorrectly. Please try again.") ER3(SEC_ERROR_BAD_NICKNAME, (SEC_ERROR_BASE + 103), "Certificate nickname already in use.") ER3(SEC_ERROR_NOT_FORTEZZA_ISSUER, (SEC_ERROR_BASE + 104), "Peer FORTEZZA chain has a non-FORTEZZA Certificate.") ER3(SEC_ERROR_CANNOT_MOVE_SENSITIVE_KEY, (SEC_ERROR_BASE + 105), "A sensitive key cannot be moved to the slot where it is needed.") ER3(SEC_ERROR_JS_INVALID_MODULE_NAME, (SEC_ERROR_BASE + 106), "Invalid module name.") ER3(SEC_ERROR_JS_INVALID_DLL, (SEC_ERROR_BASE + 107), "Invalid module path/filename") ER3(SEC_ERROR_JS_ADD_MOD_FAILURE, (SEC_ERROR_BASE + 108), "Unable to add module") ER3(SEC_ERROR_JS_DEL_MOD_FAILURE, (SEC_ERROR_BASE + 109), "Unable to delete module") ER3(SEC_ERROR_OLD_KRL, (SEC_ERROR_BASE + 110), "New KRL is not later than the current one.") ER3(SEC_ERROR_CKL_CONFLICT, (SEC_ERROR_BASE + 111), "New CKL has different issuer than current CKL. Delete current CKL.") ER3(SEC_ERROR_CERT_NOT_IN_NAME_SPACE, (SEC_ERROR_BASE + 112), "The Certifying Authority for this certificate is not permitted to issue a \ certificate with this name.") ER3(SEC_ERROR_KRL_NOT_YET_VALID, (SEC_ERROR_BASE + 113), "The key revocation list for this certificate is not yet valid.") ER3(SEC_ERROR_CRL_NOT_YET_VALID, (SEC_ERROR_BASE + 114), "The certificate revocation list for this certificate is not yet valid.") ER3(SEC_ERROR_UNKNOWN_CERT, (SEC_ERROR_BASE + 115), "The requested certificate could not be found.") ER3(SEC_ERROR_UNKNOWN_SIGNER, (SEC_ERROR_BASE + 116), "The signer's certificate could not be found.") ER3(SEC_ERROR_CERT_BAD_ACCESS_LOCATION, (SEC_ERROR_BASE + 117), "The location for the certificate status server has invalid format.") ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_TYPE, (SEC_ERROR_BASE + 118), "The OCSP response cannot be fully decoded; it is of an unknown type.") ER3(SEC_ERROR_OCSP_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 119), "The OCSP server returned unexpected/invalid HTTP data.") ER3(SEC_ERROR_OCSP_MALFORMED_REQUEST, (SEC_ERROR_BASE + 120), "The OCSP server found the request to be corrupted or improperly formed.") ER3(SEC_ERROR_OCSP_SERVER_ERROR, (SEC_ERROR_BASE + 121), "The OCSP server experienced an internal error.") ER3(SEC_ERROR_OCSP_TRY_SERVER_LATER, (SEC_ERROR_BASE + 122), "The OCSP server suggests trying again later.") ER3(SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, (SEC_ERROR_BASE + 123), "The OCSP server requires a signature on this request.") ER3(SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, (SEC_ERROR_BASE + 124), "The OCSP server has refused this request as unauthorized.") ER3(SEC_ERROR_OCSP_UNKNOWN_RESPONSE_STATUS, (SEC_ERROR_BASE + 125), "The OCSP server returned an unrecognizable status.") ER3(SEC_ERROR_OCSP_UNKNOWN_CERT, (SEC_ERROR_BASE + 126), "The OCSP server has no status for the certificate.") ER3(SEC_ERROR_OCSP_NOT_ENABLED, (SEC_ERROR_BASE + 127), "You must enable OCSP before performing this operation.") ER3(SEC_ERROR_OCSP_NO_DEFAULT_RESPONDER, (SEC_ERROR_BASE + 128), "You must set the OCSP default responder before performing this operation.") ER3(SEC_ERROR_OCSP_MALFORMED_RESPONSE, (SEC_ERROR_BASE + 129), "The response from the OCSP server was corrupted or improperly formed.") ER3(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE, (SEC_ERROR_BASE + 130), "The signer of the OCSP response is not authorized to give status for \ this certificate.") ER3(SEC_ERROR_OCSP_FUTURE_RESPONSE, (SEC_ERROR_BASE + 131), "The OCSP response is not yet valid (contains a date in the future).") ER3(SEC_ERROR_OCSP_OLD_RESPONSE, (SEC_ERROR_BASE + 132), "The OCSP response contains out-of-date information.") ER3(SEC_ERROR_DIGEST_NOT_FOUND, (SEC_ERROR_BASE + 133), "The CMS or PKCS #7 Digest was not found in signed message.") ER3(SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE, (SEC_ERROR_BASE + 134), "The CMS or PKCS #7 Message type is unsupported.") ER3(SEC_ERROR_MODULE_STUCK, (SEC_ERROR_BASE + 135), "PKCS #11 module could not be removed because it is still in use.") ER3(SEC_ERROR_BAD_TEMPLATE, (SEC_ERROR_BASE + 136), "Could not decode ASN.1 data. Specified template was invalid.") ER3(SEC_ERROR_CRL_NOT_FOUND, (SEC_ERROR_BASE + 137), "No matching CRL was found.") ER3(SEC_ERROR_REUSED_ISSUER_AND_SERIAL, (SEC_ERROR_BASE + 138), "You are attempting to import a cert with the same issuer/serial as \ an existing cert, but that is not the same cert.") ER3(SEC_ERROR_BUSY, (SEC_ERROR_BASE + 139), "NSS could not shutdown. Objects are still in use.") ER3(SEC_ERROR_EXTRA_INPUT, (SEC_ERROR_BASE + 140), "DER-encoded message contained extra unused data.") ER3(SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE, (SEC_ERROR_BASE + 141), "Unsupported elliptic curve.") ER3(SEC_ERROR_UNSUPPORTED_EC_POINT_FORM, (SEC_ERROR_BASE + 142), "Unsupported elliptic curve point form.") ER3(SEC_ERROR_UNRECOGNIZED_OID, (SEC_ERROR_BASE + 143), "Unrecognized Object Identifier.") ER3(SEC_ERROR_OCSP_INVALID_SIGNING_CERT, (SEC_ERROR_BASE + 144), "Invalid OCSP signing certificate in OCSP response.") ER3(SEC_ERROR_REVOKED_CERTIFICATE_CRL, (SEC_ERROR_BASE + 145), "Certificate is revoked in issuer's certificate revocation list.") ER3(SEC_ERROR_REVOKED_CERTIFICATE_OCSP, (SEC_ERROR_BASE + 146), "Issuer's OCSP responder reports certificate is revoked.") ER3(SEC_ERROR_CRL_INVALID_VERSION, (SEC_ERROR_BASE + 147), "Issuer's Certificate Revocation List has an unknown version number.") ER3(SEC_ERROR_CRL_V1_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 148), "Issuer's V1 Certificate Revocation List has a critical extension.") ER3(SEC_ERROR_CRL_UNKNOWN_CRITICAL_EXTENSION, (SEC_ERROR_BASE + 149), "Issuer's V2 Certificate Revocation List has an unknown critical extension.") ER3(SEC_ERROR_UNKNOWN_OBJECT_TYPE, (SEC_ERROR_BASE + 150), "Unknown object type specified.") ER3(SEC_ERROR_INCOMPATIBLE_PKCS11, (SEC_ERROR_BASE + 151), "PKCS #11 driver violates the spec in an incompatible way.") ER3(SEC_ERROR_NO_EVENT, (SEC_ERROR_BASE + 152), "No new slot event is available at this time.") ER3(SEC_ERROR_CRL_ALREADY_EXISTS, (SEC_ERROR_BASE + 153), "CRL already exists.") ER3(SEC_ERROR_NOT_INITIALIZED, (SEC_ERROR_BASE + 154), "NSS is not initialized.") ER3(SEC_ERROR_TOKEN_NOT_LOGGED_IN, (SEC_ERROR_BASE + 155), "The operation failed because the PKCS#11 token is not logged in.") ER3(SEC_ERROR_OCSP_RESPONDER_CERT_INVALID, (SEC_ERROR_BASE + 156), "Configured OCSP responder's certificate is invalid.") ER3(SEC_ERROR_OCSP_BAD_SIGNATURE, (SEC_ERROR_BASE + 157), "OCSP response has an invalid signature.") ER3(SEC_ERROR_OUT_OF_SEARCH_LIMITS, (SEC_ERROR_BASE + 158), "Cert validation search is out of search limits") ER3(SEC_ERROR_INVALID_POLICY_MAPPING, (SEC_ERROR_BASE + 159), "Policy mapping contains anypolicy") ER3(SEC_ERROR_POLICY_VALIDATION_FAILED, (SEC_ERROR_BASE + 160), "Cert chain fails policy validation") ER3(SEC_ERROR_UNKNOWN_AIA_LOCATION_TYPE, (SEC_ERROR_BASE + 161), "Unknown location type in cert AIA extension") ER3(SEC_ERROR_BAD_HTTP_RESPONSE, (SEC_ERROR_BASE + 162), "Server returned bad HTTP response") ER3(SEC_ERROR_BAD_LDAP_RESPONSE, (SEC_ERROR_BASE + 163), "Server returned bad LDAP response") ER3(SEC_ERROR_FAILED_TO_ENCODE_DATA, (SEC_ERROR_BASE + 164), "Failed to encode data with ASN1 encoder") ER3(SEC_ERROR_BAD_INFO_ACCESS_LOCATION, (SEC_ERROR_BASE + 165), "Bad information access location in cert extension") ER3(SEC_ERROR_LIBPKIX_INTERNAL, (SEC_ERROR_BASE + 166), "Libpkix internal error occured during cert validation.") ER3(SEC_ERROR_PKCS11_GENERAL_ERROR, (SEC_ERROR_BASE + 167), "A PKCS #11 module returned CKR_GENERAL_ERROR, indicating that an unrecoverable error has occurred.") ER3(SEC_ERROR_PKCS11_FUNCTION_FAILED, (SEC_ERROR_BASE + 168), "A PKCS #11 module returned CKR_FUNCTION_FAILED, indicating that the requested function could not be performed. Trying the same operation again might succeed.") ER3(SEC_ERROR_PKCS11_DEVICE_ERROR, (SEC_ERROR_BASE + 169), "A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.") ER3(SEC_ERROR_BAD_INFO_ACCESS_METHOD, (SEC_ERROR_BASE + 170), "Unknown information access method in certificate extension.") ER3(SEC_ERROR_CRL_IMPORT_FAILED, (SEC_ERROR_BASE + 171), "Error attempting to import a CRL.") jss-4.4.3/jss/org/mozilla/jss/util/SSLerrs.h000066400000000000000000000356671326145000000206500ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* SSL-specific security error codes */ /* caller must include "sslerr.h" */ ER3(SSL_ERROR_EXPORT_ONLY_SERVER, SSL_ERROR_BASE + 0, "Unable to communicate securely. Peer does not support high-grade encryption.") ER3(SSL_ERROR_US_ONLY_SERVER, SSL_ERROR_BASE + 1, "Unable to communicate securely. Peer requires high-grade encryption which is not supported.") ER3(SSL_ERROR_NO_CYPHER_OVERLAP, SSL_ERROR_BASE + 2, "Cannot communicate securely with peer: no common encryption algorithm(s).") ER3(SSL_ERROR_NO_CERTIFICATE, SSL_ERROR_BASE + 3, "Unable to find the certificate or key necessary for authentication.") ER3(SSL_ERROR_BAD_CERTIFICATE, SSL_ERROR_BASE + 4, "Unable to communicate securely with peer: peers's certificate was rejected.") /* unused (SSL_ERROR_BASE + 5),*/ ER3(SSL_ERROR_BAD_CLIENT, SSL_ERROR_BASE + 6, "The server has encountered bad data from the client.") ER3(SSL_ERROR_BAD_SERVER, SSL_ERROR_BASE + 7, "The client has encountered bad data from the server.") ER3(SSL_ERROR_UNSUPPORTED_CERTIFICATE_TYPE, SSL_ERROR_BASE + 8, "Unsupported certificate type.") ER3(SSL_ERROR_UNSUPPORTED_VERSION, SSL_ERROR_BASE + 9, "Peer using unsupported version of security protocol.") /* unused (SSL_ERROR_BASE + 10),*/ ER3(SSL_ERROR_WRONG_CERTIFICATE, SSL_ERROR_BASE + 11, "Client authentication failed: private key in key database does not match public key in certificate database.") ER3(SSL_ERROR_BAD_CERT_DOMAIN, SSL_ERROR_BASE + 12, "Unable to communicate securely with peer: requested domain name does not match the server's certificate.") /* SSL_ERROR_POST_WARNING (SSL_ERROR_BASE + 13), defined in sslerr.h */ ER3(SSL_ERROR_SSL2_DISABLED, (SSL_ERROR_BASE + 14), "Peer only supports SSL version 2, which is locally disabled.") ER3(SSL_ERROR_BAD_MAC_READ, (SSL_ERROR_BASE + 15), "SSL received a record with an incorrect Message Authentication Code.") ER3(SSL_ERROR_BAD_MAC_ALERT, (SSL_ERROR_BASE + 16), "SSL peer reports incorrect Message Authentication Code.") ER3(SSL_ERROR_BAD_CERT_ALERT, (SSL_ERROR_BASE + 17), "SSL peer cannot verify your certificate.") ER3(SSL_ERROR_REVOKED_CERT_ALERT, (SSL_ERROR_BASE + 18), "SSL peer rejected your certificate as revoked.") ER3(SSL_ERROR_EXPIRED_CERT_ALERT, (SSL_ERROR_BASE + 19), "SSL peer rejected your certificate as expired.") ER3(SSL_ERROR_SSL_DISABLED, (SSL_ERROR_BASE + 20), "Cannot connect: SSL is disabled.") ER3(SSL_ERROR_FORTEZZA_PQG, (SSL_ERROR_BASE + 21), "Cannot connect: SSL peer is in another FORTEZZA domain.") ER3(SSL_ERROR_UNKNOWN_CIPHER_SUITE , (SSL_ERROR_BASE + 22), "An unknown SSL cipher suite has been requested.") ER3(SSL_ERROR_NO_CIPHERS_SUPPORTED , (SSL_ERROR_BASE + 23), "No cipher suites are present and enabled in this program.") ER3(SSL_ERROR_BAD_BLOCK_PADDING , (SSL_ERROR_BASE + 24), "SSL received a record with bad block padding.") ER3(SSL_ERROR_RX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 25), "SSL received a record that exceeded the maximum permissible length.") ER3(SSL_ERROR_TX_RECORD_TOO_LONG , (SSL_ERROR_BASE + 26), "SSL attempted to send a record that exceeded the maximum permissible length.") /* * Received a malformed (too long or short or invalid content) SSL handshake. */ ER3(SSL_ERROR_RX_MALFORMED_HELLO_REQUEST , (SSL_ERROR_BASE + 27), "SSL received a malformed Hello Request handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CLIENT_HELLO , (SSL_ERROR_BASE + 28), "SSL received a malformed Client Hello handshake message.") ER3(SSL_ERROR_RX_MALFORMED_SERVER_HELLO , (SSL_ERROR_BASE + 29), "SSL received a malformed Server Hello handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CERTIFICATE , (SSL_ERROR_BASE + 30), "SSL received a malformed Certificate handshake message.") ER3(SSL_ERROR_RX_MALFORMED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 31), "SSL received a malformed Server Key Exchange handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CERT_REQUEST , (SSL_ERROR_BASE + 32), "SSL received a malformed Certificate Request handshake message.") ER3(SSL_ERROR_RX_MALFORMED_HELLO_DONE , (SSL_ERROR_BASE + 33), "SSL received a malformed Server Hello Done handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CERT_VERIFY , (SSL_ERROR_BASE + 34), "SSL received a malformed Certificate Verify handshake message.") ER3(SSL_ERROR_RX_MALFORMED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 35), "SSL received a malformed Client Key Exchange handshake message.") ER3(SSL_ERROR_RX_MALFORMED_FINISHED , (SSL_ERROR_BASE + 36), "SSL received a malformed Finished handshake message.") /* * Received a malformed (too long or short) SSL record. */ ER3(SSL_ERROR_RX_MALFORMED_CHANGE_CIPHER , (SSL_ERROR_BASE + 37), "SSL received a malformed Change Cipher Spec record.") ER3(SSL_ERROR_RX_MALFORMED_ALERT , (SSL_ERROR_BASE + 38), "SSL received a malformed Alert record.") ER3(SSL_ERROR_RX_MALFORMED_HANDSHAKE , (SSL_ERROR_BASE + 39), "SSL received a malformed Handshake record.") ER3(SSL_ERROR_RX_MALFORMED_APPLICATION_DATA , (SSL_ERROR_BASE + 40), "SSL received a malformed Application Data record.") /* * Received an SSL handshake that was inappropriate for the state we're in. * E.g. Server received message from server, or wrong state in state machine. */ ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_REQUEST , (SSL_ERROR_BASE + 41), "SSL received an unexpected Hello Request handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_HELLO , (SSL_ERROR_BASE + 42), "SSL received an unexpected Client Hello handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_HELLO , (SSL_ERROR_BASE + 43), "SSL received an unexpected Server Hello handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CERTIFICATE , (SSL_ERROR_BASE + 44), "SSL received an unexpected Certificate handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_SERVER_KEY_EXCH , (SSL_ERROR_BASE + 45), "SSL received an unexpected Server Key Exchange handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CERT_REQUEST , (SSL_ERROR_BASE + 46), "SSL received an unexpected Certificate Request handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_HELLO_DONE , (SSL_ERROR_BASE + 47), "SSL received an unexpected Server Hello Done handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CERT_VERIFY , (SSL_ERROR_BASE + 48), "SSL received an unexpected Certificate Verify handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_CLIENT_KEY_EXCH , (SSL_ERROR_BASE + 49), "SSL received an unexpected Client Key Exchange handshake message.") ER3(SSL_ERROR_RX_UNEXPECTED_FINISHED , (SSL_ERROR_BASE + 50), "SSL received an unexpected Finished handshake message.") /* * Received an SSL record that was inappropriate for the state we're in. */ ER3(SSL_ERROR_RX_UNEXPECTED_CHANGE_CIPHER , (SSL_ERROR_BASE + 51), "SSL received an unexpected Change Cipher Spec record.") ER3(SSL_ERROR_RX_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 52), "SSL received an unexpected Alert record.") ER3(SSL_ERROR_RX_UNEXPECTED_HANDSHAKE , (SSL_ERROR_BASE + 53), "SSL received an unexpected Handshake record.") ER3(SSL_ERROR_RX_UNEXPECTED_APPLICATION_DATA, (SSL_ERROR_BASE + 54), "SSL received an unexpected Application Data record.") /* * Received record/message with unknown discriminant. */ ER3(SSL_ERROR_RX_UNKNOWN_RECORD_TYPE , (SSL_ERROR_BASE + 55), "SSL received a record with an unknown content type.") ER3(SSL_ERROR_RX_UNKNOWN_HANDSHAKE , (SSL_ERROR_BASE + 56), "SSL received a handshake message with an unknown message type.") ER3(SSL_ERROR_RX_UNKNOWN_ALERT , (SSL_ERROR_BASE + 57), "SSL received an alert record with an unknown alert description.") /* * Received an alert reporting what we did wrong. (more alerts above) */ ER3(SSL_ERROR_CLOSE_NOTIFY_ALERT , (SSL_ERROR_BASE + 58), "SSL peer has closed this connection.") ER3(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT , (SSL_ERROR_BASE + 59), "SSL peer was not expecting a handshake message it received.") ER3(SSL_ERROR_DECOMPRESSION_FAILURE_ALERT , (SSL_ERROR_BASE + 60), "SSL peer was unable to successfully decompress an SSL record it received.") ER3(SSL_ERROR_HANDSHAKE_FAILURE_ALERT , (SSL_ERROR_BASE + 61), "SSL peer was unable to negotiate an acceptable set of security parameters.") ER3(SSL_ERROR_ILLEGAL_PARAMETER_ALERT , (SSL_ERROR_BASE + 62), "SSL peer rejected a handshake message for unacceptable content.") ER3(SSL_ERROR_UNSUPPORTED_CERT_ALERT , (SSL_ERROR_BASE + 63), "SSL peer does not support certificates of the type it received.") ER3(SSL_ERROR_CERTIFICATE_UNKNOWN_ALERT , (SSL_ERROR_BASE + 64), "SSL peer had some unspecified issue with the certificate it received.") ER3(SSL_ERROR_GENERATE_RANDOM_FAILURE , (SSL_ERROR_BASE + 65), "SSL experienced a failure of its random number generator.") ER3(SSL_ERROR_SIGN_HASHES_FAILURE , (SSL_ERROR_BASE + 66), "Unable to digitally sign data required to verify your certificate.") ER3(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE , (SSL_ERROR_BASE + 67), "SSL was unable to extract the public key from the peer's certificate.") ER3(SSL_ERROR_SERVER_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 68), "Unspecified failure while processing SSL Server Key Exchange handshake.") ER3(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE , (SSL_ERROR_BASE + 69), "Unspecified failure while processing SSL Client Key Exchange handshake.") ER3(SSL_ERROR_ENCRYPTION_FAILURE , (SSL_ERROR_BASE + 70), "Bulk data encryption algorithm failed in selected cipher suite.") ER3(SSL_ERROR_DECRYPTION_FAILURE , (SSL_ERROR_BASE + 71), "Bulk data decryption algorithm failed in selected cipher suite.") ER3(SSL_ERROR_SOCKET_WRITE_FAILURE , (SSL_ERROR_BASE + 72), "Attempt to write encrypted data to underlying socket failed.") ER3(SSL_ERROR_MD5_DIGEST_FAILURE , (SSL_ERROR_BASE + 73), "MD5 digest function failed.") ER3(SSL_ERROR_SHA_DIGEST_FAILURE , (SSL_ERROR_BASE + 74), "SHA-1 digest function failed.") ER3(SSL_ERROR_MAC_COMPUTATION_FAILURE , (SSL_ERROR_BASE + 75), "MAC computation failed.") ER3(SSL_ERROR_SYM_KEY_CONTEXT_FAILURE , (SSL_ERROR_BASE + 76), "Failure to create Symmetric Key context.") ER3(SSL_ERROR_SYM_KEY_UNWRAP_FAILURE , (SSL_ERROR_BASE + 77), "Failure to unwrap the Symmetric key in Client Key Exchange message.") ER3(SSL_ERROR_PUB_KEY_SIZE_LIMIT_EXCEEDED , (SSL_ERROR_BASE + 78), "SSL Server attempted to use domestic-grade public key with export cipher suite.") ER3(SSL_ERROR_IV_PARAM_FAILURE , (SSL_ERROR_BASE + 79), "PKCS11 code failed to translate an IV into a param.") ER3(SSL_ERROR_INIT_CIPHER_SUITE_FAILURE , (SSL_ERROR_BASE + 80), "Failed to initialize the selected cipher suite.") ER3(SSL_ERROR_SESSION_KEY_GEN_FAILURE , (SSL_ERROR_BASE + 81), "Client failed to generate session keys for SSL session.") ER3(SSL_ERROR_NO_SERVER_KEY_FOR_ALG , (SSL_ERROR_BASE + 82), "Server has no key for the attempted key exchange algorithm.") ER3(SSL_ERROR_TOKEN_INSERTION_REMOVAL , (SSL_ERROR_BASE + 83), "PKCS#11 token was inserted or removed while operation was in progress.") ER3(SSL_ERROR_TOKEN_SLOT_NOT_FOUND , (SSL_ERROR_BASE + 84), "No PKCS#11 token could be found to do a required operation.") ER3(SSL_ERROR_NO_COMPRESSION_OVERLAP , (SSL_ERROR_BASE + 85), "Cannot communicate securely with peer: no common compression algorithm(s).") ER3(SSL_ERROR_HANDSHAKE_NOT_COMPLETED , (SSL_ERROR_BASE + 86), "Cannot initiate another SSL handshake until current handshake is complete.") ER3(SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE , (SSL_ERROR_BASE + 87), "Received incorrect handshakes hash values from peer.") ER3(SSL_ERROR_CERT_KEA_MISMATCH , (SSL_ERROR_BASE + 88), "The certificate provided cannot be used with the selected key exchange algorithm.") ER3(SSL_ERROR_NO_TRUSTED_SSL_CLIENT_CA , (SSL_ERROR_BASE + 89), "No certificate authority is trusted for SSL client authentication.") ER3(SSL_ERROR_SESSION_NOT_FOUND , (SSL_ERROR_BASE + 90), "Client's SSL session ID not found in server's session cache.") ER3(SSL_ERROR_DECRYPTION_FAILED_ALERT , (SSL_ERROR_BASE + 91), "Peer was unable to decrypt an SSL record it received.") ER3(SSL_ERROR_RECORD_OVERFLOW_ALERT , (SSL_ERROR_BASE + 92), "Peer received an SSL record that was longer than is permitted.") ER3(SSL_ERROR_UNKNOWN_CA_ALERT , (SSL_ERROR_BASE + 93), "Peer does not recognize and trust the CA that issued your certificate.") ER3(SSL_ERROR_ACCESS_DENIED_ALERT , (SSL_ERROR_BASE + 94), "Peer received a valid certificate, but access was denied.") ER3(SSL_ERROR_DECODE_ERROR_ALERT , (SSL_ERROR_BASE + 95), "Peer could not decode an SSL handshake message.") ER3(SSL_ERROR_DECRYPT_ERROR_ALERT , (SSL_ERROR_BASE + 96), "Peer reports failure of signature verification or key exchange.") ER3(SSL_ERROR_EXPORT_RESTRICTION_ALERT , (SSL_ERROR_BASE + 97), "Peer reports negotiation not in compliance with export regulations.") ER3(SSL_ERROR_PROTOCOL_VERSION_ALERT , (SSL_ERROR_BASE + 98), "Peer reports incompatible or unsupported protocol version.") ER3(SSL_ERROR_INSUFFICIENT_SECURITY_ALERT , (SSL_ERROR_BASE + 99), "Server requires ciphers more secure than those supported by client.") ER3(SSL_ERROR_INTERNAL_ERROR_ALERT , (SSL_ERROR_BASE + 100), "Peer reports it experienced an internal error.") ER3(SSL_ERROR_USER_CANCELED_ALERT , (SSL_ERROR_BASE + 101), "Peer user canceled handshake.") ER3(SSL_ERROR_NO_RENEGOTIATION_ALERT , (SSL_ERROR_BASE + 102), "Peer does not permit renegotiation of SSL security parameters.") ER3(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED , (SSL_ERROR_BASE + 103), "SSL server cache not configured and not disabled for this socket.") ER3(SSL_ERROR_UNSUPPORTED_EXTENSION_ALERT , (SSL_ERROR_BASE + 104), "SSL peer does not support requested TLS hello extension.") ER3(SSL_ERROR_CERTIFICATE_UNOBTAINABLE_ALERT , (SSL_ERROR_BASE + 105), "SSL peer could not obtain your certificate from the supplied URL.") ER3(SSL_ERROR_UNRECOGNIZED_NAME_ALERT , (SSL_ERROR_BASE + 106), "SSL peer has no certificate for the requested DNS name.") ER3(SSL_ERROR_BAD_CERT_STATUS_RESPONSE_ALERT , (SSL_ERROR_BASE + 107), "SSL peer was unable to get an OCSP response for its certificate.") ER3(SSL_ERROR_BAD_CERT_HASH_VALUE_ALERT , (SSL_ERROR_BASE + 108), "SSL peer reported bad certificate hash value.") ER3(SSL_ERROR_RX_UNEXPECTED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 109), "SSL received an unexpected New Session Ticket handshake message.") ER3(SSL_ERROR_RX_MALFORMED_NEW_SESSION_TICKET, (SSL_ERROR_BASE + 110), "SSL received a malformed New Session Ticket handshake message.") ER3(SSL_ERROR_DECOMPRESSION_FAILURE, (SSL_ERROR_BASE + 111), "SSL received a compressed record that could not be decompressed.") ER3(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, (SSL_ERROR_BASE + 112), "Renegotiation is not allowed on this SSL socket.") jss-4.4.3/jss/org/mozilla/jss/util/Tunnel.java000066400000000000000000000006751326145000000212410ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; /** * A class to allow friendly functions access to other parts of JSS. */ public class Tunnel { protected static byte[] GetPasswordByteCopy(Password pw) { return pw.getByteCopy(); } } jss-4.4.3/jss/org/mozilla/jss/util/UTF8Converter.java000066400000000000000000000266621326145000000224160ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.jss.util; import java.io.*; /** * Class for converting between char arrays and byte arrays. The conversion * is guaranteed (in optimized mode only) not to leave any data hanging around * in memory unless there is a catastrophic VM error, which is useful for * encoding passwords. */ public class UTF8Converter { /** * Creates a new UTF8-encoded byte array representing the * char[] passed in. The output array will NOT be null-terminated. * *

This call is safe for passwords; all internal buffers are cleared. * The output array is the owned by the caller, who has responsibility * for clearing it. * *

See http://www.stonehard.com/unicode/standard/ for the UTF-16 * and UTF-8 standards. * * @param unicode An array of Unicode characters, which may have UCS4 * characters encoded in UTF-16. This array must not be null. * @exception CharConversionException If the input characters are invalid. */ public static byte[] UnicodeToUTF8(char[] unicode) throws CharConversionException { return UnicodeToUTF8(unicode, false); } /** * Creates a new null-terminated UTF8-encoded byte array representing the * char[] passed in. * *

This call is safe for passwords; all internal buffers are cleared. * The output array is the owned by the caller, who has responsibility * for clearing it. * *

See http://www.stonehard.com/unicode/standard/ for the UTF-16 * and UTF-8 standards. * * @param unicode An array of Unicode characters, which may have UCS4 * characters encoded in UTF-16. This array must not be null. * @exception CharConversionException If the input characters are invalid. */ public static byte[] UnicodeToUTF8NullTerm(char [] unicode) throws CharConversionException { return UnicodeToUTF8(unicode, true); } /** * Do the work of the above functions. */ protected static byte[] UnicodeToUTF8(char[] unicode, boolean nullTerminate) throws CharConversionException { int uni; // unicode index int utf; // UTF8 index int maxsize; // maximum size of UTF8 output byte[] utf8 = null; // UTF8 output buffer byte[] temp = null; // used to create an array of the correct size char c; // Unicode character int ucs4; // UCS4 encoding of a character boolean failed = true; boolean orphaned_low = false; Assert._assert(unicode != null); if(unicode == null) { return null; } try { // Allocate worst-case size (UTF8 bytes == 1.5 times Unicode bytes) maxsize = unicode.length * 3; //chars are 2 bytes each if(nullTerminate) { maxsize++; } utf8 = new byte[maxsize]; for(uni=0, utf=0; uni < unicode.length; uni++) { // // Convert UCS2 to UCS4 // c = unicode[uni]; if( c >= 0xd800 && c <= 0xdbff) { // This is the high half of a UTF-16 char ucs4 = (c-0xd800)<<10; // Now get the lower half if(uni == unicode.length-1) { //There is no lower half throw new CharConversionException(); } c = unicode[++uni]; if(c < 0xdc00 || c > 0xdfff) { // not in the low-half zone throw new CharConversionException(); } ucs4 |= c-0xdc00; ucs4 += 0x00010000; } else if(c >=0xdc00 && c <=0xdfff) { // orphaned low-half char orphaned_low = true; throw new CharConversionException(); } else { // UCS2 char to UCS4 ucs4 = unicode[uni]; } // // UCS4 to UTF8 conversion // if(ucs4 < 0x80) { // 0000 0000 - 0000 007f (ASCII) utf8[utf++] = (byte)ucs4; } else if(ucs4 < 0x800) { // 0000 0080 - 0000 07ff utf8[utf++] = (byte) (0xc0 | ucs4>>6); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else if(ucs4 < 0x0010000) { // 0000 0800 - 0000 ffff utf8[utf++] = (byte) (0xe0 | ucs4>>12); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else if(ucs4 < 0x00200000) { // 001 0000 - 001f ffff utf8[utf++] = (byte) (0xf0 | ucs4>>18); utf8[utf++] = (byte) (0x80 | ((ucs4>>12) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else if(ucs4 < 0x00200000) { // 0020 0000 - 03ff ffff utf8[utf++] = (byte) (0xf8 | ucs4>>24); utf8[utf++] = (byte) (0x80 | ((ucs4>>18) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>12) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } else { // 0400 0000 - 7fff ffff utf8[utf++] = (byte) (0xfc | ucs4>>30); utf8[utf++] = (byte) (0x80 | ((ucs4>>24) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>18) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>12) & 0x3f) ); utf8[utf++] = (byte) (0x80 | ((ucs4>>6) & 0x3f) ); utf8[utf++] = (byte) (0x80 | (ucs4 & 0x3f) ); } } if(nullTerminate) { utf8[utf++] = 0; } // // Copy into a correct-sized array // try { int i; // last index is the size of the UTF8 temp = new byte[utf]; for(i=0; i < utf; i++) { temp[i] = utf8[i]; utf8[i] = 0; } utf8 = temp; temp = null; } finally { if(temp != null) { wipeBytes(temp); } } failed = false; return utf8; } finally { // Cleanup data locations where the password was written if(failed && utf8 != null) { wipeBytes(utf8); utf8 = null; } ucs4 = 0; c = 0; if(Debug.DEBUG) { // Verify this operation by comparing its output // to that of the standard Java conversion routines. // WARNING: This means passwords will be left in memory, // so Ninja is not secure in debugging mode! try { OutputStreamWriter writer; ByteArrayOutputStream barray; int i; byte[] output; barray = new ByteArrayOutputStream(); writer = new OutputStreamWriter(barray, "UTF8"); writer.write(unicode, 0, unicode.length); writer.close(); output = barray.toByteArray(); // My class rejects orphaned low-half characters, but the Java // class allows them. I think they really are bogus, so // let's pretend the Java class rejects them too. if(orphaned_low) { throw new IOException(); } // It worked with the Java class, so it should have worked // with my class Assert._assert(utf8 != null); // Compare the arrays if(nullTerminate) { Assert._assert(utf8.length-1 == output.length); } else { Assert._assert(utf8.length == output.length); } for(i=0; i "+utf8.length+ " bytes of utf8\n"); // // empty array // System.out.println("Empty input test:"); unicode = new char[0]; utf8 = UnicodeToUTF8(unicode); Assert._assert(utf8 != null); Assert._assert(utf8.length == 0); System.out.println("given 0 bytes Unicode, produces 0 length utf8\n"); // // UCS4 // System.out.println("UCS4 Test:"); unicode = new char[] {'\ud800', '\udc00', '\uda85', '\ude47', '\udbff', '\udfff'}; utf8 = UnicodeToUTF8(unicode); for(i=0; i < 6; i++) { System.out.print( Integer.toHexString(unicode[i]) + " "); } System.out.println(); for(i=0; i < utf8.length; i++) { System.out.print( Integer.toHexString(utf8[i]) + " "); } System.out.println("\n"); // // high half with no low half // System.out.println("high half at end of input:"); try { unicode = new char[] {'\ud800'}; utf8 = UnicodeToUTF8(unicode); Assert.notReached("should have failed on bad UCS4"); } catch (CharConversionException e) { System.out.println("Correctly caught bad UCS4\n"); } // // high half with something else // System.out.println("high half with something other than low half:"); try { unicode = new char[] {'\ud800', '\u007f'}; utf8 = UnicodeToUTF8(unicode); Assert.notReached("should have failed on bad UCS4"); } catch (CharConversionException e) { System.out.println("Correctly caught bad UCS4\n"); } // // orphaned low half // System.out.println("orphaned low half test:"); try { unicode = new char[] {'\u0032', '\udc01', '\u0033'}; utf8 = UnicodeToUTF8(unicode); Assert.notReached("should have failed on bad UCS4"); } catch (CharConversionException e) { System.out.println("Correctly caught bad UCS4\n"); } // // null-terminated // System.out.println("null-terminating:"); unicode = new char[] {'f', 'o', 'o', 'b', 'a', 'r'}; utf8 = UnicodeToUTF8NullTerm(unicode); for(i=0; i < unicode.length; i++) { System.out.print(unicode[i] + " "); } System.out.println(); for(i=0; i < utf8.length; i++) { System.out.print(utf8[i] + " "); } System.out.println("\n"); } catch(CharConversionException e) { System.out.println("Error converting Unicode "+e); } finally { if(!Debug.DEBUG) { System.out.println("***WARNING***"); System.out.println("Debugging mode is disabled. This code only"+ " checks itself in debug mode. The test is almost worthless"+ " in optimized mode." ); } } } } jss-4.4.3/jss/org/mozilla/jss/util/config.mk000066400000000000000000000004201326145000000207130ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. TARGETS=$(LIBRARY) SHARED_LIBRARY= IMPORT_LIBRARY= NO_MD_RELEASE = 1 jss-4.4.3/jss/org/mozilla/jss/util/errstrings.c000066400000000000000000000040061326145000000214670ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nspr.h" struct tuple_str { PRErrorCode errNum; const char * errString; }; typedef struct tuple_str tuple_str; #define ER2(a,b) {a, b}, #define ER3(a,b,c) {a, c}, #include "secerr.h" #include "sslerr.h" static const tuple_str errStrings[] = { /* keep this list in ascending order of error numbers */ #include "SSLerrs.h" #include "SECerrs.h" #include "NSPRerrs.h" }; static const PRInt32 numStrings = sizeof(errStrings) / sizeof(tuple_str); /* Returns a UTF-8 encoded constant error string for "errNum". * Returns NULL of errNum is unknown. */ const char * JSS_strerror(PRErrorCode errNum) { PRInt32 low = 0; PRInt32 high = numStrings - 1; PRInt32 i; PRErrorCode num; static int initDone; /* make sure table is in ascending order. * binary search depends on it. */ if (!initDone) { PRErrorCode lastNum = 0x80000000; for (i = low; i <= high; ++i) { num = errStrings[i].errNum; if (num <= lastNum) { fprintf(stderr, "sequence error in error strings at item %d\n" "error %d (%s)\n" "should come after \n" "error %d (%s)\n", i, lastNum, errStrings[i-1].errString, num, errStrings[i].errString); } lastNum = num; } initDone = 1; } /* Do binary search of table. */ while (low + 1 < high) { i = (low + high) / 2; num = errStrings[i].errNum; if (errNum == num) return errStrings[i].errString; if (errNum < num) high = i; else low = i; } if (errNum == errStrings[low].errNum) return errStrings[low].errString; if (errNum == errStrings[high].errNum) return errStrings[high].errString; return NULL; } jss-4.4.3/jss/org/mozilla/jss/util/java_ids.h000066400000000000000000000236731326145000000210650ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef JAVA_IDS_H #define JAVA_IDS_H PR_BEGIN_EXTERN_C /* ** JNI uses strings to identify Java classes, fields, and methods. Rather ** than put lots of string constants in our JNI code, we define them once ** here. This has two benefits: it reduces the probability of typos ** (we only have to type the names once), and it allows us to more ** easily change these identifiers. */ #define PLAIN_CONSTRUCTOR "" #define PLAIN_CONSTRUCTOR_SIG "()V" /* * Algorithm */ #define ALGORITHM_CLASS_NAME "org/mozilla/jss/crypto/Algorithm" #define OID_INDEX_FIELD_NAME "oidIndex" #define OID_INDEX_FIELD_SIG "I" /* * BigInteger */ #define BIG_INTEGER_CLASS_NAME "java/math/BigInteger" #define BIG_INTEGER_CONSTRUCTOR_NAME "" #define BIG_INTEGER_CONSTRUCTOR_SIG "([B)V" /* * CipherContextProxy */ #define CIPHER_CONTEXT_PROXY_CLASS_NAME "org/mozilla/jss/pkcs11/CipherContextProxy" #define CIPHER_CONTEXT_PROXY_CONSTRUCTOR_SIG "([B)V" /* * Debug */ #define DEBUG_CLASS_NAME "org/mozilla/jss/util/Debug" #define DEBUG_TRACE_NAME "trace" #define DEBUG_TRACE_SIG "(ILjava/lang/String;)V" /* * InetAddress */ #define GET_ADDR_NAME "getAddress" #define GET_ADDR_SIG "()[B" /* * InputStream */ #define ISTREAM_READ_NAME "read" #define ISTREAM_READ_SIG "([B)I" /* * KeyPair */ #define KEY_PAIR_CLASS_NAME "java/security/KeyPair" #define KEY_PAIR_CONSTRUCTOR_NAME "" #define KEY_PAIR_CONSTRUCTOR_SIG "(Ljava/security/PublicKey;Ljava/security/PrivateKey;)V" /* * KeyProxy */ #define KEY_PROXY_FIELD "keyProxy" #define KEY_PROXY_SIG "Lorg/mozilla/jss/pkcs11/KeyProxy;" /* * KeyType */ #define KEYTYPE_CLASS_NAME "org/mozilla/jss/pkcs11/KeyType" #define NULL_KEYTYPE_FIELD "NULL" #define RSA_KEYTYPE_FIELD "RSA" #define DSA_KEYTYPE_FIELD "DSA" #define EC_KEYTYPE_FIELD "EC" #define FORTEZZA_KEYTYPE_FIELD "FORTEZZA" #define DH_KEYTYPE_FIELD "DH" #define KEA_KEYTYPE_FIELD "KEA" #define KEYTYPE_FIELD_SIG "Lorg/mozilla/jss/pkcs11/KeyType;" #define DES_KEYTYPE_FIELD "DES" #define DES3_KEYTYPE_FIELD "DES3" #define RC4_KEYTYPE_FIELD "RC4" #define RC2_KEYTYPE_FIELD "RC2" #define SHA1_HMAC_KEYTYPE_FIELD "SHA1_HMAC" #define AES_KEYTYPE_FIELD "AES" #define GENERIC_SECRET_KEYTYPE_FIELD "GENERIC_SECRET" /* * NativeProxy */ #define NATIVE_PROXY_CLASS_NAME "org/mozilla/jss/util/NativeProxy" #define NATIVE_PROXY_POINTER_FIELD "mPointer" #define NATIVE_PROXY_POINTER_SIG "[B" /* * NSSInit */ #define NSSINIT_CLASS_NAME "org/mozilla/jss/NSSInit" #define NSSINIT_ISINITIALIZED_NAME "isInitialized" #define NSSINIT_ISINITIALIZED_SIG "()Z" /* * OutputStream */ #define OSTREAM_WRITE_NAME "write" #define OSTREAM_WRITE_SIG "([BII)V" /* * Password */ #define PASSWORD_CLASS_NAME "org/mozilla/jss/util/Password" #define PASSWORD_CONSTRUCTOR_SIG "([C)V" #define PW_GET_BYTE_COPY_NAME "getByteCopy" #define PW_GET_BYTE_COPY_SIG "()[B" #define PW_CLEAR_NAME "clear" #define PW_CLEAR_SIG "()V" /* * PasswordCallback */ #define PW_CALLBACK_GET_PW_FIRST_NAME "getPasswordFirstAttempt" #define PW_CALLBACK_GET_PW_FIRST_SIG "(Lorg/mozilla/jss/util/PasswordCallbackInfo;)Lorg/mozilla/jss/util/Password;" #define PW_CALLBACK_GET_PW_AGAIN_NAME "getPasswordAgain" #define PW_CALLBACK_GET_PW_AGAIN_SIG "(Lorg/mozilla/jss/util/PasswordCallbackInfo;)Lorg/mozilla/jss/util/Password;" /* * PK11Cert */ #define CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Cert" #define CERT_CONSTRUCTOR_NAME "" #define CERT_CONSTRUCTOR_SIG "([B[BLjava/lang/String;)V" #define CERT_PROXY_FIELD "certProxy" #define CERT_PROXY_SIG "Lorg/mozilla/jss/pkcs11/CertProxy;" /* * PK11InternalCert */ #define INTERNAL_CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11InternalCert" /* * PK11TokenCert */ #define TOKEN_CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11TokenCert" /* * PK11InternalTokenCert */ #define INTERNAL_TOKEN_CERT_CLASS_NAME "org/mozilla/jss/pkcs11/PK11InternalTokenCert" /* * PK11DSAPublicKey */ #define PK11_DSA_PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11DSAPublicKey" /* * PK11ECPublicKey */ #define PK11_EC_PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11ECPublicKey" /* * PK11Module */ #define PK11MODULE_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Module" #define PK11MODULE_CONSTRUCTOR_SIG "([B)V" #define PK11MODULE_PROXY_FIELD "moduleProxy" #define PK11MODULE_PROXY_SIG "Lorg/mozilla/jss/pkcs11/ModuleProxy;" /* * PK11PrivKey */ #define PK11PRIVKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11PrivKey" #define PK11PRIVKEY_CONSTRUCTOR_NAME "" #define PK11PRIVKEY_CONSTRUCTOR_SIG "([B)V" /* * PK11PubKey */ #define PK11PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11PubKey" #define PK11PUBKEY_CONSTRUCTOR_NAME "" #define PK11PUBKEY_CONSTRUCTOR_SIG "([B)V" /* * PK11RSAPublicKey */ #define PK11_RSA_PUBKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11RSAPublicKey" /* * PK11Signature */ #define PK11SIGNATURE_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Signature" #define SIG_CONTEXT_PROXY_FIELD "sigContext" #define SIG_CONTEXT_PROXY_SIG "Lorg/mozilla/jss/pkcs11/SigContextProxy;" #define SIG_ALGORITHM_FIELD "algorithm" #define SIG_ALGORITHM_SIG "Lorg/mozilla/jss/crypto/Algorithm;" #define SIG_PW_FIELD "pwExtractor" #define SIG_PW_SIG "Lorg/mozilla/jss/crypto/PasswordExtractor;" #define SIG_KEY_FIELD "key" #define SIG_KEY_SIG "Lorg/mozilla/jss/pkcs11/PK11Key;" /* * PK11Store */ #define PK11STORE_PROXY_FIELD "storeProxy" #define PK11STORE_PROXY_SIG "Lorg/mozilla/jss/pkcs11/TokenProxy;" /* * PK11SymKey */ #define PK11SYMKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11SymKey" #define PK11SYMKEY_CONSTRUCTOR_SIG "([B)V" #define PK11SYMKEY_CONSTRUCTOR_1_SIG "([BLjava/lang/String;)V" /* * PK11Token */ #define PK11TOKEN_PROXY_FIELD "tokenProxy" #define PK11TOKEN_PROXY_SIG "Lorg/mozilla/jss/pkcs11/TokenProxy;" #define PK11TOKEN_CLASS_NAME "org/mozilla/jss/pkcs11/PK11Token" #define PK11TOKEN_CONSTRUCTOR_NAME "" #define PK11TOKEN_CONSTRUCTOR_SIG "([BZZ)V" /* * PrivateKey.KeyType */ #define PRIVKEYTYPE_CLASS_NAME "org/mozilla/jss/crypto/PrivateKey$Type" #define PRIVKEYTYPE_SIG "Lorg/mozilla/jss/crypto/PrivateKey$Type;" #define RSA_PRIVKEYTYPE_FIELD "RSA" #define DSA_PRIVKEYTYPE_FIELD "DSA" #define EC_PRIVKEYTYPE_FIELD "EC" /* * PQGParams */ #define PQG_PARAMS_CONSTRUCTOR_NAME "" #define PQG_PARAMS_CONSTRUCTOR_SIG "(Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;Ljava/math/BigInteger;ILjava/math/BigInteger;)V" /* * SigContextProxy */ #define SIG_CONTEXT_PROXY_CLASS_NAME "org/mozilla/jss/pkcs11/SigContextProxy" #define SIG_CONTEXT_PROXY_CONSTRUCTOR_NAME "" #define SIG_CONTEXT_PROXY_CONSTRUCTOR_SIG "([B)V" /* * Socket */ #define SOCKET_GET_OUTPUT_STREAM_NAME "getOutputStream" #define SOCKET_GET_OUTPUT_STREAM_SIG "()Ljava/io/OutputStream;" #define SOCKET_GET_INPUT_STREAM_NAME "getInputStream" #define SOCKET_GET_INPUT_STREAM_SIG "()Ljava/io/InputStream;" #define GET_INET_ADDR_NAME "getInetAddress" #define GET_INET_ADDR_SIG "()Ljava/net/InetAddress;" #define GET_PORT_NAME "getPort" #define GET_PORT_SIG "()I" #define GET_LOCAL_ADDR_NAME "getLocalAddress" #define GET_LOCAL_PORT_NAME "getLocalPort" #define SOCKET_CLOSE_NAME "close" #define SOCKET_CLOSE_SIG "()V" #define SET_SO_TIMEOUT_NAME "setSoTimeout" #define SET_SO_TIMEOUT_SIG "(I)V" #define GET_KEEPALIVE_NAME "getKeepAlive" #define GET_KEEPALIVE_SIG "()Z" #define GET_SEND_BUF_SIZE "getSendBufferSize" #define GET_RECV_BUF_SIZE "getReceiveBufferSize" #define GET_BUF_SIZE_SIG "()I" /* * SocketBase */ #define SOCKET_BASE_NAME "org/mozilla/jss/ssl/SocketBase" #define PROCESS_EXCEPTIONS_NAME "processExceptions" #define PROCESS_EXCEPTIONS_SIG "(Ljava/lang/Throwable;Ljava/lang/Throwable;)Ljava/lang/Throwable;" #define SUPPORTS_IPV6_NAME "supportsIPV6" #define SUPPORTS_IPV6_SIG "()Z" /* * SSLAlertEvent */ #define SSL_ALERT_EVENT_CLASS "org/mozilla/jss/ssl/SSLAlertEvent" /* * SSLCertificateApprovalCallback */ #define SSLCERT_APP_CB_APPROVE_NAME "approve" #define SSLCERT_APP_CB_APPROVE_SIG "(Lorg/mozilla/jss/crypto/X509Certificate;Lorg/mozilla/jss/ssl/SSLCertificateApprovalCallback$ValidityStatus;)Z" /* * SSLSecurityStatus */ #define SSL_SECURITY_STATUS_CLASS_NAME "org/mozilla/jss/ssl/SSLSecurityStatus" #define SSL_SECURITY_STATUS_CONSTRUCTOR_NAME "" #define SSL_SECURITY_STATUS_CONSTRUCTOR_SIG "(ILjava/lang/String;IILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/mozilla/jss/crypto/X509Certificate;)V" /* * SSLSocket */ #define SSLSOCKET_CLASS "org/mozilla/jss/ssl/SSLSocket" #define SSLSOCKET_HANDSHAKE_NOTIFIER_NAME "notifyAllHandshakeListeners" #define SSLSOCKET_HANDSHAKE_NOTIFIER_SIG "()V" #define SSLSOCKET_PROXY_FIELD "sockProxy" #define SSLSOCKET_PROXY_SIG "Lorg/mozilla/jss/ssl/SocketProxy;" /* * StringBuffer */ #define STRING_BUFFER_NAME "java/lang/StringBuffer" #define STRING_BUFFER_APPEND_NAME "append" #define STRING_BUFFER_APPEND_SIG "(Ljava/lang/String;)Ljava/lang/StringBuffer;" /* * ValidityStatus */ #define SSLCERT_APP_CB_VALIDITY_STATUS_CLASS \ "org/mozilla/jss/ssl/SSLCertificateApprovalCallback$ValidityStatus" #define SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_NAME "addReason" #define SSLCERT_APP_CB_VALIDITY_STATUS_ADD_REASON_SIG \ "(ILorg/mozilla/jss/pkcs11/PK11Cert;I)V" /* * SymKeyProxy */ #define SYM_KEY_PROXY_FIELD "keyProxy" #define SYM_KEY_PROXY_SIG "Lorg/mozilla/jss/pkcs11/SymKeyProxy;" /* * Throwable */ #define THROWABLE_NAME "java/lang/Throwable" #define THROWABLE_TO_STRING_NAME "toString" #define THROWABLE_TO_STRING_SIG "()Ljava/lang/String;" /* * TokenCallbackInfo */ #define TOKEN_CBINFO_CLASS_NAME "org/mozilla/jss/pkcs11/TokenCallbackInfo" #define TOKEN_CBINFO_CONSTRUCTOR_NAME "" #define TOKEN_CBINFO_CONSTRUCTOR_SIG "(Ljava/lang/String;)V" /* * Vector */ #define VECTOR_ADD_ELEMENT_NAME "addElement" #define VECTOR_ADD_ELEMENT_SIG "(Ljava/lang/Object;)V" /* * X509Certificate */ #define X509_CERT_CLASS "org/mozilla/jss/crypto/X509Certificate" PR_END_EXTERN_C #endif jss-4.4.3/jss/org/mozilla/jss/util/jss_bigint.h000066400000000000000000000030751326145000000214320ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* Need to include these first: #include #include */ #ifndef JSS_BIG_INT_H #define JSS_BIG_INT_H PR_BEGIN_EXTERN_C /*********************************************************************** * * J S S _ O c t e t S t r i n g T o B y t e A r r a y * * Converts a representation of an integer as a big-endian octet string * stored in a SECItem (as used by the low-level crypto functions) to a * representation of an integer as a big-endian Java byte array. Prepends * a zero byte to force it to be positive. */ jbyteArray JSS_OctetStringToByteArray(JNIEnv *env, SECItem *item); /*********************************************************************** * * J S S _ B y t e A r r a y T o O c t e t S t r i n g * * Converts an integer represented as a big-endian Java byte array to * an integer represented as a big-endian octet string in a SECItem. * * INPUTS * byteArray * A Java byte array containing an integer represented in * big-endian format. Must not be NULL. * item * Pointer to a SECItem that will be filled with the integer * from the byte array, in big-endian format. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an exception * was thrown. */ PRStatus JSS_ByteArrayToOctetString(JNIEnv *env, jbyteArray byteArray, SECItem *item); PR_END_EXTERN_C #endif jss-4.4.3/jss/org/mozilla/jss/util/jss_exceptions.h000066400000000000000000000071371326145000000223420ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* These are class names suitable for passing to JSS_nativeThrow or ** JSS_nativeThrowMsg. They are the fully qualified class name of the ** exception, separated by slashes instead of periods. */ #ifndef JSS_EXCEPTIONS_H #define JSS_EXCEPTIONS_H PR_BEGIN_EXTERN_C #define ALREADY_INITIALIZED_EXCEPTION "org/mozilla/jss/crypto/AlreadyInitializedException" #define ARRAY_INDEX_OUT_OF_BOUNDS_EXCEPTION "java/lang/ArrayIndexOutOfBoundsException" #define INDEX_OUT_OF_BOUNDS_EXCEPTION "java/lang/IndexOutOfBoundsException" #define BAD_PADDING_EXCEPTION "org/mozilla/jss/crypto/BadPaddingException" #define BIND_EXCEPTION "java/net/BindException" #define CERT_DATABASE_EXCEPTION "org/mozilla/jss/CertDatabaseException" #define CERTIFICATE_EXCEPTION "java/security/cert/CertificateException" #define CERTIFICATE_ENCODING_EXCEPTION "java/security/cert/CertificateEncodingException" #define CRL_IMPORT_EXCEPTION "org/mozilla/jss/CRLImportException" #define DIGEST_EXCEPTION "java/security/DigestException" #define GENERAL_SECURITY_EXCEPTION "java/security/GeneralSecurityException" #define GENERIC_EXCEPTION "java/lang/Exception" #define GIVE_UP_EXCEPTION "org/mozilla/jss/util/PasswordCallback$GiveUpException" #define ILLEGAL_ARGUMENT_EXCEPTION "java/lang/IllegalArgumentException" #define ILLEGAL_BLOCK_SIZE_EXCEPTION "org/mozilla/jss/crypto/IllegalBlockSizeException" #define INCORRECT_PASSWORD_EXCEPTION "org/mozilla/jss/util/IncorrectPasswordException" #define INTERRUPTED_IO_EXCEPTION "java/io/InterruptedIOException" #define INVALID_DER_EXCEPTION "org/mozilla/jss/crypto/InvalidDERException" #define INVALID_NICKNAME_EXCEPTION "org/mozilla/jss/util/InvalidNicknameException" #define INVALID_KEY_FORMAT_EXCEPTION "org/mozilla/jss/crypto/InvalidKeyFormatException" #define INVALID_PARAMETER_EXCEPTION "java/security/InvalidParameterException" #define IO_EXCEPTION "java/io/IOException" #define KEY_DATABASE_EXCEPTION "org/mozilla/jss/KeyDatabaseException" #define KEY_EXISTS_EXCEPTION "org/mozilla/jss/crypto/KeyAlreadyImportedException" #define KEYSTORE_EXCEPTION "java/security/KeyStoreException" #define NICKNAME_CONFLICT_EXCEPTION "org/mozilla/jss/CryptoManager$NicknameConflictException" #define NO_SUCH_ALG_EXCEPTION "java/security/NoSuchAlgorithmException" #define NO_SUCH_ITEM_ON_TOKEN_EXCEPTION "org/mozilla/jss/crypto/NoSuchItemOnTokenException" #define NO_SUCH_TOKEN_EXCEPTION "org/mozilla/jss/NoSuchTokenException" #define NOT_EXTRACTABLE_EXCEPTION "org/mozilla/jss/crypto/SymmetricKey$NotExtractableException" #define NULL_POINTER_EXCEPTION "java/lang/NullPointerException" #define OBJECT_NOT_FOUND_EXCEPTION "org/mozilla/jss/crypto/ObjectNotFoundException" #define OUT_OF_MEMORY_ERROR "java/lang/OutOfMemoryError" #define PQG_PARAM_GEN_EXCEPTION "org/mozilla/jss/crypto/PQGParamGenException" /* This is a RuntimeException */ #define SECURITY_EXCEPTION "java/lang/SecurityException" #define SIGNATURE_EXCEPTION "java/security/SignatureException" #define SOCKET_EXCEPTION "java/net/SocketException" #define SSLSOCKET_EXCEPTION "org/mozilla/jss/ssl/SSLSocketException" #define SOCKET_TIMEOUT_EXCEPTION "java/net/SocketTimeoutException" #define TOKEN_EXCEPTION "org/mozilla/jss/crypto/TokenException" #define TOKEN_NOT_INITIALIZED_EXCEPTION "org/mozilla/jss/pkcs11/PK11Token$NotInitializedException" #define USER_CERT_CONFLICT_EXCEPTION "org/mozilla/jss/CryptoManager$UserCertConflictException" PR_END_EXTERN_C #endif jss-4.4.3/jss/org/mozilla/jss/util/jssutil.c000066400000000000000000000406621326145000000207720ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include #include #include #include #include #include "jssutil.h" #include "jss_bigint.h" #include "jss_exceptions.h" #include "java_ids.h" #include "_jni/org_mozilla_jss_util_Password.h" /*********************************************************************** ** ** J S S _ t h r o w M s g P r E r r A r g ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** message is the message parameter of the throwable. It must not be NULL. ** If you don't have a message, call JSS_throw. ** ** errCode is a PRErrorCode returned from PR_GetError(). ** ** Example: ** JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, PR_GetError()); ** return -1; */ void JSS_throwMsgPrErrArg(JNIEnv *env, char *throwableClassName, char *message, PRErrorCode errCode) { const char *errStr = JSS_strerror(errCode); char *msg = NULL; int msgLen; if( errStr == NULL ) { errStr = "Unknown error"; } msgLen = strlen(message) + strlen(errStr) + 40; msg = PR_Malloc(msgLen); if( msg == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } PR_snprintf(msg, msgLen, "%s: (%ld) %s", message, errCode, errStr); JSS_throwMsg(env, throwableClassName, msg); finish: if(msg != NULL) { PR_Free(msg); } } /*********************************************************************** ** ** J S S _ t h r o w M s g ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** message is the message parameter of the throwable. It must not be NULL. ** If you don't have a message, call JSS_throw. ** ** Example: ** JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, ** "Bogus argument, you ninny"); ** return -1; */ void JSS_throwMsg(JNIEnv *env, char *throwableClassName, char *message) { jclass throwableClass; jint VARIABLE_MAY_NOT_BE_USED result; /* validate arguments */ PR_ASSERT(env!=NULL && throwableClassName!=NULL && message!=NULL); throwableClass = NULL; if(throwableClassName) { throwableClass = (*env)->FindClass(env, throwableClassName); /* make sure the class was found */ PR_ASSERT(throwableClass != NULL); } if(throwableClass == NULL) { throwableClass = (*env)->FindClass(env, GENERIC_EXCEPTION); } PR_ASSERT(throwableClass != NULL); result = (*env)->ThrowNew(env, throwableClass, message); PR_ASSERT(result == 0); } /*********************************************************************** ** ** J S S _ t h r o w ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** Example: ** JSS_throw(env, ILLEGAL_ARGUMENT_EXCEPTION); ** return -1; */ void JSS_throw(JNIEnv *env, char *throwableClassName) { jclass throwableClass; jobject throwable; jmethodID constructor; jint VARIABLE_MAY_NOT_BE_USED result; PR_ASSERT( (*env)->ExceptionOccurred(env) == NULL ); /* Lookup the class */ throwableClass = NULL; if(throwableClassName) { throwableClass = (*env)->FindClass(env, throwableClassName); /* make sure the class was found */ PR_ASSERT(throwableClass != NULL); } if(throwableClass == NULL) { throwableClass = (*env)->FindClass(env, GENERIC_EXCEPTION); } PR_ASSERT(throwableClass != NULL); /* Lookup up the plain vanilla constructor */ constructor = (*env)->GetMethodID( env, throwableClass, PLAIN_CONSTRUCTOR, PLAIN_CONSTRUCTOR_SIG); if(constructor == NULL) { /* Anything other than OutOfMemory is a bug */ ASSERT_OUTOFMEM(env); return; } /* Create an instance of the throwable */ throwable = (*env)->NewObject(env, throwableClass, constructor); if(throwable == NULL) { /* Anything other than OutOfMemory is a bug */ ASSERT_OUTOFMEM(env); return; } /* Throw the new instance */ result = (*env)->Throw(env, throwable); PR_ASSERT(result == 0); } /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y ** ** Given a NativeProxy, extract the pointer and store it at the given ** address. ** ** nativeProxy: a JNI reference to a NativeProxy. ** ptr: address of a void* that will receive the pointer extracted from ** the NativeProxy. ** Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown. ** ** Example: ** DataStructure *recovered; ** jobject proxy; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxy(env, proxy, (void**)&recovered) != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr) { #ifdef DEBUG jclass nativeProxyClass; #endif jclass proxyClass; jfieldID byteArrayField; jbyteArray byteArray; int size; PR_ASSERT(env!=NULL && nativeProxy != NULL && ptr != NULL); if( nativeProxy == NULL ) { JSS_throw(env, NULL_POINTER_EXCEPTION); return PR_FAILURE; } proxyClass = (*env)->GetObjectClass(env, nativeProxy); PR_ASSERT(proxyClass != NULL); #ifdef DEBUG nativeProxyClass = (*env)->FindClass( env, NATIVE_PROXY_CLASS_NAME); if(nativeProxyClass == NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } /* make sure what we got was really a NativeProxy object */ PR_ASSERT( (*env)->IsInstanceOf(env, nativeProxy, nativeProxyClass) ); #endif byteArrayField = (*env)->GetFieldID( env, proxyClass, NATIVE_PROXY_POINTER_FIELD, NATIVE_PROXY_POINTER_SIG); if(byteArrayField==NULL) { ASSERT_OUTOFMEM(env); return PR_FAILURE; } byteArray = (jbyteArray) (*env)->GetObjectField(env, nativeProxy, byteArrayField); PR_ASSERT(byteArray != NULL); size = sizeof(*ptr); PR_ASSERT((*env)->GetArrayLength(env, byteArray) == size); (*env)->GetByteArrayRegion(env, byteArray, 0, size, (void*)ptr); if( (*env)->ExceptionOccurred(env) ) { PR_ASSERT(PR_FALSE); return PR_FAILURE; } else { return PR_SUCCESS; } } /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y O w n e r ** ** Given an object which contains a NativeProxy, extract the pointer ** from the NativeProxy and store it at the given address. ** ** proxyOwner: an object which contains a NativeProxy member. ** proxyFieldName: the name of the NativeProxy member. ** proxyFieldSig: the signature of the NativeProxy member. ** ptr: address of a void* that will receive the extract pointer. ** Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. ** ** Example: ** ** public class Owner { ** protected MyProxy myProxy; ** [...] ** } ** ** ** DataStructure *recovered; ** jobject owner; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxyOwner(env, owner, "myProxy", (void**)&recovered) ** != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxyOwner(JNIEnv *env, jobject proxyOwner, char* proxyFieldName, char *proxyFieldSig, void **ptr) { jclass ownerClass; jfieldID proxyField; jobject proxyObject; PR_ASSERT(env!=NULL && proxyOwner!=NULL && proxyFieldName!=NULL && ptr!=NULL); /* * Get proxy object */ ownerClass = (*env)->GetObjectClass(env, proxyOwner); proxyField = (*env)->GetFieldID(env, ownerClass, proxyFieldName, proxyFieldSig); if(proxyField == NULL) { return PR_FAILURE; } proxyObject = (*env)->GetObjectField(env, proxyOwner, proxyField); PR_ASSERT(proxyObject != NULL); /* * Get the pointer from the Native Reference object */ return JSS_getPtrFromProxy(env, proxyObject, ptr); } /*********************************************************************** ** ** J S S _ p t r T o B y t e A r r a y ** ** Turn a C pointer into a Java byte array. The byte array can be passed ** into a NativeProxy constructor. ** ** Returns a byte array containing the pointer, or NULL if an exception ** was thrown. */ jbyteArray JSS_ptrToByteArray(JNIEnv *env, void *ptr) { jbyteArray byteArray; /* Construct byte array from the pointer */ byteArray = (*env)->NewByteArray(env, sizeof(ptr)); if(byteArray==NULL) { PR_ASSERT( (*env)->ExceptionOccurred(env) != NULL); return NULL; } (*env)->SetByteArrayRegion(env, byteArray, 0, sizeof(ptr), (jbyte*)&ptr); if((*env)->ExceptionOccurred(env) != NULL) { PR_ASSERT(PR_FALSE); return NULL; } return byteArray; } /*********************************************************************** * * J S S _ O c t e t S t r i n g T o B y t e A r r a y * * Converts a representation of an integer as a big-endian octet string * stored in a SECItem (as used by the low-level crypto functions) to a * representation of an integer as a big-endian Java byte array. Prepends * a zero byte to force it to be positive. Returns NULL if an exception * occurred. * */ jbyteArray JSS_OctetStringToByteArray(JNIEnv *env, SECItem *item) { jbyteArray array; jbyte *bytes; int size; /* size of the resulting byte array */ PR_ASSERT(env != NULL && item->len>0); /* allow space for extra zero byte */ size = item->len+1; array = (*env)->NewByteArray(env, size); if(array == NULL) { ASSERT_OUTOFMEM(env); return NULL; } bytes = (*env)->GetByteArrayElements(env, array, NULL); if(bytes == NULL) { ASSERT_OUTOFMEM(env); return NULL; } /* insert a 0 as the MSByte to force the string to be positive */ bytes[0] = 0; /* now insert the rest of the bytes */ memcpy(bytes+1, item->data, size-1); (*env)->ReleaseByteArrayElements(env, array, bytes, 0); return array; } #define ZERO_SECITEM(item) {(item).data=NULL; (item).len=0;} /*********************************************************************** * * J S S _ B y t e A r r a y T o O c t e t S t r i n g * * Converts an integer represented as a big-endian Java byte array to * an integer represented as a big-endian octet string in a SECItem. * * INPUTS * byteArray * A Java byte array containing an integer represented in * big-endian format. Must not be NULL. * item * Pointer to a SECItem that will be filled with the integer * from the byte array, in big-endian format. * RETURNS * PR_SUCCESS if the operation was successful, PR_FAILURE if an exception * was thrown. */ PRStatus JSS_ByteArrayToOctetString(JNIEnv *env, jbyteArray byteArray, SECItem *item) { jbyte *bytes=NULL; PRStatus status=PR_FAILURE; jsize size; PR_ASSERT(env!=NULL && byteArray!=NULL && item!=NULL); ZERO_SECITEM(*item); size = (*env)->GetArrayLength(env, byteArray); PR_ASSERT(size > 0); bytes = (*env)->GetByteArrayElements(env, byteArray, NULL); if(bytes==NULL) { ASSERT_OUTOFMEM(env); goto finish; } item->data = (unsigned char*) PR_Malloc(size); if(item->data == NULL) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } item->len = size; memcpy(item->data, bytes, size); status = PR_SUCCESS; finish: if(bytes) { (*env)->ReleaseByteArrayElements(env, byteArray, bytes, JNI_ABORT); } if(status != PR_SUCCESS) { SECITEM_FreeItem(item, PR_FALSE); } return status; } /************************************************************************ * * J S S _ w i p e C h a r A r r a y * * Given a string, set it to all zeroes. Be a chum and don't pass in NULL. */ void JSS_wipeCharArray(char* array) { PR_ASSERT(array != NULL); if(array == NULL) { return; } for(; *array != '\0'; array++) { *array = '\0'; } } #ifdef DEBUG static int debugLevel = JSS_TRACE_VERBOSE; #else static int debugLevel = JSS_TRACE_ERROR; #endif /********************************************************************** * * J S S _ t r a c e * * Sends a trace message. * * INPUTS * level * The trace level, from org.mozilla.jss.util.Debug. * mesg * The trace message. Must not be NULL. */ void JSS_trace(JNIEnv *env, jint level, char *mesg) { PR_ASSERT(env!=NULL && mesg!=NULL); if(level <= debugLevel) { printf("%s\n", mesg); fflush(stdout); } } /*********************************************************************** * A S S E R T _ O U T O F M E M * * In most JNI calls that throw Exceptions, OutOfMemoryError is the only * one that doesn't indicate a bug in the code. If a JNI function throws * an exception (or returns an unexpected NULL), you can call this to * PR_ASSERT that it is due to an OutOfMemory condition. It takes a JNIEnv*, * which better not be NULL. */ void JSS_assertOutOfMem(JNIEnv *env) { jclass VARIABLE_MAY_NOT_BE_USED memErrClass; jthrowable excep; PR_ASSERT(env != NULL); /* Make sure an exception has been thrown, and save it */ excep = (*env)->ExceptionOccurred(env); PR_ASSERT(excep != NULL); /* Clear the exception so we can call JNI exceptions */ (*env)->ExceptionClear(env); /* See if the thrown exception was an OutOfMemoryError */ memErrClass = (*env)->FindClass(env, "java/lang/OutOfMemoryError"); PR_ASSERT(memErrClass != NULL); PR_ASSERT( (*env)->IsInstanceOf(env, excep, memErrClass) ); /* Re-throw the exception */ (*env)->Throw(env, excep); } /*********************************************************************** * Debug.setNativeLevel * * If the debug level is changed in Java code, change it in native * code as well. */ JNIEXPORT void JNICALL Java_org_mozilla_jss_util_Debug_setNativeLevel (JNIEnv *env, jclass clazz, jint level) { debugLevel = level; } /*********************************************************************** * Copies the contents of a SECItem into a new Java byte array. * * item * A SECItem. Must not be NULL. * RETURNS * A Java byte array. NULL will be returned if an exception was * thrown. */ jbyteArray JSS_SECItemToByteArray(JNIEnv *env, SECItem *item) { jbyteArray array=NULL; PR_ASSERT(env!=NULL && item!=NULL); PR_ASSERT(item->len >= 0); PR_ASSERT(item->len == 0 || item->data != NULL); array = (*env)->NewByteArray(env, item->len); if( array == NULL ) { ASSERT_OUTOFMEM(env); goto finish; } (*env)->SetByteArrayRegion(env, array, 0, item->len, (jbyte*)item->data); finish: return array; } /*********************************************************************** * J S S _ B y t e A r r a y T o S E C I t e m * * Copies the contents of a Java byte array into a new SECItem. * * byteArray * A Java byte array. Must not be NULL. * RETURNS * A newly allocated SECItem, or NULL iff an exception was thrown. */ SECItem* JSS_ByteArrayToSECItem(JNIEnv *env, jbyteArray byteArray) { SECItem *item = NULL; PR_ASSERT(env!=NULL && byteArray!=NULL); /* Create a new SECItem */ item = PR_NEW(SECItem); if( item == NULL ) { JSS_throw(env, OUT_OF_MEMORY_ERROR); goto finish; } /* Setup the length, allocate the buffer */ item->len = (*env)->GetArrayLength(env, byteArray); item->data = PR_Malloc(item->len); /* copy the bytes from the byte array into the SECItem */ (*env)->GetByteArrayRegion(env, byteArray, 0, item->len, (jbyte*)item->data); if( (*env)->ExceptionOccurred(env) ) { SECITEM_FreeItem(item, PR_TRUE /*freeit*/); item = NULL; } finish: return item; } /* * External references to the rcs and sccsc ident information in * jssver.c. These are here to prevent the compiler from optimizing * away the symbols in jssver.c */ extern const char __jss_base_rcsid[]; extern const char __jss_base_sccsid[]; jss-4.4.3/jss/org/mozilla/jss/util/jssutil.h000066400000000000000000000205101326145000000207650ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef JSS_NATIVE_UTIL_H #define JSS_NATIVE_UTIL_H /* The following #defines are used to suppress undesired compiler warnings * that have been deemed inappropriate. * * IMPORTANT: These are ONLY used on an "as-needed" basis! */ #ifdef __GNUC__ #define FUNCTION_MAY_NOT_BE_USED __attribute__ ((unused)) #define VARIABLE_MAY_NOT_BE_USED __attribute__ ((unused)) #else #define FUNCTION_MAY_NOT_BE_USED #define VARIABLE_MAY_NOT_BE_USED #endif /* Need to include these first. * #include * #include * #include */ PR_BEGIN_EXTERN_C /**** NSPR private thread functions ****/ /* PRThread* PR_AttachThread(PRThreadType type, PRThreadPriority priority, PRThreadStack *stack); void PR_DetachThread(void); */ #define PR_AttachThread(a, b, c) ((PRThread*)1) #define PR_DetachThread() /* defined in CryptoManager.c */ extern JavaVM *JSS_javaVM; /*********************************************************************** * J S S _ t h r o w M s g * * Throw an exception in native code. You should return right after * calling this function. * * throwableClassName is the name of the throwable you are throwing in * JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. * * message is the message parameter of the throwable. It must not be NULL. * If you don't have a message, call JSS_nativeThrow. * * Example: * JSS_nativeThrowMsg(env, "java/lang/IllegalArgumentException", * "Bogus argument, you ninny"); * return -1; */ void JSS_throwMsg(JNIEnv *env, char *throwableClassName, char *message); #define JSS_nativeThrowMsg JSS_throwMsg /*********************************************************************** * J S S _ t h r o w * * Throw an exception in native code. You should return right after * calling this function. * * throwableClassName is the name of the throwable you are throwing in * JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. * * Example: * JSS_nativeThrow(env, "java/lang/IllegalArgumentException"); * return -1; */ void JSS_throw(JNIEnv *env, char *throwableClassName); #define JSS_nativeThrow JSS_throw /*********************************************************************** * A S S E R T _ O U T O F M E M * * In most JNI calls that throw Exceptions, OutOfMemoryError is the only * one that doesn't indicate a bug in the code. If a JNI function throws * an exception (or returns an unexpected NULL), you can call this to * PR_ASSERT that it is due to an OutOfMemory condition. It takes a JNIEnv*, * which better not be NULL. */ void JSS_assertOutOfMem(JNIEnv *env); #ifdef DEBUG #define ASSERT_OUTOFMEM(env) JSS_assertOutOfMem(env) #else #define ASSERT_OUTOFMEM(env) #endif /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y ** ** Given a NativeProxy, extract the pointer and store it at the given ** address. ** ** nativeProxy: a JNI reference to a NativeProxy. ** ptr: address of a void* that will receive the pointer extracted from ** the NativeProxy. ** Returns: PR_SUCCESS on success, PR_FAILURE if an exception was thrown. ** ** Example: ** DataStructure *recovered; ** jobject proxy; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxy(env, proxy, (void**)&recovered) != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxy(JNIEnv *env, jobject nativeProxy, void **ptr); /*********************************************************************** ** ** J S S _ g e t P t r F r o m P r o x y O w n e r ** ** Given an object which contains a NativeProxy, extract the pointer ** from the NativeProxy and store it at the given address. ** ** proxyOwner: an object which contains a NativeProxy member. ** proxyFieldName: the name of the NativeProxy member. ** proxyFieldSig: the signature of the NativeProxy member. ** ptr: address of a void* that will receive the extract pointer. ** Returns: PR_SUCCESS for success, PR_FAILURE if an exception was thrown. ** ** Example: ** ** public class Owner { ** protected MyProxy myProxy; ** [...] ** } ** ** ** DataStructure *recovered; ** jobject owner; ** JNIEnv *env; ** [...] ** if(JSS_getPtrFromProxyOwner(env, owner, "myProxy", (void**)&recovered) ** != PR_SUCCESS) { ** return; // exception was thrown! ** } */ PRStatus JSS_getPtrFromProxyOwner(JNIEnv *env, jobject proxyOwner, char* proxyFieldName, char *proxyFieldSig, void **ptr); /* * Turn a C pointer into a Java byte array. The byte array can be passed * into a NativeProxy constructor. * * Returns a byte array containing the pointer, or NULL if an exception * was thrown. */ jbyteArray JSS_ptrToByteArray(JNIEnv *env, void *ptr); /************************************************************************ * * J S S _ w i p e C h a r A r r a y * * Given a string, set it to all zeroes. Don't pass in NULL. */ void JSS_wipeCharArray(char* array); /********************************************************************** * * J S S _ t r a c e * * Sends a trace message. * * INPUTS * level * The trace level (see below for constants). Must be > 0. * mesg * The trace message. Must not be NULL. */ void JSS_trace(JNIEnv *env, jint level, char *mesg); /* trace levels */ #define JSS_TRACE_ERROR 1 #define JSS_TRACE_VERBOSE 5 #define JSS_TRACE_OBNOXIOUS 10 /*********************************************************************** * J S S _ S E C I t e m T o B y t e A r r a y * * Copies the contents of a SECItem into a new Java byte array. * * item * A SECItem. Must not be NULL. * RETURNS * A Java byte array. NULL will be returned if an exception was * thrown. */ jbyteArray JSS_SECItemToByteArray(JNIEnv *env, SECItem *item); /*********************************************************************** * J S S _ B y t e A r r a y T o S E C I t e m * * Copies the contents of a Java byte array into a new SECItem. * * byteArray * A Java byte array. Must not be NULL. * RETURNS * A newly allocated SECItem, or NULL iff an exception was thrown. */ SECItem* JSS_ByteArrayToSECItem(JNIEnv *env, jbyteArray byteArray); /*********************************************************************** * J S S _ s t r e r r o r * * Provides string representations for NSPR, SEC, and SSL errors. * Swiped from PSM. * * RETURNS * A UTF-8 encoded constant error string for errNum. * NULL if errNum is unknown. */ const char * JSS_strerror(PRErrorCode errNum); /*********************************************************************** ** ** J S S _ t h r o w M s g P r E r r A r g ** ** Throw an exception in native code. You should return right after ** calling this function. ** ** throwableClassName is the name of the throwable you are throwing in ** JNI class name format (xxx/xx/xxx/xxx). It must not be NULL. ** ** message is the message parameter of the throwable. It must not be NULL. ** If you don't have a message, call JSS_throw. ** ** errCode is a PRErrorCode returned from PR_GetError(). ** ** Example: ** JSS_throwMsg(env, ILLEGAL_ARGUMENT_EXCEPTION, PR_GetError()); ** return -1; */ void JSS_throwMsgPrErrArg(JNIEnv *env, char *throwableClassName, char *message, PRErrorCode errCode); #define JSS_throwMsgPrErr(e, cn, m) \ JSS_throwMsgPrErrArg((e), (cn), (m), PR_GetError()) /************************************************************************ ** ** J S S _ i n i t E r r c o d e T r a n s l a t i o n T a b l e. ** ** Initializes the error code translation table. This should be called ** by CryptoManager.initialize(), and must be called before any calls to ** JSS_ConvertNativeErrcodeToJava. ** */ void JSS_initErrcodeTranslationTable(); /************************************************************************ ** ** J S S _ C o n v e r t N a t i v e E r r c o d e T o J a v a ** ** Converts an NSPR or NSS error code to a Java error code. ** (defined in the class o.m.util.NativeErrcodes) ** ** Returns ** The Java error code, or -1 if a corresponding Java error code could ** not be found. */ int JSS_ConvertNativeErrcodeToJava(int nativeErrcode); PR_END_EXTERN_C #endif jss-4.4.3/jss/org/mozilla/jss/util/jssver.c000066400000000000000000000014031326145000000205770ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "jssver.h" /* Library identity and versioning */ #if defined(DEBUG) #define _DEBUG_STRING " (debug)" #else #define _DEBUG_STRING "" #endif /* * Version information for the 'ident' and 'what commands * * NOTE: the first component of the concatenated rcsid string * must not end in a '$' to prevent rcs keyword substitution. */ const char __jss_base_rcsid[] = "$Header: JSS " JSS_VERSION _DEBUG_STRING " " __DATE__ " " __TIME__ " $"; const char __jss_base_sccsid[] = "@(#)JSS " JSS_VERSION _DEBUG_STRING " " __DATE__ " " __TIME__; jss-4.4.3/jss/org/mozilla/jss/util/jssver.h000066400000000000000000000025351326145000000206130ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef JSSVER_H #define JSSVER_H /* * JSS's major version, minor version, patch level, and whether * this is a beta release. * * The format of the version string should be * ".[.] []" */ /********************************************************************/ /* The VERSION Strings should be updated in the following */ /* files everytime a new release of JSS is generated: */ /* */ /* lib/manifest.mn */ /* org/mozilla/jss/CryptoManager.c */ /* org/mozilla/jss/CryptoManager.java */ /* org/mozilla/jss/JSSProvider.java */ /* org/mozilla/jss/util/jssver.h */ /* */ /********************************************************************/ #define JSS_VERSION "4.4.0" #define JSS_VMAJOR 4 #define JSS_VMINOR 4 #define JSS_VPATCH 0 #define JSS_BETA PR_FALSE #endif jss-4.4.3/jss/org/mozilla/jss/util/manifest.mn000066400000000000000000000013611326145000000212640ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../../../.. MODULE = jss NS_USE_JDK = 1 REQUIRES = nspr20 nss PACKAGE = org/mozilla/jss/util PRIVATE_EXPORTS = jssutil.h \ jss_exceptions.h \ java_ids.h \ jss_bigint.h \ jssver.h \ $(NULL) CSRCS = jssutil.c \ jssver.c \ errstrings.c \ NativeErrcodes.c \ $(NULL) LIBRARY_NAME = jssutil jss-4.4.3/jss/org/mozilla/manifest.mn000066400000000000000000000004171326145000000175110ustar00rootroot00000000000000# # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../.. MODULE = jss DIRS = jss \ $(NULL) jss-4.4.3/jss/pkg/000077500000000000000000000000001326145000000136705ustar00rootroot00000000000000jss-4.4.3/jss/pkg/Makefile000066400000000000000000000011011326145000000153210ustar00rootroot00000000000000#! gmake # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. CORE_DEPTH = ../.. DEPTH = ../.. include $(CORE_DEPTH)/coreconf/config.mk publish: ifeq ($(OS_TARGET),Linux) rm -rf $(OBJDIR) cp -r linux $(OBJDIR) $(MAKE) -C $(OBJDIR) publish endif ifeq ($(OS_TARGET),SunOS) rm -rf $(OBJDIR) cp -r solaris $(OBJDIR) $(MAKE) -C $(OBJDIR) publish endif clean:: rm -rf $(OBJDIR) include $(CORE_DEPTH)/coreconf/rules.mk jss-4.4.3/jss/pkg/linux/000077500000000000000000000000001326145000000150275ustar00rootroot00000000000000jss-4.4.3/jss/pkg/linux/Makefile000066400000000000000000000052251326145000000164730ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # CORE_DEPTH = ../../.. NAME = sun-jss ifndef RPM_RELEASE RPM_RELEASE = 1 endif VERSION = `grep JSS_VERSION $(CORE_DEPTH)/jss/org/mozilla/jss/util/jssver.h \ | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//'` PWD = `pwd` BUILDROOT = $(PWD)\/$(NAME)-root include $(CORE_DEPTH)/coreconf/config.mk # Force i386 for non 64 bit build ifneq ($(USE_64),1) RPMTARGET = "--target=i386" RPMLIBDIR = lib else RPMLIBDIR = lib64 endif publish: $(MAKE) clean mkdir -p SOURCES SRPMS RPMS BUILD mkdir -p opt/sun/private/$(RPMLIBDIR) find $(CORE_DEPTH)/../dist/$(OBJDIR)/lib -type l \ \( -name "*jss*.so" \) \ -exec cp {} opt/sun/private/$(RPMLIBDIR) \; ifdef JSS3_LOCATION cp $(JSS3_LOCATION)/$(OBJDIR)/lib/libjss3.so opt/sun/private/$(RPMLIBDIR) endif mkdir -p opt/sun/private/share/lib ifeq ($(BUILD_OPT), 1) cp $(CORE_DEPTH)/../dist/release/no-policy/classes/jss4.jar \ opt/sun/private/share/lib/jss4.jar ifdef JSS3_LOCATION cp $(JSS3_LOCATION)/xpclass.jar opt/sun/private/share/lib/jss3.jar endif else cp $(CORE_DEPTH)/../dist/release/no-policy/classes_DBG/jss4_dbg.jar \ opt/sun/private/share/lib/jss4.jar ifdef JSS3_LOCATION cp $(JSS3_LOCATION)/xpclass_dbg.jar opt/sun/private/share/lib/jss3.jar endif endif tar czvf $(NAME)-$(VERSION).tar.gz opt echo "AutoReq: 0" > temp.spec echo "%define _topdir `pwd`" >>temp.spec sed -e "s/NAME_REPLACE/$(NAME)/" \ -e "s/VERSION_REPLACE/$(VERSION)/" \ -e "s/RELEASE_REPLACE/$(RPM_RELEASE)/" \ <$(NAME).spec >>temp.spec echo "" >>temp.spec echo "%files" >>temp.spec echo "%defattr(-,root,root)" >>temp.spec echo "%dir /opt" >>temp.spec echo "%dir /opt/sun" >>temp.spec echo "%dir /opt/sun/private" >>temp.spec echo "%dir /opt/sun/private/$(RPMLIBDIR)" >>temp.spec echo "%dir /opt/sun/private/share" >>temp.spec echo "%dir /opt/sun/private/share/lib" >>temp.spec find opt \( -name "*.so" -o -name "*.jar" \) \ | sed -e "s-^-/-" >>temp.spec echo "" >>temp.spec echo "%files devel" >>temp.spec echo "%defattr(-,root,root)" >>temp.spec find opt -type d | sed -e "s-^-%dir /-" >>temp.spec find opt -type f ! \( -name "*.so" -o -name "*.jar" \) \ | sed -e "s-^-/-" >>temp.spec cp $(NAME)-$(VERSION).tar.gz SOURCES rpmbuild $(RPMTARGET) -bb temp.spec clean:: rm -rf SOURCES SRPMS RPMS BUILD rm -rf opt rm -f temp.spec rm -f $(NAME)-$(VERSION).tar.gz include $(CORE_DEPTH)/coreconf/rules.mk jss-4.4.3/jss/pkg/linux/sun-jss.spec000066400000000000000000000031351326145000000173070ustar00rootroot00000000000000Summary: Network Security Services for Java Name: NAME_REPLACE Vendor: Sun Microsystems, Inc. Version: VERSION_REPLACE Release: RELEASE_REPLACE Copyright: Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Also under other license(s) as shown at the Description field. Distribution: Sun Java(TM) Enterprise System URL: http://www.sun.com Group: System Environment/Base Source: %{name}-%{version}.tar.gz ExclusiveOS: Linux BuildRoot: %_topdir/%{name}-root Requires: sun-nspr >= 4.3, sun-nss >= 3.9 %description Network Security Services for Java (JSS) is a set of libraries designed to support cross-platform development of security-enabled server applications. Applications built with JSS can support SSL v2 and v3, TLS, PKCS #5, PKCS #7, PKCS #11, PKCS #12, S/MIME, X.509 v3 certificates, and other security standards. See: http://www.mozilla.org/projects/security/pki/jss/ This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. %package devel Summary: Development Libraries for Network Security Services for Java Group: Development/Libraries Requires: %{name} = %{version}-%{release} %define _unpackaged_files_terminate_build 0 %description devel Header files for doing development with Network Security Services for Java. Under "MPL/GPL" license. %prep %setup -c %build %install rm -rf $RPM_BUILD_ROOT mkdir $RPM_BUILD_ROOT cd $RPM_BUILD_ROOT tar xvzf $RPM_SOURCE_DIR/%{name}-%{version}.tar.gz %clean rm -rf $RPM_BUILD_ROOT jss-4.4.3/jss/pkg/solaris/000077500000000000000000000000001326145000000153445ustar00rootroot00000000000000jss-4.4.3/jss/pkg/solaris/Makefile000066400000000000000000000052341326145000000170100ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # CORE_DEPTH = ../../.. %: %.ksh $(RM) $@ $(CP) $< $@ chmod +x $@ DIRS = \ SUNWjss include Makefile.com PROTO = \ $(ROOT) \ $(ROOT)/usr/share/lib/mps \ $(ROOT)/usr/lib/mps ifeq ($(MACH),sparc) PROTO += $(ROOT)/usr/share/lib/mps/sparcv9 \ $(ROOT)/usr/lib/mps/sparcv9 endif ifeq ($(USE_64), 1) ifeq ($(MACH), sparc) # Sparc PROTO += $(ROOT)/usr/lib/mps/sparcv9 \ $(ROOT)/usr/share/lib/mps/sparcv9 else # AMD64 PROTO += $(ROOT)/usr/lib/mps/amd64 \ $(ROOT)/usr/share/lib/mps/amd64 endif DIST64 = $(DIST) DIST32 = $(shell echo $(DIST) | sed -e "s|_64_OPT|_OPT|g" -e "s|_64_DBG|_DBG|g") else DIST32 = $(DIST) DIST64 = $(shell echo $(DIST) | sed -e "s|_OPT|_64_OPT|g" -e "s|_DBG|_64_DBG|g") endif OBJ32 = $(shell basename $(DIST32)) OBJ64 = $(shell basename $(DIST64)) ifeq ($(BUILD_OPT),1) IMPORT_JSS_JAR = jss4.jar else IMPORT_JSS_JAR = jss4_dbg.jar endif awk_pkginfo: bld_awk_pkginfo ./bld_awk_pkginfo -m $(MACH) -p "$(PRODUCT_VERSION)" -o $@ -v $(PRODUCT_VERSION) all:: awk_pkginfo $(PROTO) publish: awk_pkginfo $(PROTO) +$(LOOP_OVER_DIRS) clean clobber:: $(RM) awk_pkginfo bld_awk_pkginfo $(RM) -r $(ROOT) $(ROOT): mkdir -p $@ $(ROOT)/usr/lib/mps/sparcv9: mkdir -p $@ $(CP) -r $(DIST64)/lib/*.so $@ ifdef JSS3_LOCATION $(CP) $(JSS3_LOCATION)/$(OBJ64)/lib/libjss3.so $@ endif $(ROOT)/usr/share/lib/mps/sparcv9: echo "target=$(SOURCE_RELEASE_XP_DIR)/$(SOURCE_RELEASE_XP_CLASSES_DIR)/$(IMPORT_JSS_JAR)" mkdir -p $@ $(CP) $(SOURCE_RELEASE_XP_DIR)/$(SOURCE_RELEASE_XP_CLASSES_DIR)/$(IMPORT_JSS_JAR) $@/jss4.jar ifdef JSS3_LOCATION $(CP) $(JSS3_LOCATION)/$(IMPORT_XPCLASS_JAR) $@/jss3.jar endif $(ROOT)/usr/lib/mps/amd64: mkdir -p $@ $(CP) -r $(DIST64)/lib/*.so $@ $(ROOT)/usr/share/lib/mps/amd64: echo "target=$(SOURCE_RELEASE_XP_DIR)/$(SOURCE_RELEASE_XP_CLASSES_DIR)/$(IMPORT_JSS_JAR)" mkdir -p $@ $(CP) $(SOURCE_RELEASE_XP_DIR)/$(SOURCE_RELEASE_XP_CLASSES_DIR)/$(IMPORT_JSS_JAR) $@/jss4.jar $(ROOT)/usr/lib/mps: mkdir -p $@ $(CP) -r $(DIST32)/lib/*.so $@ ifdef JSS3_LOCATION $(CP) $(JSS3_LOCATION)/$(OBJ32)/lib/libjss3.so $@ endif $(ROOT)/usr/share/lib/mps: echo "target=$(SOURCE_RELEASE_XP_DIR)/$(SOURCE_RELEASE_XP_CLASSES_DIR)/$(IMPORT_JSS_JAR)" mkdir -p $@ $(CP) $(SOURCE_RELEASE_XP_DIR)/$(SOURCE_RELEASE_XP_CLASSES_DIR)/$(IMPORT_JSS_JAR) $@/jss4.jar ifdef JSS3_LOCATION $(CP) $(JSS3_LOCATION)/$(IMPORT_XPCLASS_JAR) $@/jss3.jar endif jss-4.4.3/jss/pkg/solaris/Makefile.com000066400000000000000000000015661326145000000175710ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # MACH = $(shell mach) PUBLISH_ROOT = $(DIST) ifeq ($(CORE_DEPTH),../../..) ROOT = ROOT else ROOT = $(subst ../../../,,$(CORE_DEPTH))/ROOT endif PKGARCHIVE = $(PUBLISH_ROOT)/pkgarchive DATAFILES = copyright FILES = $(DATAFILES) pkginfo PACKAGE = $(shell basename `pwd`) PRODUCT_VERSION = $(shell grep JSS_VERSION $(CORE_DEPTH)/jss/org/mozilla/jss/util/jssver.h | sed -e 's/"$$//' -e 's/.*"//' -e 's/ .*//') LN = /usr/bin/ln CP = /usr/bin/cp CLOBBERFILES = $(FILES) include $(CORE_DEPTH)/coreconf/config.mk include $(CORE_DEPTH)/coreconf/rules.mk # vim: ft=make jss-4.4.3/jss/pkg/solaris/Makefile.targ000066400000000000000000000020601326145000000177360ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # include ../proto64.mk ifdef JSS3_LOCATION PROTOTYPE_BASE=prototype3_ else PROTOTYPE_BASE=prototype_ endif pkginfo: pkginfo.tmpl ../awk_pkginfo $(RM) $@; nawk -f ../awk_pkginfo $@.tmpl > $@ prototype: prototype_$(MACH) @echo "Using $(PROTOTYPE_BASE)$(MACH) to build package $(PACKAGE)" cat $(PROTOTYPE_BASE)$(MACH) | sed $(sed_proto64) >prototype pkg: $(PKGARCHIVE) pkgdepend prototype pkgmk -f prototype -d $(PKGARCHIVE) -r $(ROOT) -o $(PACKAGE) $(PKGARCHIVE): [ -d $(PKGARCHIVE) ] || mkdir -p $(PKGARCHIVE) $(DATAFILES):: %: ../common_files/% $(RM) $@; cp ../common_files/$@ $@ $(MACHDATAFILES): %: ../common_files/%_$(MACH) $(RM) $@; cp ../common_files/$@_$(MACH) $@ clobber clean:: -$(RM) $(CLOBBERFILES) $(CLEANFILES) .PHONY: pkg jss-4.4.3/jss/pkg/solaris/SUNWjss/000077500000000000000000000000001326145000000166605ustar00rootroot00000000000000jss-4.4.3/jss/pkg/solaris/SUNWjss/Makefile000066400000000000000000000006541326145000000203250ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # CORE_DEPTH = ../../../.. include ../Makefile.com all:: $(FILES) publish:: all pkg include ../Makefile.targ jss-4.4.3/jss/pkg/solaris/SUNWjss/pkgdepend000066400000000000000000000016001326145000000205410ustar00rootroot00000000000000# Copyright 2005 Microsystems, Inc. All Rights Reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # $Id$ # # This package information file defines software dependencies associated # with the pkg. You can define three types of pkg dependencies with this file: # P indicates a prerequisite for installation # I indicates an incompatible package # R indicates a reverse dependency # see pkginfo(4), PKG parameter # see pkginfo(4), NAME parameter # see pkginfo(4), VERSION parameter # see pkginfo(4), ARCH parameter # # () # () # ... # # ... P SUNWtls Netscape Security Services jss-4.4.3/jss/pkg/solaris/SUNWjss/pkginfo.tmpl000066400000000000000000000022161326145000000212140ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # # # This required package information file describes characteristics of the # package, such as package abbreviation, full package name, package version, # and package architecture. # PKG="SUNWjss" NAME="Network Security Services for Java (JSS)" ARCH="ISA" VERSION="JSSVERS,REV=0.0.0" SUNW_PRODNAME="Network Security Services for Java (JSS)" SUNW_PRODVERS="JSSVERS" SUNW_PKGTYPE="usr" MAXINST="1000" CATEGORY="system" DESC="Network Security Services for Java (JSS)" VENDOR="Sun Microsystems, Inc." HOTLINE="Please contact your local service provider" EMAIL="" CLASSES="none" BASEDIR=/ SUNW_PKGVERS="1.0" #VSTOCK="" #ISTATES="" #RSTATES='' #ULIMIT="" #ORDER="" #PSTAMP="" #INTONLY="" jss-4.4.3/jss/pkg/solaris/SUNWjss/prototype3_com000066400000000000000000000031621326145000000215730ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # # This required package information file contains a list of package contents. # The 'pkgmk' command uses this file to identify the contents of a package # and their location on the development machine when building the package. # Can be created via a text editor or through use of the 'pkgproto' command. #!search # where to find pkg objects #!include # include another 'prototype' file #!default # default used if not specified on entry #!= # puts parameter in pkg environment # packaging files i copyright i pkginfo i depend=pkgdepend # # source locations relative to the prototype file # # SUNWpr # d none usr 755 root sys d none usr/lib 755 root bin d none usr/lib/mps 755 root bin d none usr/lib/mps/secv1 755 root bin d none usr/share 755 root sys d none usr/share/lib 755 root sys d none usr/share/lib/mps 755 root bin d none usr/share/lib/mps/secv1 755 root bin f none usr/lib/mps/libjss4.so 755 root bin f none usr/share/lib/mps/jss4.jar 644 root bin s none usr/lib/mps/secv1/libjss4.so=../libjss4.so s none usr/share/lib/mps/secv1/jss4.jar=../jss4.jar f none usr/lib/mps/libjss3.so 755 root bin f none usr/share/lib/mps/jss3.jar 644 root bin s none usr/lib/mps/secv1/libjss3.so=../libjss3.so s none usr/share/lib/mps/secv1/jss3.jar=../jss3.jar jss-4.4.3/jss/pkg/solaris/SUNWjss/prototype3_i386000066400000000000000000000020501326145000000215010ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # # This required package information file contains a list of package contents. # The 'pkgmk' command uses this file to identify the contents of a package # and their location on the development machine when building the package. # Can be created via a text editor or through use of the 'pkgproto' command. #!search # where to find pkg objects #!include # include another 'prototype' file #!default # default used if not specified on entry #!= # puts parameter in pkg environment # # Include ISA independent files (prototype_com) # !include prototype3_com # # # # List files which are i386 specific here # # source locations relative to the prototype file # # # SUNWjss jss-4.4.3/jss/pkg/solaris/SUNWjss/prototype3_sparc000066400000000000000000000035101326145000000221220ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # # This required package information file contains a list of package contents. # The 'pkgmk' command uses this file to identify the contents of a package # and their location on the development machine when building the package. # Can be created via a text editor or through use of the 'pkgproto' command. #!search # where to find pkg objects #!include # include another 'prototype' file #!default # default used if not specified on entry #!= # puts parameter in pkg environment # # Include ISA independent files (prototype_com) # !include prototype3_com # # # # List files which are SPARC specific here # # source locations relative to the prototype file # # # SUNWjss #64#s none usr/lib/mps/64=sparcv9 #64#s none usr/lib/mps/secv1/64=sparcv9 #64#d none usr/lib/mps/sparcv9 755 root bin #64#d none usr/share/lib/mps/sparcv9 755 root bin #64#d none usr/lib/mps/secv1/sparcv9 755 root bin #64#d none usr/share/lib/mps/secv1/sparcv9 755 root bin #64#f none usr/lib/mps/sparcv9/libjss4.so 755 root bin #64#f none usr/share/lib/mps/sparcv9/jss4.jar 644 root bin #64#s none usr/lib/mps/secv1/sparcv9/libjss4.so=../../sparcv9/libjss4.so #64#s none usr/share/lib/mps/secv1/sparcv9/jss4.jar=../../sparcv9/jss4.jar #64#f none usr/lib/mps/sparcv9/libjss3.so 755 root bin #64#f none usr/share/lib/mps/sparcv9/jss3.jar 644 root bin #64#s none usr/lib/mps/secv1/sparcv9/libjss3.so=../../sparcv9/libjss3.so #64#s none usr/share/lib/mps/secv1/sparcv9/jss3.jar=../../sparcv9/jss3.jar jss-4.4.3/jss/pkg/solaris/SUNWjss/prototype_com000066400000000000000000000026621326145000000215140ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # # This required package information file contains a list of package contents. # The 'pkgmk' command uses this file to identify the contents of a package # and their location on the development machine when building the package. # Can be created via a text editor or through use of the 'pkgproto' command. #!search # where to find pkg objects #!include # include another 'prototype' file #!default # default used if not specified on entry #!= # puts parameter in pkg environment # packaging files i copyright i pkginfo i depend=pkgdepend # # source locations relative to the prototype file # # SUNWpr # d none usr 755 root sys d none usr/lib 755 root bin d none usr/lib/mps 755 root bin d none usr/lib/mps/secv1 755 root bin d none usr/share 755 root sys d none usr/share/lib 755 root sys d none usr/share/lib/mps 755 root bin d none usr/share/lib/mps/secv1 755 root bin f none usr/lib/mps/libjss4.so 755 root bin f none usr/share/lib/mps/jss4.jar 644 root bin s none usr/lib/mps/secv1/libjss4.so=../libjss4.so s none usr/share/lib/mps/secv1/jss4.jar=../jss4.jar jss-4.4.3/jss/pkg/solaris/SUNWjss/prototype_i386000066400000000000000000000030471326145000000214250ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # # This required package information file contains a list of package contents. # The 'pkgmk' command uses this file to identify the contents of a package # and their location on the development machine when building the package. # Can be created via a text editor or through use of the 'pkgproto' command. #!search # where to find pkg objects #!include # include another 'prototype' file #!default # default used if not specified on entry #!= # puts parameter in pkg environment # # Include ISA independent files (prototype_com) # !include prototype_com # # # # List files which are i386 specific here # # source locations relative to the prototype file # # # SUNWjss #64#s none usr/lib/mps/64=amd64 #64#s none usr/lib/mps/secv1/64=amd64 #64#d none usr/lib/mps/amd64 755 root bin #64#d none usr/share/lib/mps/amd64 755 root bin #64#d none usr/lib/mps/secv1/amd64 755 root bin #64#d none usr/share/lib/mps/secv1/amd64 755 root bin #64#f none usr/lib/mps/amd64/libjss4.so 755 root bin #64#f none usr/share/lib/mps/amd64/jss4.jar 644 root bin #64#s none usr/lib/mps/secv1/amd64/libjss4.so=../../amd64/libjss4.so #64#s none usr/share/lib/mps/secv1/amd64/jss4.jar=../../amd64/jss4.jar jss-4.4.3/jss/pkg/solaris/SUNWjss/prototype_sparc000066400000000000000000000031011326145000000220330ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # # This required package information file contains a list of package contents. # The 'pkgmk' command uses this file to identify the contents of a package # and their location on the development machine when building the package. # Can be created via a text editor or through use of the 'pkgproto' command. #!search # where to find pkg objects #!include # include another 'prototype' file #!default # default used if not specified on entry #!= # puts parameter in pkg environment # # Include ISA independent files (prototype_com) # !include prototype_com # # # # List files which are SPARC specific here # # source locations relative to the prototype file # # # SUNWjss #64#s none usr/lib/mps/64=sparcv9 #64#s none usr/lib/mps/secv1/64=sparcv9 #64#d none usr/lib/mps/sparcv9 755 root bin #64#d none usr/share/lib/mps/sparcv9 755 root bin #64#d none usr/lib/mps/secv1/sparcv9 755 root bin #64#d none usr/share/lib/mps/secv1/sparcv9 755 root bin #64#f none usr/lib/mps/sparcv9/libjss4.so 755 root bin #64#f none usr/share/lib/mps/sparcv9/jss4.jar 644 root bin #64#s none usr/lib/mps/secv1/sparcv9/libjss4.so=../../sparcv9/libjss4.so #64#s none usr/share/lib/mps/secv1/sparcv9/jss4.jar=../../sparcv9/jss4.jar jss-4.4.3/jss/pkg/solaris/bld_awk_pkginfo.ksh000066400000000000000000000035721326145000000212020ustar00rootroot00000000000000#!/usr/bin/ksh -p # #ident "$Id$" # # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # Simple script which builds the awk_pkginfo awk script. This awk script # is used to convert the pkginfo.tmpl files into pkginfo files # for the build. # usage() { cat <<-EOF usage: bld_awk_pkginfo -p -m -o [-v ] EOF } # # Awk strings # # two VERSION patterns: one for Dewey decimal, one for Dewey plus ,REV=n # the first has one '=' the second has two or more '=' # VERSION1="VERSION=[^=]*$" VERSION2="VERSION=[^=]*=.*$" PRODVERS="^SUNW_PRODVERS=" ARCH='ARCH=\"ISA\"' # # parse command line # mach="" prodver="" awk_script="" version="JSSVERS" while getopts o:p:m:v: c do case $c in o) awk_script=$OPTARG ;; m) mach=$OPTARG ;; p) prodver=$OPTARG ;; v) version=$OPTARG ;; \?) usage exit 1 ;; esac done if [[ ( -z $prodver ) || ( -z $mach ) || ( -z $awk_script ) ]] then usage exit 1 fi if [[ -f $awk_script ]] then rm -f $awk_script fi # # Build REV= field based on date # rev=$(date "+%Y.%m.%d.%H.%M") # # Build awk script which will process all the # pkginfo.tmpl files. # # the first VERSION pattern is replaced with a leading quotation mark # rm -f $awk_script cat << EOF > $awk_script /$VERSION1/ { sub(/\=[^=]*$/,"=\"$rev\"") print next } /$VERSION2/ { sub(/\=[^=]*$/,"=$rev\"") sub(/JSSVERS/,"$version") print next } /$PRODVERS/ { printf "SUNW_PRODVERS=\"%s\"\n", "$prodver" next } /$ARCH/ { printf "ARCH=\"%s\"\n", "$mach" next } { print } EOF jss-4.4.3/jss/pkg/solaris/common_files/000077500000000000000000000000001326145000000200165ustar00rootroot00000000000000jss-4.4.3/jss/pkg/solaris/common_files/copyright000066400000000000000000000032731326145000000217560ustar00rootroot00000000000000Copyright 2005 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. ***** BEGIN LICENSE BLOCK ***** Version: MPL 1.1/GPL 2.0/LGPL 2.1 The contents of this package are subject to the Mozilla Public License Version 1.1 (the "License"); you may not use this package except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. The Original Code is the Netscape Portable Runtime (NSPR). The Initial Developer of the Original Code is Netscape Communications Corporation. Portions created by the Initial Developer are Copyright (C) 1998-2000 the Initial Developer. All Rights Reserved. Contributor(s): Alternatively, the contents of this file may be used under the terms of either the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the MPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the MPL, the GPL or the LGPL. ***** END LICENSE BLOCK ***** jss-4.4.3/jss/pkg/solaris/proto64.mk000066400000000000000000000006721326145000000172170ustar00rootroot00000000000000# # Copyright 2005 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # #ident "$Id$" # ifeq ($(USE_64), 1) # Remove 64 tag sed_proto64='s/\#64\#//g' else # Strip 64 lines sed_proto64='/\#64\#/d' endif jss-4.4.3/jss/rules.mk000066400000000000000000000014251326145000000145740ustar00rootroot00000000000000.PHONY: buildJava .PHONY: cleanJava .PHONY: releaseJava .PHONY: testJava clean:: cleanJava release_classes:: releaseJava # always do a private_export export:: private_export PERL_VARIABLES= \ "SOURCE_PREFIX=$(SOURCE_PREFIX)" \ "SOURCE_RELEASE_PREFIX=$(SOURCE_RELEASE_PREFIX)" \ "SOURCE_RELEASE_CLASSES_DBG_DIR=$(SOURCE_RELEASE_CLASSES_DBG_DIR)" \ "SOURCE_RELEASE_CLASSES_DIR=$(SOURCE_RELEASE_CLASSES_DIR)" \ "XPCLASS_DBG_JAR=$(XPCLASS_DBG_JAR)" \ "XPCLASS_JAR=$(XPCLASS_JAR)" buildJava: perl build_java.pl $(PERL_VARIABLES) build cleanJava: perl build_java.pl $(PERL_VARIABLES) clean testJava: perl build_java.pl $(PERL_VARIABLES) test releaseJava: perl build_java.pl $(PERL_VARIABLES) release javadoc: perl build_java.pl $(PERL_VARIABLES) javadoc jss-4.4.3/jss/samples/000077500000000000000000000000001326145000000145535ustar00rootroot00000000000000jss-4.4.3/jss/samples/PQGGen.java000066400000000000000000000036131326145000000165020ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ import org.mozilla.jss.*; import org.mozilla.jss.crypto.*; /** * A command-line utility for generating PQG parameters for DSA * Key operations. Can be used for testing. * Takes the keysize as the sole argument. */ public class PQGGen { public static void main(String args[]) { int size; PQGParams pqg; try { if(args.length != 1) { throw new Exception("Usage: java PQGGen "); } size = Integer.parseInt(args[0]); System.out.println("Generating PQG parameters for "+size+ "-bit keypairs. This could take hours..."); CryptoManager.initialize("."); pqg = PQGParams.generate(size); System.out.println("Generated PQG Parameters."); System.out.println("Verifying PQG Parameters. "+ "This could take a few minutes..."); if( ! pqg.paramsAreValid() ) { throw new Exception("ERROR: Generated parameters are invalid."); } System.out.println("Parameters are valid!"); System.out.println("P: "+pqg.getP()); System.out.println("Q: "+pqg.getQ()); System.out.println("G: "+pqg.getG()); System.out.println("H: "+pqg.getH()); System.out.println("seed: "+pqg.getSeed()); System.out.println("counter: "+pqg.getCounter()); } catch(NumberFormatException e) { System.err.println("Invalid key size: "+e); } catch(PQGParamGenException e) { System.err.println(e); } catch(java.security.InvalidParameterException e) { System.err.println("Invalid key size: "+e); } catch(Exception e) { System.err.println(e); } } } jss-4.4.3/jss/samples/README.txt000066400000000000000000000001101326145000000162410ustar00rootroot00000000000000Better sample code is available in the org/mozilla/jss/tests directory. jss-4.4.3/jss/samples/inputfile.pfx000066400000000000000000000103221326145000000172670ustar00rootroot0000000000000000 *H $00  *H $00   *H  00   *H  0 *v~/[=C,ŹLKQtr҄#QARז3)cgqȵG?o;fـH [yspXm%R@4~Q%:SΠ }VΛ E=lo+K>;¯ 6m#aEh5e?/:'(y[8fI (4Fq HG>5ًtc%5TLR[l}lztåA@ :{c},VBN25X t16dɐCXćӍ[ƶ4oD?תz OU3qJʘZfF2>|RߊίV -!MnavK%s.\# tQ@/zBM1Wq I:;!~0; TZ7._%p&O!f5vUu[(WiseS"N!#N).sQ` kG,6[k7W( ;Q/uz%,鸚 ?U 5T0 b;JԙB1xN+'o3ǔ!٫`)MGM<8qa0.*%N &[KO1b0;   *H  1.,,,CMS Administrator's ID0#   *H  1"Hn!+_Ϋ0  *H 00  *H 0  *H  0 $)ո>oqƇ8.4Ebp apeyz;mh*/6G[ֽ@ԻCBpvr3rS־{KDK0r2YѮ=WbdgڮڟRJbYc['y^t쟴W?mTt> [Soʹ[;%" U=6S-x`~PTpWkڅX7#{܌%f, wq-F]`v-23,,BC㯿+I=2m`9 2]4P*MPN=$1N0 UjWU^0B^WYVՅ`+sE4p*`HGE)ԩ:]?ę`S;VceαViS[M4׈U"+]/ kvd[$XL8de܂%Vo4q'C0.'M6̌Jml;$hKBLM)[wȁl~` mA.RikӞ 8VS#jUacbH\?L .'g 5v_i|WcWc ^C= ewKI+N~L\ES̰T,"d4ζ QX{nrw$`jhl3Oe31yNnY@$J}`C ֳ+_S+ p[o: ͆n7Gq6@z~m1!!̅]3'fnAQ:6>Y60x v8>܈GF|15^ d3 OMtv͹0Kn^(#Jr˸n[&`+fḭg9e-e t"~A3`=e) qP _{\]3!Y7EQV%i,.ge8dS XE*L᳄_cIIڊ_fOflyq#W6:0z i0Ay.Y&6f/-aU`?^`DPڣRb O!{pν^LdcPO#eSa~s7ч4ӗ'r4\1rZh#g)$Z*.}RG*#ԊCs2$kZ)~\Ҡ]3>@ZaAL!j{T/vK TjkEy x}`'n h9A$'X&xdHүF. ruѸ So޸<84k[Pdmnb050!0 +Қ>cTA~žnzp z.jss-4.4.3/jss/samples/pkcs12.java000066400000000000000000000242601326145000000165250ustar00rootroot00000000000000/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * This program reads in a PKCS #12 file and dumps its contents to the screen. * At the same time, it creates a new PKCS #12 file. As it reads through the * old file, it writes its contents into the new file. Then the new file * is encrypted and MACed with a new, different password. */ /* note that this code still has some problems reading PKCS12 file * generated with Communicator. */ import java.io.*; import org.mozilla.jss.*; import org.mozilla.jss.pkcs12.*; import org.mozilla.jss.crypto.*; import org.mozilla.jss.asn1.*; import org.mozilla.jss.util.*; import org.mozilla.jss.pkix.primitive.*; import org.mozilla.jss.pkix.cert.*; public class pkcs12 { public static void main(String []args) { try { // Read arguments if( args.length != 3 ) { System.out.println("Usage: PFX "); System.exit(-1); } // open input file for reading FileInputStream infile=null; try { infile = new FileInputStream(args[1]); } catch (FileNotFoundException f) { System.out.println("Cannot open file "+args[1]+ " for reading: "+f.getMessage()); return; } int certfile = 0; // initialize CryptoManager. This is necessary because there is // crypto involved with decoding a PKCS #12 file CryptoManager.initialize( args[0] ); CryptoManager manager = CryptoManager.getInstance(); // Decode the P12 file PFX.Template pfxt = new PFX.Template(); PFX pfx = (PFX) pfxt.decode(new BufferedInputStream(infile, 2048)); System.out.println("Decoded PFX"); // print out information about the top-level PFX structure System.out.println("Version: "+pfx.getVersion()); AuthenticatedSafes authSafes = pfx.getAuthSafes(); SEQUENCE safeContentsSequence = authSafes.getSequence(); System.out.println("AuthSafes has "+ safeContentsSequence.size()+" SafeContents"); // Get the password for the old file System.out.println("Enter password: "); Password pass = Password.readPasswordFromConsole(); // get new password, which will be used for the new file we create // later System.out.println("Enter new password:"); Password newPass = Password.readPasswordFromConsole(); // Verify the MAC on the PFX. This is important to be sure // it hasn't been tampered with. StringBuffer sb = new StringBuffer(); if( pfx.verifyAuthSafes(pass, sb) ) { System.out.println("AuthSafes verifies correctly."); } else { System.out.println("AuthSafes failed to verify because: "+ sb); } // Create a new AuthenticatedSafes. As we read the contents of the // old authSafes, we will store them into the new one. After we have // cycled through all the contents, they will all have been copied into // the new authSafes. AuthenticatedSafes newAuthSafes = new AuthenticatedSafes(); // Loop over contents of the old authenticated safes //for(int i=0; i < asSeq.size(); i++) { for(int i=0; i < safeContentsSequence.size(); i++) { // The safeContents may or may not be encrypted. We always send // the password in. It will get used if it is needed. If the // decryption of the safeContents fails for some reason (like // a bad password), then this method will throw an exception SEQUENCE safeContents = authSafes.getSafeContentsAt(pass, i); System.out.println("\n\nSafeContents #"+i+" has "+ safeContents.size()+" bags"); // Go through all the bags in this SafeContents for(int j=0; j < safeContents.size(); j++) { SafeBag safeBag = (SafeBag) safeContents.elementAt(j); // The type of the bag is an OID System.out.println("\nBag "+j+" has type "+ safeBag.getBagType() ); // look for bag attributes SET attribs = safeBag.getBagAttributes(); if( attribs == null ) { System.out.println("Bag has no attributes"); } else { for(int b=0; b < attribs.size(); b++) { Attribute a = (Attribute) attribs.elementAt(b); if( a.getType().equals(SafeBag.FRIENDLY_NAME)) { // the friendly name attribute is a nickname BMPString bs = (BMPString) ((ANY)a.getValues(). elementAt(0)).decodeWith( BMPString.getTemplate()); System.out.println("Friendly Name: "+bs); } else if(a.getType().equals(SafeBag.LOCAL_KEY_ID)){ // the local key id is used to match a key // to its cert. The key id is the SHA-1 hash of // the DER-encoded cert. OCTET_STRING os =(OCTET_STRING) ((ANY)a.getValues(). elementAt(0)).decodeWith( OCTET_STRING.getTemplate()); System.out.println("LocalKeyID:"); /* AuthenticatedSafes. print_byte_array(os.toByteArray()); */ } else { System.out.println("Unknown attribute type: "+ a.getType().toString()); } } } // now look at the contents of the bag ASN1Value val = safeBag.getInterpretedBagContent(); if( val instanceof PrivateKeyInfo ) { // A PrivateKeyInfo contains an unencrypted private key System.out.println("content is PrivateKeyInfo"); } else if( val instanceof EncryptedPrivateKeyInfo ) { // An EncryptedPrivateKeyInfo is, well, an encrypted // PrivateKeyInfo. Usually, strong crypto is used in // an EncryptedPrivateKeyInfo. EncryptedPrivateKeyInfo epki = ((EncryptedPrivateKeyInfo)val); System.out.println( "content is EncryptedPrivateKeyInfo, algoid:" + epki.getEncryptionAlgorithm().getOID()); // Because we are in a PKCS #12 file, the passwords are // char-to-byte converted in a special way. We have to // use the special converter class instead of the default. PrivateKeyInfo pki = epki.decrypt(pass, new org.mozilla.jss.pkcs12.PasswordConverter() ); // import the key into the key3.db CryptoToken tok = manager.getTokenByName("Internal Key Storage Token"); CryptoStore store = tok.getCryptoStore(); tok.login( new ConsolePasswordCallback()); ByteArrayOutputStream baos = new ByteArrayOutputStream(); pki.encode(baos); store.importPrivateKey(baos.toByteArray(), PrivateKey.RSA); // re-encrypt the PrivateKeyInfo with the new password // and random salt byte[] salt = new byte[ PBEAlgorithm.PBE_SHA1_DES3_CBC.getSaltLength()]; JSSSecureRandom rand = CryptoManager.getInstance(). getSecureRNG(); rand.nextBytes(salt); epki = EncryptedPrivateKeyInfo.createPBE( PBEAlgorithm.PBE_SHA1_DES3_CBC, newPass, salt, 1, new PasswordConverter(), pki); // Overwrite the previous EncryptedPrivateKeyInfo with // this new one we just created using the new password. // This is what will get put in the new PKCS #12 file // we are creating. safeContents.insertElementAt( new SafeBag( safeBag.getBagType(), epki, safeBag.getBagAttributes()), i); safeContents.removeElementAt(i+1); } else if( val instanceof CertBag ) { System.out.println("content is CertBag"); CertBag cb = (CertBag) val; if( cb.getCertType().equals(CertBag.X509_CERT_TYPE)) { // this is an X.509 certificate OCTET_STRING os = (OCTET_STRING)cb.getInterpretedCert(); Certificate cert = (Certificate) ASN1Util.decode(Certificate.getTemplate(), os.toByteArray()); cert.getInfo().print(System.out); } else { System.out.println("Unrecognized cert type"); } } else { System.out.println("content is ANY"); } } // Add the new safe contents to the new authsafes if( authSafes.safeContentsIsEncrypted(i) ) { newAuthSafes.addEncryptedSafeContents( authSafes.DEFAULT_KEY_GEN_ALG, newPass, null, authSafes.DEFAULT_ITERATIONS, safeContents); } else { newAuthSafes.addSafeContents( safeContents ); } } // Create new PFX from the new authsafes PFX newPfx = new PFX(newAuthSafes); // Add a MAC to the new PFX newPfx.computeMacData(newPass, null, PFX.DEFAULT_ITERATIONS); // write the new PFX out to a file FileOutputStream fos = new FileOutputStream(args[2]); newPfx.encode(fos); fos.close(); } catch( Exception e ) { e.printStackTrace(); } } }