Thursday, May 26, 2011

Is copyright right?

For the ones not familiar with copyright, I'll make a short introduction. For a longer description check the wikipedia article. Copyright is a tool invented to foster innovation. It provides the author of literal or artistic work with a monopoly on copying the work. That monopoly can be understood because it is not an easy job to create literal or art works, and authors could use this monopoly to generate income. Today copyright has been extended to provide a monopoly for 70 years.

I am myself a copyright owner of several works of mine, one prominent being the software GnuTLS, a computer security software (or library to be precise). The copyright will remain on me and my descendants for my lifetime and my descendants will hold copyright to the software for 70 years afterwards. So if I could chose, so no-one could profit from that software for more than 100-120 years (if I can last that long). Why has the society granted me the power to deprive her from my work for so long? Moreover I have chosen to distribute my software under the GNU lesser general public license. I like this license because it promotes sharing, but many people do not think so. A big software company's CEO has even argued that this software license is a cancer. He might be right or wrong. If he is right then society has granted me the power to distribute my work only under a cancer-like license for 100 years or so. If I am right then maybe the society could benefit from my software.

But I might always be wrong, not matter what I believe. Why would the society trust authors of work to restrict them for a ridiculus amount of time, after which the works are hardly useful for anything than display on a museum? Now people in France and the World in general are looking for ways to enforce copyright in the digital world. But did we ever answered the question whether copyright as it is today makes sense in the digital era?.

Shouldn't we first balance the cost to the society versus the profits? Is 70 years after the author's death a reasonable time? Is no copyright a reasonable choice? These are the two extremes. I think today we are on the one extreme we should move somewhere closer to a balanced decision.

PS. I wrote that after watching the views of Perry Barlow in e-G8.

PS2. For the pendantics, I have chosen not to keep the copyright of my work in GnuTLS but rather transfer it to Free Software Foundation. This does not alter my arguments in any way as they apply to FSF as well.

Monday, May 16, 2011

using the Belgian ID cards with GnuTLS

Belgium is among the few countries that provide citizens with a smart-card containing RSA private keys and certificates signed by a national authority. Those keys can be used by GnuTLS as well, so let's explore the possibilities.

Initially you need a smart-card reader, I suppose any supported by opensc would do. I got one from, that also provided me with some smart-cards for free for the development of GnuTLS. Anyway after you have a smart-card reader make sure opensc is installed and is operating. For example in my system I see my reader as:

$ opensc-tool -l
# Detected readers (pcsc)
Nr.  Card  Features  Name
0    Yes             OmniKey CardMan 3121 00 00

Also make sure that /etc/gnutls/pkcs11.conf contains the line


which instructs GnuTLS to load the opensc PKCS #11 library. If you are wondering what PKCS #11 is, think of it as a common interface to talk to smart-cards. From now on, only GnuTLS (2.12) tools are required.

Initially let's verify the card is present. That would be with the command:
$ ./p11tool --list-tokens
Token 0:
        URL: pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API
        Label: BELPIC (Basic PIN)
        Manufacturer: (unknown)
        Model: PKCS#15
        Serial: XXX

Nice. We see that the card is present. Note that URL on top of the listing. GnuTLS uses PKCS #11 URLs to identify all objects within a token. They might be a bit intimidating because of their size, but they can uniquely and permanently identify an object. But let's now see what's stored inside:

$ ./p11tool --list-all --login
PIN required for token 'BELPIC (Basic PIN)' with URL 'pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29'
Enter PIN: 
Object 0:
        URL: pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29;object=Authentication;objecttype=private;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API;id=%02
        Type: Private key
        Label: Authentication
        ID: 02

Object 1:
        URL: pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29;object=Authentication;objecttype=cert;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API;id=%02
        Type: X.509 Certificate
        Label: Authentication
        ID: 02

Object 2:
        URL: pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29;object=Authentication;objecttype=public;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API;id=%02
        Type: Public key
        Label: Authentication
        ID: 02


Object 9:
        URL: pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=93FF298DB713225;model=PKCS%2315;manufacturer=%28unknown%29;object=Root;objecttype=public;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API;id=%06
        Type: Public key
        Label: Root
        ID: 06

That's quite some stuff there. As it seems there are a private-public key pair with a certificate to be used for authentication, another pair for signing and few national certificate authorities and their public keys. We can try to export one of the authorities as:

$ ./p11tool --login --export "pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29;object=Root;objecttype=cert;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API;id=%06"|certtool -i
Enter PIN: 
X.509 Certificate Information:
        Version: 3
        Serial Number (hex): 2affbe9fa2f0e987
        Issuer: C=BE,CN=Belgium Root CA2
                Not Before: Thu Oct 04 10:00:00 UTC 2007
                Not After: Wed Dec 15 08:00:00 UTC 2021
        Subject: C=BE,CN=Belgium Root CA2
        Subject Public Key Algorithm: RSA
                Modulus (bits 2048):
                Exponent (bits 24):
                Key Usage (critical):
                        Certificate signing.
                        CRL signing.
                Basic Constraints (critical):
                        Certificate Authority (CA): TRUE
                Unknown extension (not critical):
                        ASCII: 0907..`8...0.0,..+........
                        Hexdump: 3039303706056038090101302e302c06082b060105050702011620687474703a2f2f7265706f7369746f72792e6569642e62656c6769756d2e6265
                Subject Key Identifier (not critical):
                Unknown extension 2.16.840.1.113730.1.1 (not critical):
                        ASCII: ....
                        Hexdump: 03020007
                Authority Key Identifier (not critical):
        Signature Algorithm: RSA-SHA
Other Information:
        MD5 fingerprint:
        SHA-1 fingerprint:
        Public Key Id:


Ok let's now connect to a site using gnutls-cli. We use the authentication key and certificate we listed before.

$ ./gnutls-cli -p 5556 --x509certfile "pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29;object=Authentication;objecttype=cert;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API;id=%02" --x509keyfile "pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29;object=Authentication;objecttype=private;library-manufacturer=OpenSC%20%28www%2Eopensc%2Dproject%2Eorg%29;library-description=Smart%20card%20PKCS%2311%20API;id=%02"

PIN required for token 'BELPIC (Basic PIN)' with URL 'pkcs11:token=BELPIC%20%28Basic%20PIN%29;serial=XXX;model=PKCS%2315;manufacturer=%28unknown%29'
Enter pin:
Processed 1 client X.509 certificates...
Resolving ''...
Connecting to ''...
- Successfully sent 1 certificate(s) to server.
- Ephemeral Diffie-Hellman parameters
- Using prime: 1024 bits
- Secret key: 1020 bits
- Peer's public key: 1023 bits
- Server has requested a certificate.
- Certificate type: X.509
- Got a certificate list of 1 certificates.
- Certificate[0] info:
- subject `O=GnuTLS test server,', issuer `CN=GnuTLS test CA', RSA key 1024 bits, signed using RSA-SHA1, activated `2007-04-18 13:29:21 UTC', expires `2008-04-17 13:29:21 UTC', SHA-1 fingerprint `9838d56df8d651c70aea6202bb2e8322f527b2cb'
- The hostname in the certificate matches ''.
- Peer's certificate issuer is unknown
- Peer's certificate is NOT trusted
- Version: TLS1.1
- Key Exchange: DHE-RSA
- Cipher: AES-128-CBC
- Compression: NULL
- Handshake was completed

- Simple Client Mode:

GET / HTTP/1.0

The output of the GET command will show us the certificate used for the connection. That was all and I hope it was simple enough.

Tuesday, May 10, 2011

is really gnutls considered harmful?

A comment made few years ago by Howard Chu, the developer of openldap, seems to be being repeated by people, ignorant of the issue, as an argument against GnuTLS. It is the sad truth however that this comment is and was wrong back then. I had commented back then stating the facts and why I thought Howard came up to that conclusion.

So what is the issue? Howard claims that GnuTLS makes liberal use of strcpy(), strcat() and strlen(). Those functions are known to be responsible for several attacks via buffer overflows in current programs. In GnuTLS however we had few vulnerabilities (discussed in our security advisories page) but none of them was a buffer overflow. Why is that? Because we don't use strcpy() and strcat() liberally. We don't use them with data originated from the network or the user or without checking boundaries. GnuTLS includes a custom string library, the gnutls_buffer_st interface in gnutls_str, which is used in most of the cases.

So why was Howard concerned about our liberal use of strcpy() and strcat()? We do use those functions, but for static string copying and for strings originating within the library. E.g. our ASN.1 library requires to identify objects a string of the form "PKIX1.CRLDistributionPoints.?1.distributionPoint.fullName" or "PKIX1.CRLDistributionPoints.?5.distributionPoint.fullName". Thus in several occasions we do something like
char str[256];

gnutls_str_cpy(str, sizeof(str), "PKIX1.CRLDistributionPoints.");
gnutls_str_cat(str, sizeof(str), "?1.distributionPoint.fullName");
Our version of strcpy() and strcat() provide a safer wrapper function over the libc function, that will never overflow the destination string. Other cases include strings that are locally generated and controlled. Thus seeing strcpy() or strcat() in a program does not mean that it is vulnerable to buffer overflow attacks. Two things are also required, user or network input to be involved and bound checking not to be done. As far as we know neither is or was true for GnuTLS.

Of course noone is claiming that GnuTLS is perfect and bug-free. No software is bug-free and don't believe anyone claiming it. My claim is that the specific critique is invalid.