Package: libgwenhywfar79
Version: 5.6.0-2
Severity: serious
Tags: patch upstream fixed-upstream
Forwarded: https://www.aquamaniac.de/rdm/issues/295

A few days ago the communication to the banking server
https://hbci-pintan.gad.de/ doesn't work anymore because the already accepted
server certificate is rejected with the message "Owner of certificate does not
match hostname".

The issue could be easily reproduced with bogus anonymous credentials as below
(the error is triggered before authentication or credentials are needed). The
only relevant parameter for the reproduction is the "--server" parameter, all
other parameters are just there as the command wants them to be present.

```
$ aqhbci-tool4 adduser --username=Anonymous \
                       --tokentype=pintan \
                       --user=anonymous \
                       --bank=0 \
                       --server=https://hbci-pintan.gad.de/
3:2023/04/18 21-14-36:(null)(50094):banking_update.c:  610: No AqBanking config 
folder found at [/home/user/.aqbanking/settings6/users] (-1)
3:2023/04/18 21-14-36:(null)(50094):banking_update.c:  610: No AqBanking config 
folder found at [/home/user/.aqbanking/settings/users] (-1)
3:2023/04/18 21-14-36:(null)(50094):banking_update.c:  411: There is no old 
settings folder, need initial setup
```

On a system which didn't have any AqBanking setup before, a new user with
unique id 1 will be created (see output of "aqhbci-tool4 listusers").

```
$ aqhbci-tool4 listusers
User 0: Bank: de/0 User Id: anonymous Customer Id: anonymous Unique Id: 1
```

Now, for reproduction of the error, you need to retrieve the server
certificate, which will implicitly validate it.

```
$ aqhbci-tool4 getcert --user=1
5:2023/04/18 21-22-43:aqbanking(50117):siotlsext.c:  233: Status for 
certificate 76:42:76:BF:8E:E5:95:22:ED:A7:85:10:8F:52:96:73" has changed to 
"Certificate owner does not match hostname" (00000000->00000020), need to 
present
4:2023/04/18 21-22-43:gwen(50117):syncio_tls.c:  137: No checkCertFn set, using 
GWEN_GUI
===== Certificate Received =====
The following certificate has been received:
Name         : fints1.atruvia.de
Organisation : Atruvia AG
Department   : unknown
Country      : DE
City         : Karlsruhe
State        : Baden-W?rttemberg
Valid after  : 2023/03/21 08:14:05
Valid until  : 2024/03/21 08:09:00
Hash (MD5)   : 76:42:76:BF:8E:E5:95:22:ED:A7:85:10:8F:52:96:73
Hash (SHA1)  : 8E:C0:B3:C1:F7:B6:0A:9B:8F:86:00:D0:F2:72:E9:F6:72:EE:D7:18
Hash (SHA512): 
DE:A2:D8:16:29:3B:64:83:34:C4:BD:5C:08:40:DE:45:26:BA:EF:5E:79:E9:21:52:77:DE:3A:A2:F6:B8:98:E4:62:BE:28:31:03:57:D8:67:40:64:35:C7:A1:7C:31:AB:C3:B2:7C:B3:3B:98:31:CE:DE:23:36:50:F9:F2:77:E1
Status       : Certificate owner does not match hostname
Do you wish to accept this certificate?
(1) Yes  (2) No
Please enter your choice: 2
5:2023/04/18 21-22-52:aqbanking(50117):siotlsext.c:  360: User response to 
presentation of cert "76:42:76:BF:8E:E5:95:22:ED:A7:85:10:8F:52:96:73" 
(Certificate owner does not match hostname): -108
3:2023/04/18 21-22-52:gwen(50117):syncio_tls.c: 1399: Peer cert not accepted 
(-108), aborting
Could not connect to server
3:2023/04/18 21-22-52:aqhbci(50117):provider_online.c:  919: Could not connect 
to server (-108)
Could not connect to server
3:2023/04/18 21-22-52:aqhbci-tool(50117):getcert.c:   98: Error -108 [Unknown 
error]
3:2023/04/18 21-22-52:aqhbci-tool(50117):aqhbci-tool.c:  275: Error calling 
control function (3)
```

Here you can see that Gwenhywfar reports the certificate as invalid with reason
"Certificate owner does not match hostname".

However, the very same configuration was working in the past just fine. Most
likely something on the server end changed.

Inspecting the certificate sent by the server shows that the "Common Name"
field is set to "fints1.atruvia.de", but also that a SubjectAltName extension
is present, which makes the certificate valid also for other hostnames,
including "hbci-pintan.gad.de".

Quoting https://en.wikipedia.org/wiki/Subject_Alternative_Name:
> RFC 2818 (May 2000) specifies Subject Alternative Names as the preferred
> method of adding DNS names to certificates, deprecating the previous method
> of putting DNS names in the commonName field. Google Chrome version 58
> (March 2017) removed support for checking the commonName field at all,
> instead only looking at the SANs.

So, if the certificate is valid, but AqBanking doesn't accept it, I concluded
to have found a bug.

Looking into the code, I think the culprit is some incomplete hostname
verification in Gwenhywfar's source file src/sio/syncio_tls.c at these lines
(line numbers based on current Git master):

```
1041       rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 
0, 0, buffer1, &size);
1042       if (rv==0) {
1043         GWEN_SslCertDescr_SetCommonName(certDescr, buffer1);
1044         if (xio->hostName && strcasecmp(xio->hostName, buffer1)!=0) {
1045           DBG_INFO(GWEN_LOGDOMAIN, "Owner of certificate does not match 
hostname");
1046           errFlags|=GWEN_SSL_CERT_FLAGS_BAD_HOSTNAME;
1047         }
```

Apparently only the Common Name of the certificate is checked, but the "Subject
Alternative Name" extension is not.

Digging a bit more, I realized that the hostname validation seems to be
implemented twice. Within the same the function the following code block is
executed just a few lines before, which seems to be fully sufficient for a
proper hostname validation.

```
 975         DBG_INFO(GWEN_LOGDOMAIN, "Checking hostname [%s]", xio->hostName);
 976         if (!gnutls_x509_crt_check_hostname(cert, xio->hostName)) {
 977           DBG_WARN(GWEN_LOGDOMAIN,
 978                    "Certificate was not issued for this host");
 979           GWEN_Gui_ProgressLog(0, GWEN_LoggerLevel_Warning,
 980                                I18N("Certificate was not issued for this 
host"));
 981           errFlags|=GWEN_SSL_CERT_FLAGS_BAD_HOSTNAME;
 982         }
```

Trusting the GnuTLS API to do a thorough hostname check already, I consider the
additional manual comparison of only the certificate's CN bogus. So, the fix is
to just drop these lines (patch attached and already committed upstream).
From: Micha Lenk <mi...@lenk.info>
Date: Sun, 16 Apr 2023 15:12:45 +0200
Bug: https://www.aquamaniac.de/rdm/issues/295
Origin: upstream, 
https://www.aquamaniac.de/rdm/projects/gwenhywfar/repository/revisions/a901426cfa0d555b7920dc39358af293dedafe85
Last-Update: 2023-04-18
Subject: Remove duplicate hostname check

The hostname in the certificate is checked already a few lines above by calling
gnutls_x509_crt_check_hostname(). No need to check it here again.

This also fixes the bad hostname validation in cases where the used server name
is only available in the SubjectAltName extension of the certificate, and not
in its Distinguished Name (DN).

Fixes #295.
---
 src/sio/syncio_tls.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/src/sio/syncio_tls.c b/src/sio/syncio_tls.c
index 6c81d58a..34c35cd7 100644
--- a/src/sio/syncio_tls.c
+++ b/src/sio/syncio_tls.c
@@ -1041,10 +1041,6 @@ int GWEN_SyncIo_Tls_GetPeerCert(GWEN_SYNCIO *sio)
       rv=gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, 0, 
0, buffer1, &size);
       if (rv==0) {
         GWEN_SslCertDescr_SetCommonName(certDescr, buffer1);
-        if (xio->hostName && strcasecmp(xio->hostName, buffer1)!=0) {
-          DBG_INFO(GWEN_LOGDOMAIN, "Owner of certificate does not match 
hostname");
-          errFlags|=GWEN_SSL_CERT_FLAGS_BAD_HOSTNAME;
-        }
       }
 
       size=sizeof(buffer1)-1;
-- 
2.30.2

Reply via email to