1from k5test import * 2 3# The name and number of each supported SPAKE group. 4builtin_groups = ((1, 'edwards25519'),) 5openssl_groups = ((2, 'P-256'), (3, 'P-384'), (4, 'P-521')) 6if runenv.have_spake_openssl == 'yes': 7 groups = builtin_groups + openssl_groups 8else: 9 groups = builtin_groups 10 11for gnum, gname in groups: 12 mark('group %s' % gname) 13 conf = {'libdefaults': {'spake_preauth_groups': gname}} 14 for realm in multipass_realms(create_user=False, create_host=False, 15 krb5_conf=conf): 16 realm.run([kadminl, 'addprinc', '+preauth', '-pw', 'pw', 'user']) 17 18 # Test a basic SPAKE preauth scenario with no optimizations. 19 msgs = ('Sending unauthenticated request', 20 '/Additional pre-authentication required', 21 'Selected etype info:', 22 'Sending SPAKE support message', 23 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 24 '/More preauthentication data is required', 25 'Continuing preauth mech PA-SPAKE (151)', 26 'SPAKE challenge received with group ' + str(gnum), 27 'Sending SPAKE response', 28 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 29 'AS key determined by preauth:', 30 'Decrypted AS reply') 31 realm.kinit('user', 'pw', expected_trace=msgs) 32 33 # Test an unsuccessful authentication. 34 msgs = ('/Additional pre-authentication required', 35 'Selected etype info:', 36 'Sending SPAKE support message', 37 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 38 '/More preauthentication data is required', 39 'Continuing preauth mech PA-SPAKE (151)', 40 'SPAKE challenge received with group ' + str(gnum), 41 'Sending SPAKE response', 42 '/Preauthentication failed') 43 realm.kinit('user', 'wrongpw', expected_code=1, expected_trace=msgs) 44 45conf = {'libdefaults': {'spake_preauth_groups': 'edwards25519'}} 46kdcconf = {'realms': {'$realm': {'spake_preauth_indicator': 'indspake'}}} 47realm = K5Realm(create_user=False, krb5_conf=conf, kdc_conf=kdcconf) 48realm.run([kadminl, 'addprinc', '+preauth', '-pw', 'pw', 'user']) 49 50# Test with FAST. 51mark('FAST') 52msgs = ('Using FAST due to armor ccache negotiation', 53 'FAST armor key:', 54 'Sending unauthenticated request', 55 '/Additional pre-authentication required', 56 'Decoding FAST response', 57 'Selected etype info:', 58 'Sending SPAKE support message', 59 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 60 '/More preauthentication data is required', 61 'Continuing preauth mech PA-SPAKE (151)', 62 'SPAKE challenge received with group 1', 63 'Sending SPAKE response', 64 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 65 'AS key determined by preauth:', 66 'FAST reply key:') 67realm.kinit(realm.host_princ, flags=['-k']) 68realm.kinit('user', 'pw', flags=['-T', realm.ccache], expected_trace=msgs) 69 70# Test optimistic client preauth (151 is PA-SPAKE). 71mark('client optimistic') 72msgs = ('Attempting optimistic preauth', 73 'Processing preauth types: PA-SPAKE (151)', 74 'Sending SPAKE support message', 75 'for next request: PA-SPAKE (151)', 76 '/More preauthentication data is required', 77 'Selected etype info:', 78 'SPAKE challenge received with group 1', 79 'Sending SPAKE response', 80 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 81 'AS key determined by preauth:', 82 'Decrypted AS reply') 83realm.run(['./icred', '-o', '151', 'user', 'pw'], expected_trace=msgs) 84 85# Test KDC optimistic challenge (accepted by client). 86mark('KDC optimistic') 87oconf = {'kdcdefaults': {'spake_preauth_kdc_challenge': 'edwards25519'}} 88oenv = realm.special_env('ochal', True, krb5_conf=oconf) 89realm.stop_kdc() 90realm.start_kdc(env=oenv) 91msgs = ('Sending unauthenticated request', 92 '/Additional pre-authentication required', 93 'Selected etype info:', 94 'SPAKE challenge received with group 1', 95 'Sending SPAKE response', 96 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 97 'AS key determined by preauth:', 98 'Decrypted AS reply') 99realm.kinit('user', 'pw', expected_trace=msgs) 100 101if runenv.have_spake_openssl != 'yes': 102 skip_rest('SPAKE fallback tests', 'SPAKE not built using OpenSSL') 103 104# Test optimistic client preauth falling back to encrypted timestamp 105# because the KDC doesn't support any of the client groups. 106mark('client optimistic (fallback)') 107p256conf={'libdefaults': {'spake_preauth_groups': 'P-256'}} 108p256env = realm.special_env('p256', False, krb5_conf=p256conf) 109msgs = ('Attempting optimistic preauth', 110 'Processing preauth types: PA-SPAKE (151)', 111 'Sending SPAKE support message', 112 'for next request: PA-SPAKE (151)', 113 '/Preauthentication failed', 114 'Selected etype info:', 115 'Encrypted timestamp ', 116 'for next request: PA-FX-COOKIE (133), PA-ENC-TIMESTAMP (2)', 117 'AS key determined by preauth:', 118 'Decrypted AS reply') 119realm.run(['./icred', '-o', '151', 'user', 'pw'], env=p256env, 120 expected_trace=msgs) 121 122# Test KDC optimistic challenge (rejected by client). 123mark('KDC optimistic (rejected)') 124rconf = {'libdefaults': {'spake_preauth_groups': 'P-384,edwards25519'}, 125 'kdcdefaults': {'spake_preauth_kdc_challenge': 'P-384'}} 126renv = realm.special_env('ochal', True, krb5_conf=rconf) 127realm.stop_kdc() 128realm.start_kdc(env=renv) 129msgs = ('Sending unauthenticated request', 130 '/Additional pre-authentication required', 131 'Selected etype info:', 132 'SPAKE challenge with group 3 rejected', 133 'Sending SPAKE support message', 134 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 135 '/More preauthentication data is required', 136 'Continuing preauth mech PA-SPAKE (151)', 137 'SPAKE challenge received with group 1', 138 'Sending SPAKE response', 139 'for next request: PA-FX-COOKIE (133), PA-SPAKE (151)', 140 'AS key determined by preauth:', 141 'Decrypted AS reply') 142realm.kinit('user', 'pw', expected_trace=msgs) 143 144# Check that the auth indicator for SPAKE is properly included by the KDC. 145mark('auth indicator') 146realm.run([kvno, realm.host_princ]) 147realm.run(['./adata', realm.host_princ], expected_msg='+97: [indspake]') 148 149success('SPAKE pre-authentication tests') 150