1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2011-2013. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: -module(pbe_SUITE). 21: 22: -include_lib("common_test/include/ct.hrl"). 23: -include_lib("public_key/include/public_key.hrl"). 24: 25: %% Note: This directive should only be used in test suites. 26: -compile(export_all). 27: 28: %%-------------------------------------------------------------------- 29: %% Common Test interface functions ----------------------------------- 30: %%-------------------------------------------------------------------- 31: 32: suite() -> [{ct_hooks,[ts_install_cth]}]. 33: 34: all() -> 35: [ 36: pbdkdf1, 37: pbdkdf2, 38: encrypted_private_key_info]. 39: 40: groups() -> 41: []. 42: 43: %%-------------------------------------------------------------------- 44: init_per_suite(Config) -> 45: application:stop(crypto), 46: try crypto:start() of 47: ok -> 48: Config 49: catch _:_ -> 50: {skip, "Crypto did not start"} 51: end. 52: 53: end_per_suite(_Config) -> 54: application:stop(crypto). 55: 56: %%-------------------------------------------------------------------- 57: 58: init_per_group(_GroupName, Config) -> 59: Config. 60: 61: end_per_group(_GroupName, Config) -> 62: Config. 63: 64: %%-------------------------------------------------------------------- 65: init_per_testcase(_TestCase, Config) -> 66: Config. 67: 68: 69: end_per_testcase(_TestCase, _Config) -> 70: ok. 71: 72: %%-------------------------------------------------------------------- 73: %% Test Cases -------------------------------------------------------- 74: %%-------------------------------------------------------------------- 75: 76: pbdkdf1() -> 77: [{doc,"Test with PKCS #5 PBKDF1 Test Vectors"}]. 78: pbdkdf1(Config) when is_list(Config) -> 79: %%Password = "password" 80: %% = (0x)70617373776F7264 81: %%Salt = (0x)78578E5A5D63CB06 82: %%Count = 1000 83: %%kLen = 16 84: %%Key = PBKDF1(Password, Salt, Count, kLen) 85: %%= (0x)DC19847E05C64D2FAF10EBFB4A3D2A20 86: 87: Password = "password", 88: Salt = <<16#78,16#57,16#8E,16#5A,16#5D,16#63,16#CB,16#06>>, 89: Count = 1000, 90: 91: <<16#DC, 16#19, 16#84, 16#7E, 92: 16#05, 16#C6, 16#4D, 16#2F, 93: 16#AF, 16#10, 16#EB, 16#FB, 94: 16#4A, 16#3D, 16#2A, 16#20, _/binary>> = 95: pubkey_pbe:pbdkdf1(Password, Salt, Count, sha). 96: 97: pbdkdf2() -> 98: [{doc,"Test with PKCS #5 PBKDF2 Test Vectors"}]. 99: pbdkdf2(Config) when is_list(Config) -> 100: %% Input: 101: %% P = "password" (8 octets) 102: %% S = "salt" (4 octets) 103: %% c = 1 104: %% dkLen = 20 105: 106: %% Output: 107: %% DK = 0c 60 c8 0f 96 1f 0e 71 108: %% f3 a9 b5 24 af 60 12 06 109: %% 2f e0 37 a6 (20 octets) 110: 111: <<16#0c, 16#60, 16#c8, 16#0f, 16#96, 16#1f, 16#0e, 16#71, 112: 16#f3, 16#a9, 16#b5, 16#24, 16#af, 16#60, 16#12, 16#06, 113: 16#2f, 16#e0, 16#37, 16#a6>> = pubkey_pbe:pbdkdf2("password", "salt", 1, 20, fun crypto:hmac/4, sha, 20), 114: 115: %% Input: 116: %% P = "password" (8 octets) 117: %% S = "salt" (4 octets) 118: %% c = 2 119: %% dkLen = 20 120: 121: %% Output: 122: %% DK = ea 6c 01 4d c7 2d 6f 8c 123: %% cd 1e d9 2a ce 1d 41 f0 124: %% d8 de 89 57 (20 octets) 125: 126: <<16#ea, 16#6c, 16#01, 16#4d, 16#c7, 16#2d, 16#6f, 16#8c, 127: 16#cd, 16#1e, 16#d9, 16#2a, 16#ce, 16#1d, 16#41, 16#f0, 128: 16#d8, 16#de, 16#89, 16#57>> = 129: pubkey_pbe:pbdkdf2("password", "salt", 2, 20, fun crypto:hmac/4, sha, 20), 130: 131: %% Input: 132: %% P = "password" (8 octets) 133: %% S = "salt" (4 octets) 134: %% c = 4096 135: %% dkLen = 20 136: 137: %% Output: 138: %% DK = 4b 00 79 01 b7 65 48 9a 139: %% be ad 49 d9 26 f7 21 d0 140: %% 65 a4 29 c1 (20 octets) 141: 142: <<16#4b, 16#00, 16#79, 16#01, 16#b7, 16#65, 16#48, 16#9a, 143: 16#be, 16#ad, 16#49, 16#d9, 16#26, 16#f7, 16#21, 16#d0, 144: 16#65, 16#a4, 16#29, 16#c1>> = pubkey_pbe:pbdkdf2("password", "salt", 4096, 20, fun crypto:hmac/4, sha, 20), 145: 146: %% Input: 147: %% P = "password" (8 octets) 148: %% S = "salt" (4 octets) 149: %% c = 16777216 150: %% dkLen = 20 151: 152: %% Output: 153: %% DK = ee fe 3d 61 cd 4d a4 e4 154: %% e9 94 5b 3d 6b a2 15 8c 155: %% 26 34 e9 84 (20 octets) 156: 157: 158: <<16#ee, 16#fe, 16#3d, 16#61, 16#cd, 16#4d, 16#a4, 16#e4, 159: 16#e9, 16#94, 16#5b, 16#3d, 16#6b, 16#a2, 16#15, 16#8c, 160: 16#26, 16#34, 16#e9, 16#84>> = pubkey_pbe:pbdkdf2("password", "salt", 16777216, 20, fun crypto:hmac/4, sha, 20), 161: 162: %% Input: 163: %% P = "passwordPASSWORDpassword" (24 octets) 164: %% S = "saltSALTsaltSALTsaltSALTsaltSALTsalt" (36 octets) 165: %% c = 4096 166: %% dkLen = 25 167: 168: %% Output: 169: %% DK = 3d 2e ec 4f e4 1c 84 9b 170: %% 80 c8 d8 36 62 c0 e4 4a 171: %% 8b 29 1a 96 4c f2 f0 70 172: %% 38 (25 octets) 173: 174: <<16#3d, 16#2e, 16#ec, 16#4f, 16#e4, 16#1c, 16#84, 16#9b, 175: 16#80, 16#c8, 16#d8, 16#36, 16#62, 16#c0, 16#e4, 16#4a, 176: 16#8b, 16#29, 16#1a, 16#96, 16#4c, 16#f2, 16#f0, 16#70, 177: 16#38>> 178: = pubkey_pbe:pbdkdf2("passwordPASSWORDpassword", 179: "saltSALTsaltSALTsaltSALTsaltSALTsalt", 4096, 25, fun crypto:hmac/4, sha, 20), 180: 181: %% Input: 182: %% P = "pass\0word" (9 octets) 183: %% S = "sa\0lt" (5 octets) 184: %% c = 4096 185: %% dkLen = 16 186: 187: %% Output: 188: %% DK = 56 fa 6a a7 55 48 09 9d 189: %% cc 37 d7 f0 34 25 e0 c3 (16 octets) 190: 191: <<16#56, 16#fa, 16#6a, 16#a7, 16#55, 16#48, 16#09, 16#9d, 192: 16#cc, 16#37, 16#d7, 16#f0, 16#34, 16#25, 16#e0, 16#c3>> 193: = pubkey_pbe:pbdkdf2("pass\0word", 194: "sa\0lt", 4096, 16, fun crypto:hmac/4, sha, 20). 195: 196: encrypted_private_key_info() -> 197: [{doc,"Tests reading a EncryptedPrivateKeyInfo file encrypted with different ciphers"}]. 198: encrypted_private_key_info(Config) when is_list(Config) -> 199: Datadir = ?config(data_dir, Config), 200: {ok, PemDes} = file:read_file(filename:join(Datadir, "des_cbc_enc_key.pem")), 201: 202: PemDesEntry = public_key:pem_decode(PemDes), 203: ct:print("Pem entry: ~p" , [PemDesEntry]), 204: [{'PrivateKeyInfo', _, {"DES-CBC",_}} = PubEntry0] = PemDesEntry, 205: KeyInfo = public_key:pem_entry_decode(PubEntry0, "password"), 206: 207: {ok, Pem3Des} = file:read_file(filename:join(Datadir, "des_ede3_cbc_enc_key.pem")), 208: 209: Pem3DesEntry = public_key:pem_decode(Pem3Des), 210: ct:print("Pem entry: ~p" , [Pem3DesEntry]), 211: [{'PrivateKeyInfo', _, {"DES-EDE3-CBC",_}} = PubEntry1] = Pem3DesEntry, 212: KeyInfo = public_key:pem_entry_decode(PubEntry1, "password"), 213: 214: {ok, PemRc2} = file:read_file(filename:join(Datadir, "rc2_cbc_enc_key.pem")), 215: 216: PemRc2Entry = public_key:pem_decode(PemRc2), 217: ct:print("Pem entry: ~p" , [PemRc2Entry]), 218: [{'PrivateKeyInfo', _, {"RC2-CBC",_}} = PubEntry2] = PemRc2Entry, 219: KeyInfo = public_key:pem_entry_decode(PubEntry2, "password"), 220: 221: %% key generated with ssh-keygen -N hello_aes -f aes_128_cbc_enc_key 222: {ok, PemAesCbc} = file:read_file(filename:join(Datadir, "aes_128_cbc_enc_key")), 223: 224: PemAesCbcEntry = public_key:pem_decode(PemAesCbc), 225: ct:print("Pem entry: ~p" , [PemAesCbcEntry]), 226: [{'RSAPrivateKey', _, {"AES-128-CBC",_}} = PubAesCbcEntry] = PemAesCbcEntry, 227: #'RSAPrivateKey'{} = public_key:pem_entry_decode(PubAesCbcEntry, "hello_aes"), 228: 229: check_key_info(KeyInfo). 230: 231: 232: check_key_info(#'PrivateKeyInfo'{privateKeyAlgorithm = 233: #'PrivateKeyInfo_privateKeyAlgorithm'{algorithm = ?rsaEncryption}, 234: privateKey = Key}) -> 235: #'RSAPrivateKey'{} = public_key:der_decode('RSAPrivateKey', iolist_to_binary(Key)).