View Issue Details

IDProjectCategoryView StatusLast Update
0000911Main CAcert WebsiteGPG/PGPpublic2013-01-15 15:27
ReporterUli60 Assigned ToNEOatNHNG  
Status closedResolutionfixed 
Fixed in Version2011 Q3 
Summary0000911: Wrong expiration time in newly added GPG Key if Key has no Expire date
Descriptionfirst reported 2011-01-04 23:08 in support mailing list

I just added my brand new GPG key to my CACert account. Everything went fine
except that the key shows up as expierd with an expiration date 1971-01-02
which is definitely wrong. The Key expires 2013-01-04 and therefore is not
expired at all.

> Hmm, I cannot see anything strange about the key. As the software gets
> the day and month right and only the year is messed up, this has to be a
> bug.

2nd report: 2011-01-20 16:11
Gerade eben habe ich einen frischen gpg-schlüssel hochgeladen.
Statt dem korrekten Ablaufdatum 20.jan.2014 wird der 02.01.1971 angezeigt.

Ein Zählerüberlauf?

3rd report: 2011-02-06 10:33
Any news on this issue? I just added my public GPG key, which I exported from
my GPF crypto sitck, and it also shows up as expired. Initially, I thought
there was some sort of incompatibility, but now after finding this thread I
think it's just a problem with the way the keys are displayed. I chose no
expiration date (=0), so maybe it adds 0 seconds to an initial point in time
instead of handling this special case separately.
Additional Information
TagsNo tags attached.
Reviewed byNEOatNHNG
Test Instructions


related to 0000922 closedNEOatNHNG CAcert application code problem causing missing "certificate about to expire" messages 



2011-02-07 12:16

developer   ~0001857

Seeing this bug I opened my enigmail and checked my gpg key.
Created back in 2001 (4.12.2001) and having NO expiry date set (at least enigmail says there is no expiry date set, same for gpg cli), CAcert pretends that the key expired on 25.7.2010.

I exported the public key again and imported into CAcert OpenGPG key - new menu. After a short delay the key was displayed and I now have two public keys in my OpenPGP key store, the new one with an expiry date of 1971-01-02 00:00:00.

Seems to me as if something broke between the date I entered my key the first time (approx 1.5 years ago) and now.


2011-02-07 12:49

developer   ~0001858


www/gpg.php 133ff:

            if($bits[0] == "pub" && (!$keyid || !$when))
                $keyid = $bits[4];
                $when = $bits[5];
                if($bits[6] != "")
                    $expires = 1;

www/gpg.php 278ff:
$query = "insert into `gpg` set `memid`='".intval($_SESSION['profile']['id'])."',`email`='".mysql_real_escape_string($lastvalidemail)."',`level`='1',`expires`='".mysql_real_escape_string($expires)."',`multiple`='".mysql_real_escape_string($multiple)."',`keyid`='".mysql_real_escape_string($keyid)."'";

Means if an expire date is set, $expires is set to 1 and written into the database ($expires = [0|1]).

From pages/gpg/2.php 29ff:

$query = "select UNIX_TIMESTAMP(`issued`) as `issued`,UNIX_TIMESTAMP(`expire`) - UNIX_TIMESTAMP() as `timeleft`,UNIX_TIMESTAMP(`expire`) as `expired`,`expire` as `expires`, `id`, `level`,`email`,`keyid` from `gpg` where `memid`='".intval($_SESSION['profile']['id'])."' ORDER BY `issued` desc";

Note that there are two data fields expire and expires. expires is a flag (see above), expire is not set by the webdb code.

The signer seems to be the one who determines the expire date of an key. There is code in which updates the expire field after passing the input to the signer.

Next step should be to have a close look into the code to see what happens here.


2011-02-07 14:48

developer   ~0001859

After looking a little deeper into the code I think that the OpenPGPextractExpiryDate in the script does not work as expected.
The function was replaced some time ago.


2011-02-15 22:24

reporter   ~0001868

This bug is still an issue. The expiration date is not extracted correctly even an expiry date is set or not. I tried different keys (generated with the GNU Privacy Assistent) and all the same.

Maybe this report helps you a bit.


2011-05-06 09:09

reporter   ~0001952

It should be fairly easy to check in the DB when the invalid expiration times began to appear, and then check that against svn/git log.

Of course there might be some discrepancy in times between commits and first invalid expiration date due to the fact that code probably isn't deployed immediately and it took some time after deploy before first user requested gpg signature. ... but still this is a cheap way of narrowing the time frame.

Unfortunately DB schema
is still WIP


2011-05-10 20:09

updater   ~0001955

There is another ticket in support with the number s20110509.130

Today I've signed two of my GPG-Keys and now the expiration date of
these two signatures is displayed to be 1971-01-02 (see attached image).


2011-05-27 10:12

updater   ~0002010

addtl. report on public support mailing list


2011-06-11 11:02

updater   ~0002028

addtl report


2011-07-05 23:06

updater   ~0002091

from Software-Assessment project meeting:

a) the key is ok
b) display on gpg list in webdb displays wrong date


2011-07-07 02:45

updater   ~0002103

Last edited: 2011-07-08 01:37

display gpg keys -> gpg.php?id=2 /pages/gpg/2.php
potential 3 problem areas:
a. to save fields "issued" and "expire" into database
b. database field format changed ? so value becomes 0
c. read "issued" and "expire" wrong

code analyze:
a) GPG new (sign)
   gpg.php?id=0 /pages/gpg/0.php
   form submit -> gpg.php CSR, process="Submit", oldid=0
     loggedin.php: no further file inclusions
     /includes/general.php seems to be active from session_start
   loadem("account") -> include_once /includes/account_stuff.php
   analyze / handle / extract gpg.key (gpg.php l.81 ff.)
   if all ok -> insert into gpg -> memid, email, level, expires, multiple, keyid
             -> not set: csr,crt,issued,expire,warning
     extract uid,name,comment,email from key
   if all ok -> update gpg -> csr=$csrname
   waitForResult('gpg', $id); -> -> HandleGPG()
        l.1098 $date=OpenPGPextractExpiryDate($crtname) returns formated date
                                                      or empty ("")
      update gpg -> crt='$crtname', issued=now(), expire=$date
   gpg.php l.503 readfile(generatecertpath("crt","gpg",$id));
   routine finishes here
   table gpg: expire should have eg 2010-11-27 16:48:40 or 0000-00-00 00:00:00
       but this info is yet unverified
       could also be 1970-01-01 00:00:00

addtl note to
   if there is an expire date set in the key, transforms the
     time-until-expire into a date within the sub OpenPGPextractExpiryDate()

maybe a system upgrade ? package revision upgrade did break the routine ?!?
also interesting ... around March 2010 a repository move from /cacert/CommModule to /CommModule did happen and a system upgrade did happen in 12/2010
so the question here, does the "expire" field lists 1970-* or 1971-* records starting 03/2010 or 12/2010 ? (where issued >= 2010-03-* or 2010-12-*)
This may give an indicator if the problem is related on wrong database entry produced in the new gpg key routine or if the date in the database is correct and the problem relates to the view gpg key routine

b. is unlikely to happen

c. view gpg -> gpg.php?id=2 -> /pages/gpg/2.php
   l.29 query -> table gpg, field expire as expires
   l.63 display $row['expires']

As there is no calculation or transformation of the date value in the view routine, it displays as it is saved in the database field "expire"
so the problem starts in the sign new gpg key routine, and here in the
date calculation process -> see above section a. analyze


2011-07-08 05:49

developer   ~0002105

The 0000-00-00 vs. 1970-* or 1971-* assumption of Uli is not correct, from my feeling and understanding of the meaning of the value. There really should not be any 0000-00-00 values, because any gpg key has an expiration date, even if it is set way into future, or am I wrong?

Maybe the output of the gpg command changed and some regular expression simply does not find the value in the output. Maybe the default language for gpg output changed or other fancy stuff.


2011-07-15 22:15

updater   ~0002141

new report and answer
from public support mailing list


2011-07-19 16:34

updater   ~0002153

Last edited: 2011-07-19 16:38

problem is a bit tricky
the gpg key includes the correct expire date
but that is extracted wrongly from the fresh new signed key and stored wrongly in the gpg table that results in wrong displaying under view gpg keys
so there are 2 areas to fix
a) routine under that fixes the OpenPGPextractExpiryDate() routine (currently writing 1971-01-02 00:00:00 in the expire field instead of a valid expire date/time, thats caused by wrong calculation, thats caused by wrong readin from gpg -vv output)
b) routine under webdb that selects and displays the gpg keys expiry date


2011-07-19 22:52

administrator   ~0002158

I have fixed the regular expression parsing the date, I hope it works fine now. The fix is available on the test server Please review and test.


2011-07-20 09:24

updater   ~0002165

Last edited: 2011-07-20 15:32

generated new gpg key, uploaded for signingg
results in problem: unknown char, this may relate to a middle name used

generated 2nd new gpg key, w/o middlename in it
uploaded for signing -> error: you can only submit 1 key (or similiar error msg)

removed 1st gpg key from local keyring
uploaded for signing
Your certificate request is still queued and hasn't been processed yet. Please wait, and go to Certificates -> View to see it's status.
Pending 0000-00-00 00:00:00 259303CD25B8A04B

submitted key the 2nd time:
Your certificate request is still queued and hasn't been processed yet. Please wait, and go to Certificates -> View to see it's status.

OpenPGP Keys
Status Email Address Expires Key ID
Pending 0000-00-00 00:00:00 259303CD25B8A04B
Pending 0000-00-00 00:00:00 259303CD25B8A04B

(signer restarted)

OpenPGP Keys
Status Email Address Expires Key ID
Valid 2012-07-20 10:52:45 259303CD25B8A04B
Valid 2012-07-20 10:52:41 259303CD25B8A04B

sec key has expires: never (option 0) in it

signed key (gpg -vv)
:signature packet: algo 17, keyid 4BE7348177F751AC
        version 4, created 1311159161, md5len 0, sigclass 0x10
        digest algo 2, begin of digest 55 de
        hashed subpkt 2 len 4 (sig created 2011-07-20)
        critical hashed subpkt 3 len 4 (sig expires after 1y1d0h0m)


2011-07-20 15:46

updater   ~0002166

generated new gpg key, expires after 1 year
uploaded for signing

OpenPGP Keys
Status Email Address Expires Key ID
Valid 2012-07-20 15:39:37 E51048A60B115FB2

gpg -vv [signed key]

:signature packet: algo 17, keyid 4BE7348177F751AC
        version 4, created 1311176377, md5len 0, sigclass 0x10
        digest algo 2, begin of digest 82 69
        hashed subpkt 2 len 4 (sig created 2011-07-20)
        critical hashed subpkt 3 len 4 (sig expires after 1y1d0h0m)


2011-07-20 15:49

updater   ~0002167

test verified with both same keys against local testserver image
(main problem here was generating new local server gpgtest root key, that requests passphrase, signing routine returned errors, 'caused by set passphrase on the local root key, after removing the passphrase, procedure worked as expected)


2011-07-21 13:09

administrator   ~0002172

A note towards the expire date as shown by CAcert: There is a bug which has hopefully been fixed on the test system but from what I gather from the comments above there is also a misunderstanding:

The expiry date shown is not that of the key itself but of the Signature of CAcert. That means your key will still be valid in general but the signature that CAcert did on your key will expire so you just have to resign it to get a valid signature again.

Unfortunately most GUI tools don't show the expiration of a signature. On the command line you can check out the validity of the signatures on a key by running "gpg --check-sigs <key-ID>". The "X" indicates an eXpired signature.


2011-07-26 19:37

reporter   ~0002197

I see "parsing the date". You should have a look at --fixed-list-mode which prints the date as seconds since epoch.


2011-07-26 20:11

reporter   ~0002198

Last edited: 2011-07-26 20:54

Created new key without expiration date. Exported public, uploaded and signed by CAcert. Removed the key from key ring, and re-imported the key. Expiration date of the signature is set to one year in the future on exactly the same day as today. --list-sigs show also that the signature of the newly imported key does not contain a user-id, even though the relevant user id, alternatively also the proper key id was given on command line when importing.

$ gpg --list-options show-sig-expire --list-sigs CE6B0E09
pub 2048R/CE6B0E09 2011-07-26
uid abc def <>
sig 3 CE6B0E09 2011-07-26 niemals abc def <>
sig P 77F751AC 2011-07-26 2012-07-26 [User-ID nicht gefunden]
sub 2048R/E9FFA441 2011-07-26
sig CE6B0E09 2011-07-26 niemals abc def <>

Livesystem allerdings praktisch gleich:

$ gpg --list-options show-sig-expire --list-sigs AA00E75F
pub 2048R/AA00E75F 2011-07-26
uid ein name <xyz@abc.def>
sig 3 AA00E75F 2011-07-26 niemals ein name <xyz@abc.def>
sig P 65D0FD58 2011-07-26 2012-07-26 CA Cert Signing Authority (Root CA) <>
sub 2048R/E0380C97 2011-07-26
sig AA00E75F 2011-07-26 niemals ein name <xyz@abc.def>

Aber warum? Key wie folgt erstellt:

$ gpg --gen-key
$ gpg --export-secret-key AA00E75F >
$ gpg --armor --export AA00E75F
$ gpg --delete-secret-and-public-key AA00E75F
$ gpg --import
$ gpg --import signed.asc xyz@abc.def
$ gpg --list-options show-sig-expire --list-sigs AA00E75F


2011-08-01 13:08

updater   ~0002233

tested by 2 testers (u60 + alex)


2011-08-16 23:19

administrator   ~0002299

reviewed this patch ... is okay ...


2011-08-17 19:07

reporter   ~0002302

Just a hint: gpg uses --fixed-list-mode as default in some later versions, so beware on gpg update.


2011-08-20 15:42

developer   ~0002314

Patch applied to production system on August 20, 2011. See also:

Issue History

Date Modified Username Field Change
2011-02-07 11:19 Uli60 New Issue
2011-02-07 12:16 edgarwahn Note Added: 0001857
2011-02-07 12:49 edgarwahn Note Added: 0001858
2011-02-07 14:48 edgarwahn Note Added: 0001859
2011-02-15 22:24 FH Note Added: 0001868
2011-05-06 09:09 stefanb Note Added: 0001952
2011-05-10 20:09 INOPIAE Note Added: 0001955
2011-05-27 10:12 Uli60 Note Added: 0002010
2011-06-11 11:02 Uli60 Note Added: 0002028
2011-07-05 23:06 Uli60 Note Added: 0002091
2011-07-07 02:45 Uli60 Note Added: 0002103
2011-07-07 02:48 Uli60 Note Edited: 0002103
2011-07-07 11:00 Uli60 Note Edited: 0002103
2011-07-07 11:19 Uli60 Note Edited: 0002103
2011-07-07 11:55 Uli60 Note Edited: 0002103
2011-07-07 12:21 Uli60 Note Edited: 0002103
2011-07-08 01:02 Uli60 Note Edited: 0002103
2011-07-08 01:07 Uli60 Note Edited: 0002103
2011-07-08 01:26 Uli60 Note Edited: 0002103
2011-07-08 01:36 Uli60 Note Edited: 0002103
2011-07-08 01:37 Uli60 Note Edited: 0002103
2011-07-08 05:49 edgarwahn Note Added: 0002105
2011-07-15 22:15 Uli60 Note Added: 0002141
2011-07-19 16:34 Uli60 Note Added: 0002153
2011-07-19 16:34 Uli60 Assigned To => Uli60
2011-07-19 16:34 Uli60 Status new => confirmed
2011-07-19 16:38 Uli60 Note Edited: 0002153
2011-07-19 21:25 NEOatNHNG Source_changeset_attached => cacert-devel master 28329b46
2011-07-19 21:25 NEOatNHNG Source_changeset_attached => cacert-devel master a8ae57cb
2011-07-19 22:52 NEOatNHNG Note Added: 0002158
2011-07-19 22:52 NEOatNHNG Assigned To Uli60 => NEOatNHNG
2011-07-19 22:52 NEOatNHNG Status confirmed => needs review & testing
2011-07-19 22:52 NEOatNHNG Reviewed by => NEOatNHNG
2011-07-20 09:24 Uli60 Note Added: 0002165
2011-07-20 15:27 Uli60 Note Edited: 0002165
2011-07-20 15:28 Uli60 Note Edited: 0002165
2011-07-20 15:32 Uli60 Note Edited: 0002165
2011-07-20 15:46 Uli60 Note Added: 0002166
2011-07-20 15:49 Uli60 Note Added: 0002167
2011-07-21 13:09 NEOatNHNG Note Added: 0002172
2011-07-26 19:37 dakon Note Added: 0002197
2011-07-26 20:11 alex Note Added: 0002198
2011-07-26 20:47 alex Note Edited: 0002198
2011-07-26 20:54 alex Note Edited: 0002198
2011-08-01 13:08 Uli60 Note Added: 0002233
2011-08-01 13:08 Uli60 Status needs review & testing => needs review
2011-08-16 23:19 egal Note Added: 0002299
2011-08-17 19:07 dakon Note Added: 0002302
2011-08-20 12:30 Source_changeset_attached => cacert-devel release 8e5648c6
2011-08-20 15:42 wytze Note Added: 0002314
2011-08-20 15:42 wytze Status needs review => solved?
2011-08-20 15:42 wytze Resolution open => fixed
2011-09-06 16:08 NEOatNHNG Status solved? => closed
2012-06-06 01:25 Uli60 Relationship added related to 0000922
2013-01-15 15:27 Werner Dworak Fixed in Version => 2011 Q3