blob: 19e3f8000d9db945fa9a8c3bde56d16702cd5d46 [file] [log] [blame]
Chetan Gaonkercfcce782016-05-10 10:10:42 -07001#
2# Copyright 2016-present Ciena Corporation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15#
A R Karthicka2e53d62016-02-19 17:38:30 -080016import sys, os
A R Karthicka2e53d62016-02-19 17:38:30 -080017from EapolAAA import *
18from enum import *
19import noseTlsAuthHolder as tlsAuthHolder
20from scapy_ssl_tls.ssl_tls import *
21from socket import *
22from struct import *
23import scapy
24from nose.tools import *
25from CordTestBase import CordTester
Chetan Gaonker4a25e2b2016-03-04 14:45:15 -080026import re
Chetan Gaonker5b366302016-03-21 16:18:21 -070027log.setLevel('INFO')
A R Karthicka2e53d62016-02-19 17:38:30 -080028class TLSAuthTest(EapolPacket, CordTester):
29
30 tlsStateTable = Enumeration("TLSStateTable", ("ST_EAP_SETUP",
31 "ST_EAP_START",
32 "ST_EAP_ID_REQ",
33 "ST_EAP_TLS_HELLO_REQ",
34 "ST_EAP_TLS_CERT_REQ",
Chetan Gaonkerf8f77182016-03-11 15:34:57 -080035 "ST_EAP_TLS_CHANGE_CIPHER_SPEC",
36 "ST_EAP_TLS_FINISHED",
A R Karthicka2e53d62016-02-19 17:38:30 -080037 "ST_EAP_TLS_DONE"
38 )
39 )
40 tlsEventTable = Enumeration("TLSEventTable", ("EVT_EAP_SETUP",
41 "EVT_EAP_START",
42 "EVT_EAP_ID_REQ",
43 "EVT_EAP_TLS_HELLO_REQ",
44 "EVT_EAP_TLS_CERT_REQ",
Chetan Gaonkerf8f77182016-03-11 15:34:57 -080045 "EVT_EAP_TLS_CHANGE_CIPHER_SPEC",
46 "EVT_EAP_TLS_FINISHED",
A R Karthicka2e53d62016-02-19 17:38:30 -080047 "EVT_EAP_TLS_DONE"
48 )
49 )
50 def __init__(self, intf = 'veth0'):
51 self.fsmTable = tlsAuthHolder.initTlsAuthHolderFsmTable(self, self.tlsStateTable, self.tlsEventTable)
52 EapolPacket.__init__(self, intf)
53 CordTester.__init__(self, self.fsmTable, self.tlsStateTable.ST_EAP_TLS_DONE)
54 #self.tlsStateTable, self.tlsEventTable)
55 self.currentState = self.tlsStateTable.ST_EAP_SETUP
56 self.currentEvent = self.tlsEventTable.EVT_EAP_SETUP
57 self.nextState = None
58 self.nextEvent = None
59
60 def _eapSetup(self):
A R Karthicka2e53d62016-02-19 17:38:30 -080061 self.setup()
62 self.nextEvent = self.tlsEventTable.EVT_EAP_START
63
64 def _eapStart(self):
A R Karthicka2e53d62016-02-19 17:38:30 -080065 self.eapol_start()
66 self.nextEvent = self.tlsEventTable.EVT_EAP_ID_REQ
67
68 def _eapIdReq(self):
Chetan Gaonker5b366302016-03-21 16:18:21 -070069 log.info( 'Inside EAP ID Req' )
70 def eapol_cb(pkt):
71 log.info('Got EAPOL packet with type id and code request')
72 log.info('Packet code: %d, type: %d, id: %d', pkt[EAP].code, pkt[EAP].type, pkt[EAP].id)
73 log.info("<====== Send EAP Response with identity = %s ================>" % USER)
74 self.eapol_id_req(pkt[EAP].id, USER)
75
76 self.eapol_scapy_recv(cb = eapol_cb,
77 lfilter = lambda pkt: pkt[EAP].type == EAP.TYPE_ID and pkt[EAP].code == EAP.REQUEST)
A R Karthicka2e53d62016-02-19 17:38:30 -080078 self.nextEvent = self.tlsEventTable.EVT_EAP_TLS_HELLO_REQ
79
80 def _eapTlsHelloReq(self):
Chetan Gaonker5b366302016-03-21 16:18:21 -070081
82 def eapol_cb(pkt):
83 log.info('Got hello request for id %d', pkt[EAP].id)
84 reqdata = TLSRecord(version="TLS_1_0")/TLSHandshake()/TLSClientHello(version="TLS_1_0",
A R Karthicka2e53d62016-02-19 17:38:30 -080085 gmt_unix_time=1234,
86 random_bytes="A" * 28,
87 session_id='',
88 compression_methods=(TLSCompressionMethod.NULL),
89 cipher_suites=[TLSCipherSuite.RSA_WITH_AES_128_CBC_SHA]
90 )
91
Chetan Gaonker5b366302016-03-21 16:18:21 -070092 #reqdata.show()
93 log.debug("Sending Client Hello TLS payload of len %d, id %d" %(len(reqdata),pkt[EAP].id))
94 eap_payload = self.eapTLS(EAP_RESPONSE, pkt[EAP].id, TLS_LENGTH_INCLUDED, str(reqdata))
95 self.eapol_send(EAPOL_EAPPACKET, eap_payload)
96
97 self.eapol_scapy_recv(cb = eapol_cb,
98 lfilter = lambda pkt: pkt[EAP].type == EAP_TYPE_TLS and pkt[EAP].code == EAP.REQUEST)
A R Karthicka2e53d62016-02-19 17:38:30 -080099 self.nextEvent = self.tlsEventTable.EVT_EAP_TLS_CERT_REQ
100
101 def _eapTlsCertReq(self):
Chetan Gaonker5b366302016-03-21 16:18:21 -0700102
103 def eapol_cb(pkt):
104 log.info('Got cert request')
105 rex_pem = re.compile(r'\-+BEGIN[^\-]+\-+(.*?)\-+END[^\-]+\-+', re.DOTALL)
106 self.pem_cert = """-----BEGIN CERTIFICATE-----
Chetan Gaonkerf8f77182016-03-11 15:34:57 -0800107MIIDvTCCAqWgAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBizELMAkGA1UEBhMCVVMx
108CzAJBgNVBAgTAkNBMRIwEAYDVQQHEwlTb21ld2hlcmUxEzARBgNVBAoTCkNpZW5h
109IEluYy4xHjAcBgkqhkiG9w0BCQEWD2FkbWluQGNpZW5hLmNvbTEmMCQGA1UEAxMd
110RXhhbXBsZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTYwMzExMTg1MzM2WhcN
111MTcwMzA2MTg1MzM2WjBnMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExEzARBgNV
112BAoTCkNpZW5hIEluYy4xFzAVBgNVBAMUDnVzZXJAY2llbmEuY29tMR0wGwYJKoZI
113hvcNAQkBFg51c2VyQGNpZW5hLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
114AQoCggEBAOxemcBsPn9tZsCa5o2JA6sQDC7A6JgCNXXl2VFzKLNNvB9PS6D7ZBsQ
1155An0zEDMNzi51q7lnrYg1XyiE4S8FzMGAFr94RlGMQJUbRD9V/oqszMX4k++iAOK
116tIA1gr3x7Zi+0tkjVSVzXTmgNnhChAamdMsjYUG5+CY9WAicXyy+VEV3zTphZZDR
117OjcjEp4m/TSXVPYPgYDXI40YZKX5BdvqykWtT/tIgZb48RS1NPyN/XkCYzl3bv21
118qx7Mc0fcEbsJBIIRYTUkfxnsilcnmLxSYO+p+DZ9uBLBzcQt+4Rd5pLSfi21WM39
1192Z2oOi3vs/OYAPAqgmi2JWOv3mePa/8CAwEAAaNPME0wEwYDVR0lBAwwCgYIKwYB
120BQUHAwIwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL3d3dy5leGFtcGxlLmNvbS9l
121eGFtcGxlX2NhLmNybDANBgkqhkiG9w0BAQUFAAOCAQEALBzMPDTIB6sLyPl0T6JV
122MjOkyldAVhXWiQsTjaGQGJUUe1cmUJyZbUZEc13MygXMPOM4x7z6VpXGuq1c/Vxn
123VzQ2fNnbJcIAHi/7G8W5/SQfPesIVDsHTEc4ZspPi5jlS/MVX3HOC+BDbOjdbwqP
124RX0JEr+uOyhjO+lRxG8ilMRACoBUbw1eDuVDoEBgErSUC44pq5ioDw2xelc+Y6hQ
125dmtYwfY0DbvwxHtA495frLyPcastDiT/zre7NL51MyUDPjjYjghNQEwvu66IKbQ3
126T1tJBrgI7/WI+dqhKBFolKGKTDWIHsZXQvZ1snGu/FRYzg1l+R/jT8cRB9BDwhUt
127yg==
Chetan Gaonker4a25e2b2016-03-04 14:45:15 -0800128-----END CERTIFICATE-----"""
Chetan Gaonker5b366302016-03-21 16:18:21 -0700129 self.der_cert = rex_pem.findall(self.pem_cert)[0].decode("base64")
130 reqdata = TLSRecord(version="TLS_1_0")/TLSHandshake()/TLSCertificateList(
131 certificates=[TLSCertificate(data=x509.X509Cert(self.der_cert))])
132 #reqdata.show()
133 log.info("------> Sending Client Hello TLS Certificate payload of len %d ----------->" %len(reqdata))
134 eap_payload = self.eapTLS(EAP_RESPONSE, pkt[EAP].id, TLS_LENGTH_INCLUDED, str(reqdata))
135 self.eapol_send(EAPOL_EAPPACKET, eap_payload)
136
137 self.eapol_scapy_recv(cb = eapol_cb,
138 lfilter = lambda pkt: pkt[EAP].type == EAP_TYPE_TLS and pkt[EAP].code == EAP.REQUEST)
Chetan Gaonkerf8f77182016-03-11 15:34:57 -0800139 self.nextEvent = self.tlsEventTable.EVT_EAP_TLS_CHANGE_CIPHER_SPEC
140
141 def _eapTlsChangeCipherSpec(self):
Chetan Gaonker5b366302016-03-21 16:18:21 -0700142 def eapol_cb(pkt):
143 log.info('Got change cipher request')
144 reqdata = TLSFinished(data="")
145 eap_payload = self.eapTLS(EAP_RESPONSE, pkt[EAP].id, TLS_LENGTH_INCLUDED, str(reqdata))
146 self.eapol_send(EAPOL_EAPPACKET, eap_payload)
147
148 self.eapol_scapy_recv(cb = eapol_cb,
149 lfilter = lambda pkt: pkt[EAP].type == EAP_TYPE_TLS and pkt[EAP].code == EAP.REQUEST)
Chetan Gaonkerf8f77182016-03-11 15:34:57 -0800150 self.nextEvent = self.tlsEventTable.EVT_EAP_TLS_FINISHED
151
152 def _eapTlsFinished(self):
Chetan Gaonker5b366302016-03-21 16:18:21 -0700153 def eapol_cb(pkt):
154 log.info('Got tls finished request')
155
156 self.eapol_scapy_recv(cb = eapol_cb,
157 lfilter = lambda pkt: pkt[EAP].type == EAP_TYPE_TLS and pkt[EAP].code == EAP.REQUEST)
Chetan Gaonkerf8f77182016-03-11 15:34:57 -0800158 #We stop here as certification validation success implies auth success
A R Karthicka2e53d62016-02-19 17:38:30 -0800159 self.nextEvent = None