Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

无法连接wpa2企业加密ESP-TLS (IDFGH-3779) #5698

Closed
kaedewang opened this issue Aug 5, 2020 · 22 comments
Closed

无法连接wpa2企业加密ESP-TLS (IDFGH-3779) #5698

kaedewang opened this issue Aug 5, 2020 · 22 comments

Comments

@kaedewang
Copy link

Environment

  • Development Kit: ESP32-DevKitC
  • Module or chip used: ESP32-WROOM-32D
  • IDF version (run git describe --tags to find it):
    // v4.3-dev-771-gc77c4ccf6
  • Build System: idf.py
  • Compiler version (run xtensa-esp32-elf-gcc --version to find it):
    // xtensa-esp32-elf-gcc (crosstool-NG esp-2020r2) 8.2.0
  • Operating System: wsl
  • Using an IDE?: No
  • Power Supply: USB

Problem Description

ESP32使用wpa2_enterprise例程,无法连接wpa2企业加密EAP-TLS,电脑和手机连接无问题
路由器使用ASUSwrt merlin,安装本地FreeRADIUS Version 3.0.21
根据其他issue
ESP32设置了
config EXAMPLE_VALIDATE_SERVER_CERT=n
config WPA_MBEDTLS_CRYPTO=n

FreeRADIUS设置了
disable_tlsv1_2 = no
disable_tlsv1_1 = yes
disable_tlsv1 = yes
tls_min_version = "1.2"
tls_max_version = "1.2"

FreeRADIUS Debug信息如下
(0) Received Access-Request Id 106 from 127.0.0.1:48424 to 127.0.0.1:1812 length 233
(0) User-Name = "[email protected]"
(0) NAS-IP-Address = 127.0.0.1
(0) Called-Station-Id = "D4-5D-64-4D-7B-C8:ASUS"
(0) NAS-Port-Type = Wireless-802.11
(0) Service-Type = Framed-User
(0) Calling-Station-Id = "C8-2B-96-B8-6A-DC"
(0) Connect-Info = "CONNECT 0Mbps 802.11g"
(0) Acct-Session-Id = "AA3CF7806C39EB64"
(0) Acct-Multi-Session-Id = "0ABFDC1446AD11C1"
(0) Attr-186 = 0x000fac04
(0) Attr-187 = 0x000fac04
(0) Attr-188 = 0x000fac01
(0) Framed-MTU = 1400
(0) EAP-Message = 0x02af001a016578616d706c65406573707265737369662e636f6d
(0) Message-Authenticator = 0x032d3ecaee12ccb4bfe5826034ada2bc
(0) # Executing section authorize from file /opt/etc/freeradius3/sites-enabled/default
(0) authorize {
(0) policy filter_username {
(0) if (&User-Name) {
(0) if (&User-Name) -> TRUE
(0) if (&User-Name) {
(0) if (&User-Name =~ / /) {
(0) if (&User-Name =~ / /) -> FALSE
(0) if (&User-Name =~ /@[^@]@/ ) {
(0) if (&User-Name =~ /@[^@]
@/ ) -> FALSE
(0) if (&User-Name =~ /../ ) {
(0) if (&User-Name =~ /../ ) -> FALSE
(0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) {
(0) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) -> FALSE
(0) if (&User-Name =~ /.$/) {
(0) if (&User-Name =~ /.$/) -> FALSE
(0) if (&User-Name =~ /@./) {
(0) if (&User-Name =~ /@./) -> FALSE
(0) } # if (&User-Name) = notfound
(0) } # policy filter_username = notfound
(0) [preprocess] = ok
(0) [chap] = noop
(0) [mschap] = noop
(0) [digest] = noop
(0) suffix: Checking for suffix after "@"
(0) suffix: Looking up realm "espressif.com" for User-Name = "[email protected]"
(0) suffix: No such realm "espressif.com"
(0) [suffix] = noop
(0) eap: Peer sent EAP Response (code 2) ID 175 length 26
(0) eap: EAP-Identity reply, returning 'ok' so we can short-circuit the rest of authorize
(0) [eap] = ok
(0) } # authorize = ok
(0) Found Auth-Type = eap
(0) # Executing group from file /opt/etc/freeradius3/sites-enabled/default
(0) authenticate {
(0) eap: Peer sent packet with method EAP Identity (1)
(0) eap: Calling submodule eap_tls to process data
(0) eap_tls: Initiating new TLS session
(0) eap_tls: Setting verify mode to require certificate from client
(0) eap_tls: [eaptls start] = request
(0) eap: Sending EAP Request (code 1) ID 176 length 6
(0) eap: EAP session adding &reply:State = 0xc607166ac6b71b6d
(0) [eap] = handled
(0) } # authenticate = handled
(0) Using Post-Auth-Type Challenge
(0) # Executing group from file /opt/etc/freeradius3/sites-enabled/default
(0) Challenge { ... } # empty sub-section is ignored
(0) Sent Access-Challenge Id 106 from 127.0.0.1:1812 to 127.0.0.1:48424 length 0
(0) EAP-Message = 0x01b000060d20
(0) Message-Authenticator = 0x00000000000000000000000000000000
(0) State = 0xc607166ac6b71b6dda08a4b72dd608fd
(0) Finished request
Waking up in 4.9 seconds.
(1) Received Access-Request Id 107 from 127.0.0.1:48424 to 127.0.0.1:1812 length 233
(1) User-Name = "[email protected]"
(1) NAS-IP-Address = 127.0.0.1
(1) Called-Station-Id = "D4-5D-64-4D-7B-C8:ASUS"
(1) NAS-Port-Type = Wireless-802.11
(1) Service-Type = Framed-User
(1) Calling-Station-Id = "C8-2B-96-B8-6A-DC"
(1) Connect-Info = "CONNECT 0Mbps 802.11g"
(1) Acct-Session-Id = "AA3CF7806C39EB64"
(1) Acct-Multi-Session-Id = "0ABFDC1446AD11C1"
(1) Attr-186 = 0x000fac04
(1) Attr-187 = 0x000fac04
(1) Attr-188 = 0x000fac01
(1) Framed-MTU = 1400
(1) EAP-Message = 0x02b00008030d1915
(1) State = 0xc607166ac6b71b6dda08a4b72dd608fd
(1) Message-Authenticator = 0x3ec65b164aa3513125bb08ad57020896
(1) session-state: No cached attributes
(1) # Executing section authorize from file /opt/etc/freeradius3/sites-enabled/default
(1) authorize {
(1) policy filter_username {
(1) if (&User-Name) {
(1) if (&User-Name) -> TRUE
(1) if (&User-Name) {
(1) if (&User-Name =~ / /) {
(1) if (&User-Name =~ / /) -> FALSE
(1) if (&User-Name =~ /@[^@]@/ ) {
(1) if (&User-Name =~ /@[^@]
@/ ) -> FALSE
(1) if (&User-Name =~ /../ ) {
(1) if (&User-Name =~ /../ ) -> FALSE
(1) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) {
(1) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) -> FALSE
(1) if (&User-Name =~ /.$/) {
(1) if (&User-Name =~ /.$/) -> FALSE
(1) if (&User-Name =~ /@./) {
(1) if (&User-Name =~ /@./) -> FALSE
(1) } # if (&User-Name) = notfound
(1) } # policy filter_username = notfound
(1) [preprocess] = ok
(1) [chap] = noop
(1) [mschap] = noop
(1) [digest] = noop
(1) suffix: Checking for suffix after "@"
(1) suffix: Looking up realm "espressif.com" for User-Name = "[email protected]"
(1) suffix: No such realm "espressif.com"
(1) [suffix] = noop
(1) eap: Peer sent EAP Response (code 2) ID 176 length 8
(1) eap: No EAP Start, assuming it's an on-going EAP conversation
(1) [eap] = updated

(1) [files] = noop
(1) [expiration] = noop
(1) [logintime] = noop
Not doing PAP as Auth-Type is already set.
(1) [pap] = noop
(1) } # authorize = updated
(1) Found Auth-Type = eap
(1) # Executing group from file /opt/etc/freeradius3/sites-enabled/default
(1) authenticate {
(1) eap: Expiring EAP session with state 0xc607166ac6b71b6d

(1) eap: Finished EAP session with state 0xc607166ac6b71b6d
(1) eap: Previous EAP request found for state 0xc607166ac6b71b6d, released from the list
(1) eap: Peer sent packet with method EAP NAK (3)
(1) eap: Peer NAK'd our request for TLS (13) with a request for TLS (13), skipping...
(1) eap: WARNING: !!! We requested to use an EAP type as normal.
(1) eap: WARNING: !!! The supplicant rejected that, and requested to use the same EAP type.
(1) eap: WARNING: !!! i.e. the supplicant said 'I don't like X, please use X instead.
(1) eap: WARNING: !!! The supplicant software is broken and does not work properly.
(1) eap: WARNING: !!! Please upgrade it to software that works.
(1) eap: Found mutually acceptable type PEAP (25)
(1) eap: Calling submodule eap_peap to process data
(1) eap_peap: Initiating new TLS session

(1) eap_peap: [eaptls start] = request
(1) eap: Sending EAP Request (code 1) ID 177 length 6
(1) eap: EAP session adding &reply:State = 0xc607166ac7b60f6d
(1) [eap] = handled
(1) } # authenticate = handled
(1) Using Post-Auth-Type Challenge
(1) # Executing group from file /opt/etc/freeradius3/sites-enabled/default
(1) Challenge { ... } # empty sub-section is ignored
(1) Sent Access-Challenge Id 107 from 127.0.0.1:1812 to 127.0.0.1:48424 length 0

(1) EAP-Message = 0x01b100061920
(1) Message-Authenticator = 0x00000000000000000000000000000000
(1) State = 0xc607166ac7b60f6dda08a4b72dd608fd
(1) Finished request
Waking up in 4.9 seconds.
(2) Received Access-Request Id 108 from 127.0.0.1:48424 to 127.0.0.1:1812 length 233
(2) User-Name = "[email protected]"
(2) NAS-IP-Address = 127.0.0.1
(2) Called-Station-Id = "D4-5D-64-4D-7B-C8:ASUS"
(2) NAS-Port-Type = Wireless-802.11
(2) Service-Type = Framed-User
(2) Calling-Station-Id = "C8-2B-96-B8-6A-DC"
(2) Connect-Info = "CONNECT 0Mbps 802.11g"
(2) Acct-Session-Id = "AA3CF7806C39EB64"
(2) Acct-Multi-Session-Id = "0ABFDC1446AD11C1"
(2) Attr-186 = 0x000fac04
(2) Attr-187 = 0x000fac04
(2) Attr-188 = 0x000fac01
(2) Framed-MTU = 1400
(2) EAP-Message = 0x02b10008030d1915
(2) State = 0xc607166ac7b60f6dda08a4b72dd608fd
(2) Message-Authenticator = 0x18d0d4bce15988cc7a95cbb1cc1d7693
(2) session-state: No cached attributes
(2) # Executing section authorize from file /opt/etc/freeradius3/sites-enabled/default
(2) authorize {
(2) policy filter_username {
(2) if (&User-Name) {
(2) if (&User-Name) -> TRUE
(2) if (&User-Name) {
(2) if (&User-Name =~ / /) {
(2) if (&User-Name =~ / /) -> FALSE
(2) if (&User-Name =~ /@[^@]@/ ) {
(2) if (&User-Name =~ /@[^@]
@/ ) -> FALSE
(2) if (&User-Name =~ /../ ) {
(2) if (&User-Name =~ /../ ) -> FALSE
(2) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) {
(2) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) -> FALSE
(2) if (&User-Name =~ /.$/) {
(2) if (&User-Name =~ /.$/) -> FALSE
(2) if (&User-Name =~ /@./) {
(2) if (&User-Name =~ /@./) -> FALSE
(2) } # if (&User-Name) = notfound
(2) } # policy filter_username = notfound
(2) [preprocess] = ok
(2) [chap] = noop
(2) [mschap] = noop
(2) [digest] = noop
(2) suffix: Checking for suffix after "@"
(2) suffix: Looking up realm "espressif.com" for User-Name = "[email protected]"
(2) suffix: No such realm "espressif.com"
(2) [suffix] = noop
(2) eap: Peer sent EAP Response (code 2) ID 177 length 8
(2) eap: No EAP Start, assuming it's an on-going EAP conversation
(2) [eap] = updated

(2) [files] = noop
(2) [expiration] = noop
(2) [logintime] = noop
Not doing PAP as Auth-Type is already set.
(2) [pap] = noop
(2) } # authorize = updated
(2) Found Auth-Type = eap
(2) # Executing group from file /opt/etc/freeradius3/sites-enabled/default
(2) authenticate {
(2) eap: Expiring EAP session with state 0xc607166ac7b60f6d
(2) eap: Finished EAP session with state 0xc607166ac7b60f6d
(2) eap: Previous EAP request found for state 0xc607166ac7b60f6d, released from the list
(2) eap: Peer sent packet with method EAP NAK (3)
(2) eap: Found mutually acceptable type TLS (13)
(2) eap: Calling submodule eap_tls to process data
(2) eap_tls: Initiating new TLS session
(2) eap_tls: Setting verify mode to require certificate from client

(2) eap_tls: [eaptls start] = request
(2) eap: Sending EAP Request (code 1) ID 178 length 6
(2) eap: EAP session adding &reply:State = 0xc607166ac4b51b6d
(2) [eap] = handled
(2) } # authenticate = handled
(2) Using Post-Auth-Type Challenge
(2) # Executing group from file /opt/etc/freeradius3/sites-enabled/default
(2) Challenge { ... } # empty sub-section is ignored
(2) Sent Access-Challenge Id 108 from 127.0.0.1:1812 to 127.0.0.1:48424 length 0

(2) EAP-Message = 0x01b200060d20
(2) Message-Authenticator = 0x00000000000000000000000000000000
(2) State = 0xc607166ac4b51b6dda08a4b72dd608fd
(2) Finished request
Waking up in 4.9 seconds.
(3) Received Access-Request Id 109 from 127.0.0.1:48424 to 127.0.0.1:1812 length 233
(3) User-Name = "[email protected]"
(3) NAS-IP-Address = 127.0.0.1
(3) Called-Station-Id = "D4-5D-64-4D-7B-C8:ASUS"
(3) NAS-Port-Type = Wireless-802.11
(3) Service-Type = Framed-User
(3) Calling-Station-Id = "C8-2B-96-B8-6A-DC"
(3) Connect-Info = "CONNECT 0Mbps 802.11g"
(3) Acct-Session-Id = "AA3CF7806C39EB64"
(3) Acct-Multi-Session-Id = "0ABFDC1446AD11C1"
(3) Attr-186 = 0x000fac04
(3) Attr-187 = 0x000fac04
(3) Attr-188 = 0x000fac01
(3) Framed-MTU = 1400
(3) EAP-Message = 0x02b20008030d1915
(3) State = 0xc607166ac4b51b6dda08a4b72dd608fd
(3) Message-Authenticator = 0xa9f191297d509a6b9534d9868bb936e0
(3) session-state: No cached attributes
(3) # Executing section authorize from file /opt/etc/freeradius3/sites-enabled/default
(3) authorize {
(3) policy filter_username {
(3) if (&User-Name) {
(3) if (&User-Name) -> TRUE
(3) if (&User-Name) {
(3) if (&User-Name =~ / /) {
(3) if (&User-Name =~ / /) -> FALSE
(3) if (&User-Name =~ /@[^@]@/ ) {
(3) if (&User-Name =~ /@[^@]
@/ ) -> FALSE
(3) if (&User-Name =~ /../ ) {
(3) if (&User-Name =~ /../ ) -> FALSE
(3) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) {
(3) if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+).(.+)$/)) -> FALSE
(3) if (&User-Name =~ /.$/) {
(3) if (&User-Name =~ /.$/) -> FALSE
(3) if (&User-Name =~ /@./) {
(3) if (&User-Name =~ /@./) -> FALSE
(3) } # if (&User-Name) = notfound
(3) } # policy filter_username = notfound
(3) [preprocess] = ok
(3) [chap] = noop
(3) [mschap] = noop
(3) [digest] = noop
(3) suffix: Checking for suffix after "@"
(3) suffix: Looking up realm "espressif.com" for User-Name = "[email protected]"
(3) suffix: No such realm "espressif.com"
(3) [suffix] = noop
(3) eap: Peer sent EAP Response (code 2) ID 178 length 8
(3) eap: No EAP Start, assuming it's an on-going EAP conversation
(3) [eap] = updated

(3) [files] = noop
(3) [expiration] = noop
(3) [logintime] = noop
Not doing PAP as Auth-Type is already set.
(3) [pap] = noop
(3) } # authorize = updated
(3) Found Auth-Type = eap
(3) # Executing group from file /opt/etc/freeradius3/sites-enabled/default
(3) authenticate {
(3) eap: Expiring EAP session with state 0xc607166ac4b51b6d
(3) eap: Finished EAP session with state 0xc607166ac4b51b6d
(3) eap: Previous EAP request found for state 0xc607166ac4b51b6d, released from the list
(3) eap: Peer sent packet with method EAP NAK (3)
(3) eap: Peer NAK'd our request for TLS (13) with a request for TLS (13), skipping...
(3) eap: WARNING: !!! We requested to use an EAP type as normal.
(3) eap: WARNING: !!! The supplicant rejected that, and requested to use the same EAP type.
(3) eap: WARNING: !!! i.e. the supplicant said 'I don't like X, please use X instead.
(3) eap: WARNING: !!! The supplicant software is broken and does not work properly.
(3) eap: WARNING: !!! Please upgrade it to software that works.

(3) eap: Found mutually acceptable type PEAP (25)
(3) eap: Calling submodule eap_peap to process data
(3) eap_peap: Initiating new TLS session

@github-actions github-actions bot changed the title 无法连接wpa2企业加密ESP-TLS 无法连接wpa2企业加密ESP-TLS (IDFGH-3779) Aug 5, 2020
@sagb2015
Copy link
Contributor

@kaedewang - Can you help us with the default EAP method set on Freeradius side, typically available in mods_available/eap file? Also what is the value of EAP_METHOD on esp32 in menuconfig?

@Alvin1Zhang
Copy link
Collaborator

@kaedewang Thanks for reporting, would you please help share if any updates per the questions by @sagb2015 ? Thanks.

@kaedewang
Copy link
Author

@sagb2015 @Alvin1Zhang
ESP32 EAP method:TLS
EAP setting is almost default.
Only change
default_eap_type = tls
private_key_file = ${certdir}/server.key
certificate_file = ${certdir}/server.pem
disable_tlsv1_2 = no
disable_tlsv1_1 = yes
disable_tlsv1 = yes
tls_min_version = "1.2"
tls_max_version = "1.2"
And delete other unused EAP method

eap {
# Invoke the default supported EAP type when
# EAP-Identity response is received.
#
# The incoming EAP messages DO NOT specify which EAP
# type they will be using, so it MUST be set here.
#
# For now, only one default EAP type may be used at a time.
#
# If the EAP-Type attribute is set by another module,
# then that EAP type takes precedence over the
# default type configured here.
#
default_eap_type = tls

    #  A list is maintained to correlate EAP-Response
    #  packets with EAP-Request packets.  After a
    #  configurable length of time, entries in the list
    #  expire, and are deleted.
    #
    timer_expire = 60

    #  There are many EAP types, but the server has support
    #  for only a limited subset.  If the server receives
    #  a request for an EAP type it does not support, then
    #  it normally rejects the request.  By setting this
    #  configuration to "yes", you can tell the server to
    #  instead keep processing the request.  Another module
    #  MUST then be configured to proxy the request to
    #  another RADIUS server which supports that EAP type.
    #
    #  If another module is NOT configured to handle the
    #  request, then the request will still end up being
    #  rejected.
    #
    ignore_unknown_eap_types = no

    # Cisco AP1230B firmware 12.2(13)JA1 has a bug.  When given
    # a User-Name attribute in an Access-Accept, it copies one
    # more byte than it should.
    #
    # We can work around it by configurably adding an extra
    # zero byte.
    #
    cisco_accounting_username_bug = no

    #  Help prevent DoS attacks by limiting the number of
    #  sessions that the server is tracking.  For simplicity,
    #  this is taken from the "max_requests" directive in
    #  radiusd.conf.
    #
    max_sessions = ${max_requests}


    ############################################################
    #
    #  Supported EAP-types
    #


    #  Common TLS configuration for TLS-based EAP types
    #  ------------------------------------------------
    #
    #  See raddb/certs/README for additional comments
    #  on certificates.
    #
    #  If OpenSSL was not found at the time the server was
    #  built, the "tls", "ttls", and "peap" sections will
    #  be ignored.
    #
    #  If you do not currently have certificates signed by
    #  a trusted CA you may use the 'snakeoil' certificates.
    #  Included with the server in raddb/certs.
    #
    #  If these certificates have not been auto-generated:
    #    cd raddb/certs
    #    make
    #
    #  These test certificates SHOULD NOT be used in a normal
    #  deployment.  They are created only to make it easier
    #  to install the server, and to perform some simple
    #  tests with EAP-TLS, TTLS, or PEAP.
    #
    #  Note that you should NOT use a globally known CA here!
    #  e.g. using a Verisign cert as a "known CA" means that
    #  ANYONE who has a certificate signed by them can
    #  authenticate via EAP-TLS!  This is likely not what you want.
    #
    tls-config tls-common {
            private_key_password = whatever
            private_key_file = ${certdir}/server.key

            #  If Private key & Certificate are located in
            #  the same file, then private_key_file &
            #  certificate_file must contain the same file
            #  name.
            #
            #  If ca_file (below) is not used, then the
            #  certificate_file below SHOULD also include all of
            #  the intermediate CA certificates used to sign the
            #  server certificate, but NOT the root CA.
            #
            #  Including the ROOT CA certificate is not useful and
            #  merely inflates the exchanged data volume during
            #  the TLS negotiation.
            #
            #  This file should contain the server certificate,
            #  followed by intermediate certificates, in order.
            #  i.e. If we have a server certificate signed by CA1,
            #  which is signed by CA2, which is signed by a root
            #  CA, then the "certificate_file" should contain
            #  server.pem, followed by CA1.pem, followed by
            #  CA2.pem.
            #
            #  When using "ca_file" or "ca_dir", the
            #  "certificate_file" should contain only
            #  "server.pem".  And then you may (or may not) need
            #  to set "auto_chain", depending on your version of
            #  OpenSSL.
            #
            #  In short, SSL / TLS certificates are complex.
            #  There are many versions of software, each of which
            #  behave slightly differently.  It is impossible to
            #  give advice which will work everywhere.  Instead,
            #  we give general guidelines.
            #
            certificate_file = ${certdir}/server.pem

            #  Trusted Root CA list
            #
            #  This file can contain multiple CA certificates.
            #  ALL of the CA's in this list will be trusted to
            #  issue client certificates for authentication.
            #
            #  In general, you should use self-signed
            #  certificates for 802.1x (EAP) authentication.
            #  In that case, this CA file should contain
            #  *one* CA certificate.
            #
            ca_file = ${cadir}/ca.pem

            #  OpenSSL will automatically create certificate chains,
            #  unless we tell it to not do that.  The problem is that
            #  it sometimes gets the chains right from a certificate
            #  signature view, but wrong from the clients view.
            #
            #  When setting "auto_chain = no", the server certificate
            #  file MUST include the full certificate chain.
            #
    #       auto_chain = yes

            #  If OpenSSL supports TLS-PSK, then we can use a
            #  fixed PSK identity and (hex) password.  As of
            #  3.0.18, these can be used at the same time as the
            #  certificate configuration, but only for TLS 1.0
            #  through 1.2.
            #
            #  If PSK and certificates are configured at the same
            #  time for TLS 1.3, then the server will warn you,
            #  and will disable TLS 1.3, as it will not work.
            #
            #  The work around is to have two modules (or for
            #  RadSec, two listen sections).  One will have PSK
            #  configured, and the other will have certificates
            #  configured.
            #
    #       psk_identity = "test"
    #       psk_hexphrase = "036363823"

            #  Dynamic queries for the PSK.  If TLS-PSK is used,
            #  and psk_query is set, then you MUST NOT use
            #  psk_identity or psk_hexphrase.
            #
            #  Instead, use a dynamic expansion similar to the one
            #  below.  It keys off of TLS-PSK-Identity.  It should
            #  return a of string no more than 512 hex characters.
            #  That string will be converted to binary, and will
            #  be used as the dynamic PSK hexphrase.
            #
            #  Note that this query is just an example.  You will
            #  need to customize it for your installation.
            #
    #       psk_query = "%{sql:select hex(key) from psk_keys where keyid = '%{TLS-PSK-Identity}'}"

            #  For DH cipher suites to work, you have to
            #  run OpenSSL to create the DH file first:
            #
            #    openssl dhparam -out certs/dh 2048
            #
            dh_file = ${certdir}/dh

            #  If your system doesn't have /dev/urandom,
            #  you will need to create this file, and
            #  periodically change its contents.
            #
            #  For security reasons, FreeRADIUS doesn't
            #  write to files in its configuration
            #  directory.
            #
    #       random_file = /dev/urandom

            #  This can never exceed the size of a RADIUS
            #  packet (4096 bytes), and is preferably half
            #  that, to accommodate other attributes in
            #  RADIUS packet.  On most APs the MAX packet
            #  length is configured between 1500 - 1600
            #  In these cases, fragment size should be
            #  1024 or less.
            #
    #       fragment_size = 1024

            #  include_length is a flag which is
            #  by default set to yes If set to
            #  yes, Total Length of the message is
            #  included in EVERY packet we send.
            #  If set to no, Total Length of the
            #  message is included ONLY in the
            #  First packet of a fragment series.
            #
    #       include_length = yes


            #  Check the Certificate Revocation List
            #
            #  1) Copy CA certificates and CRLs to same directory.
            #  2) Execute 'c_rehash <CA certs&CRLs Directory>'.
            #     'c_rehash' is OpenSSL's command.
            #  3) uncomment the lines below.
            #  5) Restart radiusd
    #       check_crl = yes

            # Check if intermediate CAs have been revoked.
    #       check_all_crl = yes

            ca_path = ${cadir}

            # Accept an expired Certificate Revocation List
            #
    #       allow_expired_crl = no

            #  If check_cert_issuer is set, the value will
            #  be checked against the DN of the issuer in
            #  the client certificate.  If the values do not
            #  match, the certificate verification will fail,
            #  rejecting the user.
            #
            #  This check can be done more generally by checking
            #  the value of the TLS-Client-Cert-Issuer attribute.
            #  This check can be done via any mechanism you
            #  choose.
            #
    #       check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd"

            #  If check_cert_cn is set, the value will
            #  be xlat'ed and checked against the CN
            #  in the client certificate.  If the values
            #  do not match, the certificate verification
            #  will fail rejecting the user.
            #
            #  This check is done only if the previous
            #  "check_cert_issuer" is not set, or if
            #  the check succeeds.
            #
            #  In 2.1.10 and later, this check can be done
            #  more generally by checking the value of the
            #  TLS-Client-Cert-Common-Name attribute.  This check
            #  can be done via any mechanism you choose.
            #
    #       check_cert_cn = %{User-Name}

            #  Set this option to specify the allowed
            #  TLS cipher suites.  The format is listed
            #  in "man 1 ciphers".
            #
            #  For EAP-FAST, use "ALL:!EXPORT:!eNULL:!SSLv2"
            #
            cipher_list = "DEFAULT"

            #  If enabled, OpenSSL will use server cipher list
            #  (possibly defined by cipher_list option above)
            #  for choosing right cipher suite rather than
            #  using client-specified list which is OpenSSl default
            #  behavior.  Setting this to "yes" means that OpenSSL
            #  will choose the servers ciphers, even if they do not
            #  best match what the client sends.
            #
            #  TLS negotiation is usually good, but can be imperfect.
            #  This setting allows administrators to "fine tune" it
            #  if necessary.
            #
            cipher_server_preference = no

            #  You can selectively disable TLS versions for
            #  compatability with old client devices.
            #
            #  If your system has OpenSSL 1.1.0 or greater, do NOT
            #  use these.  Instead, set tls_min_version and
            #  tls_max_version.
            #
            disable_tlsv1_2 = no
            disable_tlsv1_1 = yes
            disable_tlsv1 = yes

            #  Set min / max TLS version.  Mainly for Debian
            #  "trusty", which disables older versions of TLS, and
            #  requires the application to manually enable them.
            #
            #  If you are running Debian trusty, you should set
            #  these options, otherwise older clients will not be
            #  able to connect.
            #
            #  Allowed values are "1.0", "1.1", "1.2", and "1.3".
            #
            #  Note that the server WILL NOT permit negotiation of
            #  TLS 1.3.  The EAP-TLS standards for TLS 1.3 are NOT
            #  finished.  It is therefore impossible for the server
            #  to negotiate EAP-TLS correctly with TLS 1.3.
            #
            #  The values must be in quotes.
            #
            tls_min_version = "1.2"
            tls_max_version = "1.2"

            #  Elliptical cryptography configuration
            #
            #  Only for OpenSSL >= 0.9.8.f
            #
            ecdh_curve = "prime256v1"

            #  Session resumption / fast reauthentication
            #  cache.
            #
            #  The cache contains the following information:
            #
            #   session Id - unique identifier, managed by SSL
            #   User-Name  - from the Access-Accept
            #   Stripped-User-Name - from the Access-Request
            #   Cached-Session-Policy - from the Access-Accept
            #
            #  See also the "store" subsection below for
            #  additional attributes which can be cached.
            #
            #  The "Cached-Session-Policy" is the name of a
            #  policy which should be applied to the cached
            #  session.  This policy can be used to assign
            #  VLANs, IP addresses, etc.  It serves as a useful
            #  way to re-apply the policy from the original
            #  Access-Accept to the subsequent Access-Accept
            #  for the cached session.
            #
            #  On session resumption, these attributes are
            #  copied from the cache, and placed into the
            #  reply list.
            #
            #  You probably also want "use_tunneled_reply = yes"
            #  when using fast session resumption.
            #
            #  You can check if a session has been resumed by
            #  looking for the existence of the EAP-Session-Resumed
            #  attribute.  Note that this attribute will *only*
            #  exist in the "post-auth" section.
            #
            #  CAVEATS: The cache is stored and reloaded BEFORE
            #  the "post-auth" section is run.  This limitation
            #  makes caching more difficult than it should be.  In
            #  practice, it means that the first authentication
            #  session must set the reply attributes before the
            #  post-auth section is run.
            #
            #  When the session is resumed, the attributes are
            #  restored and placed into the session-state list.
            #
            cache {
                    #  Enable it.  The default is "no". Deleting the entire "cache"
                    #  subsection also disables caching.
                    #
                    #  As of version 3.0.14, the session cache requires the use
                    #  of the "name" and "persist_dir" configuration items, below.
                    #
                    #  The internal OpenSSL session cache has been permanently
                    #  disabled.
                    #
                    #  You can disallow resumption for a particular user by adding the
                    #  following attribute to the control item list:
                    #
                    #    Allow-Session-Resumption = No
                    #
                    #  If "enable = no" below, you CANNOT enable resumption for just one
                    #  user by setting the above attribute to "yes".
                    #
                    enable = no

                    #  Lifetime of the cached entries, in hours. The sessions will be
                    #  deleted/invalidated after this time.
                    #
                    lifetime = 24 # hours

                    #  Internal "name" of the session cache. Used to
                    #  distinguish which TLS context sessions belong to.
                    #
                    #  The server will generate a random value if unset.
                    #  This will change across server restart so you MUST
                    #  set the "name" if you want to persist sessions (see
                    #  below).
                    #
            #       name = "EAP module"

                    #  Simple directory-based storage of sessions.
                    #  Two files per session will be written, the SSL
                    #  state and the cached VPs. This will persist session
                    #  across server restarts.
                    #
                    #  The default directory is ${logdir}, for historical
                    #  reasons.  You should ${db_dir} instead.  And check
                    #  the value of db_dir in the main radiusd.conf file.
                    #  It should not point to ${raddb}
                    #
                    #  The server will need write perms, and the directory
                    #  should be secured from anyone else. You might want
                    #  a script to remove old files from here periodically:
                    #
                    #    find ${logdir}/tlscache -mtime +2 -exec rm -f {} \;
                    #
                    #  This feature REQUIRES "name" option be set above.
                    #
            #       persist_dir = "${logdir}/tlscache"

                    #
                    #  As of 3.0.20, it is possible to partially
                    #  control which attributes exist in the
                    #  session cache.  This subsection lists
                    #  attributes which are taken from the reply,
                    #  and saved to the on-disk cache.  When the
                    #  session is resumed, these attributes are
                    #  added to the "session-state" list.  The
                    #  default configuration will then take care
                    #  of copying them to the reply.
                    #
                    store {
                            Tunnel-Private-Group-Id
                    }
            }

            #  As of version 2.1.10, client certificates can be
            #  validated via an external command.  This allows
            #  dynamic CRLs or OCSP to be used.
            #
            #  This configuration is commented out in the
            #  default configuration.  Uncomment it, and configure
            #  the correct paths below to enable it.
            #
            #  If OCSP checking is enabled, and the OCSP checks fail,
            #  the verify section is not run.
            #
            #  If OCSP checking is disabled, the verify section is
            #  run on successful certificate validation.
            #
            verify {
                    #  If the OCSP checks succeed, the verify section
                    #  is run to allow additional checks.
                    #
                    #  If you want to skip verify on OCSP success,
                    #  uncomment this configuration item, and set it
                    #  to "yes".
                    #
            #       skip_if_ocsp_ok = no

                    #  A temporary directory where the client
                    #  certificates are stored.  This directory
                    #  MUST be owned by the UID of the server,
                    #  and MUST not be accessible by any other
                    #  users.  When the server starts, it will do
                    #  "chmod go-rwx" on the directory, for
                    #  security reasons.  The directory MUST
                    #  exist when the server starts.
                    #
                    #  You should also delete all of the files
                    #  in the directory when the server starts.
                    #
            #       tmpdir = /tmp/radiusd

                    #  The command used to verify the client cert.
                    #  We recommend using the OpenSSL command-line
                    #  tool.
                    #
                    #  The ${..ca_path} text is a reference to
                    #  the ca_path variable defined above.
                    #
                    #  The %{TLS-Client-Cert-Filename} is the name
                    #  of the temporary file containing the cert
                    #  in PEM format.  This file is automatically
                    #  deleted by the server when the command
                    #  returns.
                    #
            #       client = "/path/to/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}"
            }

            #  OCSP Configuration
            #
            #  Certificates can be verified against an OCSP
            #  Responder. This makes it possible to immediately
            #  revoke certificates without the distribution of
            #  new Certificate Revocation Lists (CRLs).
            #
            ocsp {
                    #  Enable it.  The default is "no".
                    #  Deleting the entire "ocsp" subsection
                    #  also disables ocsp checking
                    #
                    enable = no

                    #  The OCSP Responder URL can be automatically
                    #  extracted from the certificate in question.
                    #  To override the OCSP Responder URL set
                    #  "override_cert_url = yes".
                    #
                    override_cert_url = yes

                    #  If the OCSP Responder address is not extracted from
                    #  the certificate, the URL can be defined here.
                    #
                    url = "http://127.0.0.1/ocsp/"

                    # If the OCSP Responder can not cope with nonce
                    # in the request, then it can be disabled here.
                    #
                    # For security reasons, disabling this option
                    # is not recommended as nonce protects against
                    # replay attacks.
                    #
                    # Note that Microsoft AD Certificate Services OCSP
                    # Responder does not enable nonce by default. It is
                    # more secure to enable nonce on the responder than
                    # to disable it in the query here.
                    # See http://technet.microsoft.com/en-us/library/cc770413%28WS.10%29.aspx
                    #
            #       use_nonce = yes

                    # Number of seconds before giving up waiting
                    # for OCSP response. 0 uses system default.
                    #
            #       timeout = 0

                    # Normally an error in querying the OCSP
                    # responder (no response from server, server did
                    # not understand the request, etc) will result in
                    # a validation failure.
                    #
                    # To treat these errors as 'soft' failures and
                    # still accept the certificate, enable this
                    # option.
                    #
                    # Warning: this may enable clients with revoked
                    # certificates to connect if the OCSP responder
                    # is not available. Use with caution.
                    #
            #       softfail = no
            }
    }


    #  EAP-TLS
    #
    #  As of Version 3.0, the TLS configuration for TLS-based
    #  EAP types is above in the "tls-config" section.
    #
    tls {
            #  Point to the common TLS configuration
            #
            tls = tls-common

            #  As part of checking a client certificate, the EAP-TLS
            #  sets some attributes such as TLS-Client-Cert-Common-Name. This
            #  virtual server has access to these attributes, and can
            #  be used to accept or reject the request.
            #
    #       virtual_server = check-eap-tls
    }


    #  EAP-PEAP
    #

    ##################################################
    #
    #  !!!!! WARNINGS for Windows compatibility  !!!!!
    #
    ##################################################
    #
    #  If you see the server send an Access-Challenge,
    #  and the client never sends another Access-Request,
    #  then
    #
    #               STOP!
    #
    #  The server certificate has to have special OID's
    #  in it, or else the Microsoft clients will silently
    #  fail.  See the "scripts/xpextensions" file for
    #  details, and the following page:
    #
    #       https://support.microsoft.com/en-us/help/814394/
    #
    #  If is still doesn't work, and you're using Samba,
    #  you may be encountering a Samba bug.  See:
    #
    #       https://bugzilla.samba.org/show_bug.cgi?id=6563
    #
    #  Note that we do not necessarily agree with their
    #  explanation... but the fix does appear to work.
    #
    ##################################################

    #  The tunneled EAP session needs a default EAP type
    #  which is separate from the one for the non-tunneled
    #  EAP module.  Inside of the TLS/PEAP tunnel, we
    #  recommend using EAP-MS-CHAPv2.
    #
    peap {
            #  Which tls-config section the TLS negotiation parameters
            #  are in - see EAP-TLS above for an explanation.
            #
            #  In the case that an old configuration from FreeRADIUS
            #  v2.x is being used, all the options of the tls-config
            #  section may also appear instead in the 'tls' section
            #  above. If that is done, the tls= option here (and in
            #  tls above) MUST be commented out.
            #
            tls = tls-common

            #  The tunneled EAP session needs a default
            #  EAP type which is separate from the one for
            #  the non-tunneled EAP module.  Inside of the
            #  PEAP tunnel, we recommend using MS-CHAPv2,
            #  as that is the default type supported by
            #  Windows clients.
            #
            default_eap_type = mschapv2

            #  The PEAP module also has these configuration
            #  items, which are the same as for TTLS.
            #
            copy_request_to_tunnel = no

            #  As of version 3.0.5, this configuration item
            #  is deprecated.  Instead, you should use
            #
            #    update outer.session-state {
            #      ...
            #    }
            #
            #  This will cache attributes for the final Access-Accept.
            #
            use_tunneled_reply = no

            #  When the tunneled session is proxied, the
            #  home server may not understand EAP-MSCHAP-V2.
            #  Set this entry to "no" to proxy the tunneled
            #  EAP-MSCHAP-V2 as normal MSCHAPv2.
            #
    #       proxy_tunneled_request_as_eap = yes

            #  The inner tunneled request can be sent
            #  through a virtual server constructed
            #  specifically for this purpose.
            #
            #  A virtual server MUST be specified.
            #
            virtual_server = "inner-tunnel"

            #  This option enables support for MS-SoH
            #  see doc/SoH.txt for more info.
            #  It is disabled by default.
            #
    #       soh = yes

            #  The SoH reply will be turned into a request which
            #  can be sent to a specific virtual server:
            #
    #       soh_virtual_server = "soh-server"

            #  Unlike EAP-TLS, PEAP does not require a client certificate.
            #  However, you can require one by setting the following
            #  option. You can also override this option by setting
            #
            #    EAP-TLS-Require-Client-Cert = Yes
            #
            #  in the control items for a request.
            #
            #  Note that the majority of supplicants do not support using a
            #  client certificate with PEAP, so this option is unlikely to
            #  be usable for most people.
            #
    #       require_client_cert = yes
    }


    #  EAP-MSCHAPv2
    #
    #  Note that it is the EAP MS-CHAPv2 sub-module, not
    #  the main 'mschap' module.
    #
    #  Note also that in order for this sub-module to work,
    #  the main 'mschap' module MUST ALSO be configured.
    #
    #  This module is the *Microsoft* implementation of MS-CHAPv2
    #  in EAP.  There is another (incompatible) implementation
    #  of MS-CHAPv2 in EAP by Cisco, which FreeRADIUS does not
    #  currently support.
    #
    mschapv2 {
            #  Prior to version 2.1.11, the module never
            #  sent the MS-CHAP-Error message to the
            #  client.  This worked, but it had issues
            #  when the cached password was wrong.  The
            #  server *should* send "E=691 R=0" to the
            #  client, which tells it to prompt the user
            #  for a new password.
            #
            #  The default is to behave as in 2.1.10 and
            #  earlier, which is known to work.  If you
            #  set "send_error = yes", then the error
            #  message will be sent back to the client.
            #  This *may* help some clients work better,
            #  but *may* also cause other clients to stop
            #  working.
            #
    #       send_error = no

            #  Server identifier to send back in the challenge.
            #  This should generally be the host name of the
            #  RADIUS server.  Or, some information to uniquely
            #  identify it.
            #
    #       identity = "FreeRADIUS"
    }

}

@kaedewang
Copy link
Author

I successed to connect wpa2-enterprise by EAP-TLS.
The problem is client key. I used client key with password. After clearing password it is OK.

@AxelLin
Copy link
Contributor

AxelLin commented Aug 28, 2020

@kaedewang
The password protected client key should also work.

ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_cert_key(client_crt_start, client_crt_bytes,\
            client_key_start, client_key_bytes, NULL, 0) );

The latest 2 parameters is private_key_passwd and private_key_passwd_len.
You can check again by set correct password and password length.

@dabbinavo
Copy link
Contributor

dabbinavo commented Jun 10, 2021

The password protected client key should also work.

ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_cert_key(client_crt_start, client_crt_bytes,\
            client_key_start, client_key_bytes, NULL, 0) );

The latest 2 parameters is private_key_passwd and private_key_passwd_len.
You can check again by set correct password and password length.

@AxelLin, sorry for this (maybe) noob question, but i'm struggling with the understanding of that function.
From my understanding, the following is a common use-case:

  • Considering a network configured as WPA2-EAP TLS
  • Then, the IT administrator will give to me a ca-certificate for server certification and a client certificate that is used by my client to authenticate against the server
  • The ca-certificate has to be set with esp_wifi_sta_wpa2_ent_set_ca_cert()
  • The client certificate has to be set with esp_wifi_sta_wpa2_ent_set_cert_key()

But what to pass to client_key_start (also called private_key in the latest header file), if i only have gotten the client certificate (.crt) file but no "client key"?

@sagb2015
Copy link
Contributor

@dabbinavo In PKI, both parties (client and server in this case) generate <private, public> key pair and get certificates from trusted CA (which ties public key to the identity). Each side is supposed to know and keep their private keys private. The arg client_key_start refers to private key of the ESP32 device. Please refer to this article for more information on PKI and also contact your IT admin about generating the key pair and getting client-certificate signed by CA trusted by your organisation.

@dabbinavo
Copy link
Contributor

dabbinavo commented Jun 11, 2021

@sagb2015 Thanks for the information! It wasn't clear to me, that the user certificate (client certificate) in .p12 format (PKCS#12) distributed by the IT admin contains both, the certificate and the private key. So to use the ESP-IDF API esp_wifi_sta_wpa2_ent_set_cert_key(...);, the certificate and the private key first have to be extracted from the .p12 file and then passed to the arguments client_cert and private_key (and private_key_passwd if a password had to be specified during the extraction process for private key), right?

If so, does some ESP-IDF library running on the ESP32 already provide any functions to extract the certificate and private key from a .p12 file or do I have to include/use a separate library for this (e.g. openssl which can do that)?

@AxelLin
Copy link
Contributor

AxelLin commented Aug 30, 2021

@kaedewang
The password protected client key should also work.

ESP_ERROR_CHECK( esp_wifi_sta_wpa2_ent_set_cert_key(client_crt_start, client_crt_bytes,\
            client_key_start, client_key_bytes, NULL, 0) );

The latest 2 parameters is private_key_passwd and private_key_passwd_len.
You can check again by set correct password and password length.

I take it back.

While testing with v4.3-356-g48ae2309fd9c, I found the same issue as reported by #5698 (comment)
(It does not work if the client key needs password, but it works if the key does not need password).

I test again with v4.4-dev-2825-gb63ec47238fd, the same symptom: It does not work if the client key needs password.

@sagb2015 @kapilkedawat (I think this issue should be re-open)

@kapilkedawat
Copy link
Collaborator

@sagb2015 Thanks for the information! It wasn't clear to me, that the user certificate (client certificate) in .p12 format (PKCS#12) distributed by the IT admin contains both, the certificate and the private key. So to use the ESP-IDF API esp_wifi_sta_wpa2_ent_set_cert_key(...);, the certificate and the private key first have to be extracted from the .p12 file and then passed to the arguments client_cert and private_key (and private_key_passwd if a password had to be specified during the extraction process for private key), right?

If so, does some ESP-IDF library running on the ESP32 already provide any functions to extract the certificate and private key from a .p12 file or do I have to include/use a separate library for this (e.g. openssl which can do that)?

Hi @dabbinavo , you can use openssl commands to extract certificate and key.

While testing with v4.3-356-g48ae2309fd9c, I found the same issue as reported by #5698 (comment)
(It does not work if the client key needs password, but it works if the key does not need password).

I test again with v4.4-dev-2825-gb63ec47238fd, the same symptom: It does not work if the client key needs password.

Hi @AxelLin , can you please share the certificates that you have used? If not possible, can you please share the cert type?

@AxelLin
Copy link
Contributor

AxelLin commented Aug 30, 2021

@kapilkedawat
My testing ca, client certificate, key as below.
(For password protected key, the password: whatever)
ca.pem + client.crt + client_without_pwd.key works.
ca.pem + client.crt + client_with_pwd.key + password(whatever) fails.

ca.pem.txt
client.crt.txt
client_without_pwd.key.txt
client_with_pwd.key.txt

@AxelLin
Copy link
Contributor

AxelLin commented Aug 30, 2021

@kapilkedawat

I test again, this time it works. (No idea why it fails in my previous test).

With CONFIG_WPA_DEBUG_PRINT=y, it works but it shows some error messages as below (FYI).
(The same error messages on both v4.3 and master)

I (3941) wifi:new:<11,2>, old:<1,0>, ap:<255,255>, sta:<11,2>, prof:1
I (4958) wifi:state: init -> auth (b0)
I (4999) wifi:state: auth -> assoc (0)
I (5047) wifi:state: assoc -> run (10)
I (5048) wpa: wpa2_task prio:2, stack:6656

I (17123) wpa: SSL: Need 1914 bytes more input data
I (20117) wpa: SSL: Need 920 bytes more input data
I (24224) wpa: application data is null, adding one byte for ack
I (24233) wpa: >>>>>wpa2 FINISH

E (25240) wpa: RSN: PMKSA cache entry found - PMKID - hexdump(len=16):
E (25241) wpa: 92 98 05 cd 6c 63 ed cf 7b fb e2 44 7d d3 51 ae
<< I guess above error message should be a debug message rather than error message? >>

I (26259) wifi:connected with IGS-MESH, aid = 2, channel 11, 40D, bssid = 18:a6:f7:ab:ca:66
I (26260) wifi:security: WPA2-ENT, phy: bgn, rssi: -49
I (26262) wifi:pm start, type: 1

W (26265) wifi:Next TBTT incorrect! last beacon:1318892, offset:383, next beacon:11763692, beacon interval:102400, dtim period:0, dtim count:0, listen interval:3, now:23657636

@AxelLin
Copy link
Contributor

AxelLin commented Sep 6, 2021

@kapilkedawat
(I'm not sure how it works in my previous test.)

Test again with v4.4-dev-2928-gd5f58ab13551 and v4.3.1 debug build, I got below error message on the device:
E (407759) wpa: mbedtls_pk_parse_keyfile returned -0x2e80
E (407759) wpa: Failed to set client pki context
E (407760) wpa: Failed to set client configurations
E (407765) wpa: failed to create ssl handle
I (407770) wpa: TLS: Failed to set TLS connection parameters
I (407776) wpa: EAP-TLS: Failed to initialize SSL.

@AxelLin
Copy link
Contributor

AxelLin commented Sep 6, 2021

@kapilkedawat
(I'm not sure how it works in my previous test.)

Test again with v4.4-dev-2928-gd5f58ab13551 and v4.3.1 debug build, I got below error message on the device:
E (407759) wpa: mbedtls_pk_parse_keyfile returned -0x2e80
E (407759) wpa: Failed to set client pki context
E (407760) wpa: Failed to set client configurations
E (407765) wpa: failed to create ssl handle
I (407770) wpa: TLS: Failed to set TLS connection parameters
I (407776) wpa: EAP-TLS: Failed to initialize SSL.

Hi @kapilkedawat
Above error is because mbedtls_cipher_info_from_type() failed which is because the
cipher_alg is MBEDTLS_CIPHER_DES_EDE3_CBC and it is not supported.
Setting CONFIG_MBEDTLS_DES_C=y avoid the error.

Then I can connect to the AP.
Note, even though it works in the end, it fails so may times before successfully join the AP. (I got many disconnect with reason 204, 205).

@AxelLin
Copy link
Contributor

AxelLin commented Sep 7, 2021

@kapilkedawat

I tried diffent -keypbe setting to generate the key via openssl, e.g. PBE-SHA1-RC2-128

# openssl pkcs12 -info -in client.p12 -noout
Enter Import Password:
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And128BitRC2-CBC, Iteration 2048
Certificate bag
PKCS7 Data
Shrouded Keybag: pbeWithSHA1And128BitRC2-CBC, Iteration 2048

But I still got below error if CONFIG_MBEDTLS_DES_C=n
E (111835) wpa: mbedtls_pk_parse_keyfile returned -0x2e80

Is it necessary to set CONFIG_MBEDTLS_DES_C=y for password protected key?
I'm wondering if I missed something? ( How to test password protected key with CONFIG_MBEDTLS_DES_C=n?)

@kapilkedawat
Copy link
Collaborator

Hi @AxelLin ,

You can try with AES encryptions(128-192-256 bits). I would advise against enabling DES since it is vulnerable to sweet32 attacks.

@AxelLin
Copy link
Contributor

AxelLin commented Sep 7, 2021

Hi @AxelLin ,

You can try with AES encryptions(128-192-256 bits). I would advise against enabling DES since it is vulnerable to sweet32 attacks.

Could you show me the example to generate AES encryption key? Thanks. (I use freeRADIUS make client.pem)

@nishanth-radja
Copy link
Collaborator

Hi @AxelLin ,
Following are the steps to generate the encrypted Crts.
1.openssl genrsa -aes256 -out server.key 4096 {AES encryption of the private key}
2. openssl req -new -key server.key -out server.csr -config <required_config>
3. openssl ca -batch -keyfile ca.key -cert ca.pem -in server.csr -key 'whatever' -out server.crt -config <required_config>

For more detailed steps,Pls refer this Doc. Link

@weisen2021
Copy link

@AxelLin
Hello, I cannot connect to the RADIUS server while debugging EAP-TLS. I am using IDF4.4, the routine is WPA2_Enterprise and the chip is ESP32-D0WDQ6-V3.

I replaced wpa2_ca.pem, wpa2_client.crt, wpa2_client.ket, and wpa2_client.pem in my routine with files in the RADIUS server.

I don't use CA authentication, so I disabled it in the ConfigurAction Editor and selected TLS for the EAP Method.

When I use a Huawei mobile phone to connect to RADIUS, a user certificate is selected. The user certificate is a client. p12 file provided by my colleagues who set up RADIUS.

But I don't understand how ESP32 uses the client.p12 file.

@dabbinavo
Copy link
Contributor

dabbinavo commented Sep 24, 2022

When I use a Huawei mobile phone to connect to RADIUS, a user certificate is selected. The user certificate is a client. p12 file provided by my colleagues who set up RADIUS.

But I don't understand how ESP32 uses the client.p12 file.

@weisen2021
If you want to use the .p12 file on ESP32, you have to extract the information from it. You can do this for example with openSSL:
openssl/openssl/blob/master/demos/pkcs12/pkread.c

Also see this post

@AxelLin
Copy link
Contributor

AxelLin commented Sep 30, 2022

Hi @AxelLin , Following are the steps to generate the encrypted Crts. 1.openssl genrsa -aes256 -out server.key 4096 {AES encryption of the private key}

Hi @nishanth-radja
Above command does not work, I need to add additional "-traditional" to make it generate PKCS#1 format instead of default PKCS#8 format.

Without "-traditional" , I got E (6105) wpa: mbedtls_pk_parse_keyfile returned -0x2e80.

pk_parse_key_pkcs8_encrypted_der()
    mbedtls_pkcs5_pbes2()
        mbedtls_oid_get_cipher_alg() returns MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA

Just wondering Is it possible to support PKCS#8 format?

@weisen2021
Copy link

@dabbinavo
Thank you for your answer. Let me look at the routine first。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants