xref: /freebsd/crypto/krb5/src/tests/t_spake.py (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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