1997-11-24 22:24:04 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* For packet version 3 we calculate the keyids this way:
|
|
|
|
|
RSA := low 64 bits of n
|
1998-01-12 10:18:17 +00:00
|
|
|
|
ELGAMAL := build a v3 pubkey packet (with CTB 0x99) and calculate
|
|
|
|
|
a rmd160 hash value from it. This is used as the
|
|
|
|
|
fingerprint and the low 64 bits are the keyid.
|
1997-11-24 22:24:04 +00:00
|
|
|
|
|
1998-04-14 17:51:16 +00:00
|
|
|
|
* Revocation certificates consist only of the signature packet;
|
1998-02-18 13:58:46 +00:00
|
|
|
|
"import" knows how to handle this. The rationale behind it is
|
|
|
|
|
to keep them small.
|
|
|
|
|
|
1997-11-24 22:24:04 +00:00
|
|
|
|
|
1998-05-29 11:53:54 +00:00
|
|
|
|
Key generation shows progress by printing different characters to
|
|
|
|
|
stderr:
|
|
|
|
|
"." Last 10 Miller-Rabin tests failed
|
|
|
|
|
"+" Miller-Rabin test succeeded
|
|
|
|
|
"!" Reloading the pool with fresh prime numbers
|
|
|
|
|
"^" Checking a new value for the generator
|
|
|
|
|
"<" Size of one factor decreased
|
|
|
|
|
">" Size of one factor increased
|
|
|
|
|
|
|
|
|
|
The prime number for ElGamal is generated this way:
|
|
|
|
|
|
|
|
|
|
1) Make a prime number q of 160, 200, 240 bits (depending on the keysize)
|
|
|
|
|
2) Select the length of the other prime factors to be at least the size
|
|
|
|
|
of q and calculate the number of prime factors needed
|
|
|
|
|
3) Make a pool of prime numbers, each of the length determined in step 2
|
|
|
|
|
4) Get a new permutation out of the pool or continue with step 3
|
|
|
|
|
if we have tested all permutations.
|
|
|
|
|
5) Calculate a candidate prime p = 2 * q * p[1] * ... * p[n] + 1
|
|
|
|
|
6) Check that this prime has the correct length (this may change q if
|
|
|
|
|
it seems not to be possible to make a prime of the desired length)
|
|
|
|
|
7) Check whether this is a prime using trial divisions and the
|
|
|
|
|
Miller-Rabin test.
|
|
|
|
|
8) Continue with step 4 if we did not find a prime in step 7.
|
|
|
|
|
9) Find a generator for that prime.
|
|
|
|
|
|
|
|
|
|
|
1998-01-12 10:18:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Layout of the TrustDB
|
|
|
|
|
=====================
|
1998-01-25 18:56:33 +00:00
|
|
|
|
FIXME: use a directory record as top node instead of the pubkey record
|
|
|
|
|
|
1998-04-14 17:51:16 +00:00
|
|
|
|
The TrustDB is built from fixed length records, where the first byte
|
1998-01-12 10:18:17 +00:00
|
|
|
|
describes the record type. All numeric values are stored in network
|
|
|
|
|
byte order. The length of each record is 40 bytes. The first record of
|
|
|
|
|
the DB is always of type 1 and this is the only record of this type.
|
|
|
|
|
|
|
|
|
|
Record type 0:
|
|
|
|
|
--------------
|
|
|
|
|
Unused record, can be reused for any purpose.
|
|
|
|
|
|
|
|
|
|
Record type 1:
|
|
|
|
|
--------------
|
|
|
|
|
Version information for this TrustDB. This is always the first
|
1998-04-14 17:51:16 +00:00
|
|
|
|
record of the DB and the only one with type 1.
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte value 2
|
1998-02-24 18:50:46 +00:00
|
|
|
|
3 bytes 'gpg' magic value
|
1998-01-12 10:18:17 +00:00
|
|
|
|
1 byte Version of the TrustDB
|
|
|
|
|
3 byte reserved
|
|
|
|
|
1 u32 locked by (pid) 0 = not locked.
|
|
|
|
|
1 u32 timestamp of trustdb creation
|
|
|
|
|
1 u32 timestamp of last modification
|
|
|
|
|
1 u32 timestamp of last validation
|
|
|
|
|
(Used to keep track of the time, when this TrustDB was checked
|
|
|
|
|
against the pubring)
|
1998-01-31 21:21:22 +00:00
|
|
|
|
1 u32 reserved
|
1998-01-12 10:18:17 +00:00
|
|
|
|
1 byte marginals needed
|
|
|
|
|
1 byte completes needed
|
|
|
|
|
1 byte max. cert depth
|
|
|
|
|
If any of this 3 values are changed, all cache records
|
1998-07-06 10:23:57 +00:00
|
|
|
|
must be invalidated.
|
1998-01-12 10:18:17 +00:00
|
|
|
|
9 bytes reserved
|
|
|
|
|
|
1998-01-31 21:21:22 +00:00
|
|
|
|
|
|
|
|
|
Record type 2: (directory record)
|
1998-01-12 10:18:17 +00:00
|
|
|
|
--------------
|
|
|
|
|
Informations about a public key certificate.
|
1998-01-13 19:04:23 +00:00
|
|
|
|
These are static values which are never changed without user interaction.
|
1998-01-12 10:18:17 +00:00
|
|
|
|
|
|
|
|
|
1 byte value 2
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte reserved
|
|
|
|
|
1 u32 LID . (This is simply the record number of this record.)
|
|
|
|
|
1 u32 List of key-records (the first one is the primary key)
|
|
|
|
|
1 u32 List of uid-records
|
1998-01-31 21:21:22 +00:00
|
|
|
|
1 u32 cache record
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte ownertrust
|
|
|
|
|
1 byte sigflag
|
|
|
|
|
20 byte reserved
|
1998-01-31 21:21:22 +00:00
|
|
|
|
|
|
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
Record type 3: (key record)
|
1998-01-31 21:21:22 +00:00
|
|
|
|
--------------
|
1998-07-09 13:37:17 +00:00
|
|
|
|
Informations about a primary public key.
|
1998-07-14 17:10:28 +00:00
|
|
|
|
(This is mainly used to lookup a trust record)
|
1998-01-31 21:21:22 +00:00
|
|
|
|
|
|
|
|
|
1 byte value 3
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte reserved
|
|
|
|
|
1 u32 LID
|
|
|
|
|
1 u32 next - next key record
|
1998-07-21 12:53:38 +00:00
|
|
|
|
7 bytes reserved
|
|
|
|
|
1 byte keyflags
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte pubkey algorithm
|
|
|
|
|
1 byte length of the fingerprint (in bytes)
|
1998-01-12 10:18:17 +00:00
|
|
|
|
20 bytes fingerprint of the public key
|
1998-07-14 17:10:28 +00:00
|
|
|
|
(This is the value we use to identify a key)
|
|
|
|
|
|
|
|
|
|
Record type 4: (uid record)
|
|
|
|
|
--------------
|
|
|
|
|
Informations about a userid
|
|
|
|
|
We do not store the userid but the hash value of the userid because that
|
|
|
|
|
is sufficient.
|
|
|
|
|
|
|
|
|
|
1 byte value 4
|
|
|
|
|
1 byte reserved
|
|
|
|
|
1 u32 LID points to the directory record.
|
|
|
|
|
1 u32 next next userid
|
|
|
|
|
1 u32 pointer to preference record
|
|
|
|
|
1 u32 siglist list of valid signatures
|
1998-07-21 12:53:38 +00:00
|
|
|
|
1 byte uidflags
|
|
|
|
|
1 byte reserved
|
1998-07-14 17:10:28 +00:00
|
|
|
|
20 bytes ripemd160 hash of the username.
|
1998-01-31 21:21:22 +00:00
|
|
|
|
|
|
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
Record type 5: (pref record)
|
|
|
|
|
--------------
|
|
|
|
|
Informations about preferences
|
|
|
|
|
|
|
|
|
|
1 byte value 5
|
|
|
|
|
1 byte reserved
|
|
|
|
|
1 u32 LID; points to the directory record (and not to the uid record!).
|
|
|
|
|
(or 0 for standard preference record)
|
|
|
|
|
1 u32 next
|
|
|
|
|
|
|
|
|
|
Record type 6 (sigrec)
|
|
|
|
|
-------------
|
|
|
|
|
Used to keep track of valid key signatures. Self-signatures are not
|
|
|
|
|
stored.
|
|
|
|
|
|
|
|
|
|
1 byte value 6
|
|
|
|
|
1 byte reserved
|
|
|
|
|
1 u32 LID points back to the dir record
|
|
|
|
|
1 u32 next next sigrec of this owner or 0 to indicate the
|
|
|
|
|
last sigrec.
|
|
|
|
|
6 times
|
|
|
|
|
1 u32 Local_id of signators dir record
|
|
|
|
|
1 byte reserved
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Record type 9: (cache record)
|
1998-01-12 10:18:17 +00:00
|
|
|
|
--------------
|
|
|
|
|
Used to bind the trustDB to the concrete instance of keyblock in
|
1998-04-14 17:51:16 +00:00
|
|
|
|
a pubring. This is used to cache information.
|
1998-01-12 10:18:17 +00:00
|
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte value 9
|
1998-01-12 10:18:17 +00:00
|
|
|
|
1 byte reserved
|
|
|
|
|
1 u32 Local-Id.
|
1998-01-14 12:34:05 +00:00
|
|
|
|
8 bytes keyid of the primary key (needed?)
|
1998-01-12 10:18:17 +00:00
|
|
|
|
1 byte cache-is-valid the following stuff is only
|
|
|
|
|
valid if this is set.
|
|
|
|
|
1 byte reserved
|
|
|
|
|
20 bytes rmd160 hash value over the complete keyblock
|
|
|
|
|
This is used to detect any changes of the keyblock with all
|
|
|
|
|
CTBs and lengths headers. Calculation is easy if the keyblock
|
1998-07-06 10:23:57 +00:00
|
|
|
|
is optained from a keyserver: simply create the hash from all
|
1998-01-12 10:18:17 +00:00
|
|
|
|
received data bytes.
|
|
|
|
|
|
|
|
|
|
1 byte number of untrusted signatures.
|
|
|
|
|
1 byte number of marginal trusted signatures.
|
|
|
|
|
1 byte number of fully trusted signatures.
|
|
|
|
|
(255 is stored for all values greater than 254)
|
|
|
|
|
1 byte Trustlevel
|
|
|
|
|
0 = undefined (not calculated)
|
|
|
|
|
1 = unknown
|
|
|
|
|
2 = not trusted
|
|
|
|
|
3 = marginally trusted
|
|
|
|
|
4 = fully trusted
|
|
|
|
|
5 = ultimately trusted (have secret key too).
|
|
|
|
|
|
1998-01-14 12:34:05 +00:00
|
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
Record Type 10 (hash table)
|
|
|
|
|
--------------
|
1998-01-31 21:24:36 +00:00
|
|
|
|
Due to the fact that we use the keyid to lookup keys, we can
|
|
|
|
|
implement quick access by some simple hash methods, and avoid
|
1998-04-14 17:51:16 +00:00
|
|
|
|
the overhead of gdbm. A property of keyids is that they can be
|
|
|
|
|
used directly as hash values. (They can be considered as strong
|
|
|
|
|
random numbers.)
|
1998-01-31 21:24:36 +00:00
|
|
|
|
What we use is a dynamic multilevel architecture, which combines
|
1998-07-06 10:23:57 +00:00
|
|
|
|
hashtables, record lists, and linked lists.
|
1998-01-31 21:24:36 +00:00
|
|
|
|
|
|
|
|
|
This record is a hashtable of 256 entries; a special property
|
1998-04-14 17:51:16 +00:00
|
|
|
|
is that all these records are stored consecutively to make one
|
1998-01-31 21:24:36 +00:00
|
|
|
|
big table. The hash value is simple the 1st, 2nd, ... byte of
|
|
|
|
|
the keyid (depending on the indirection level).
|
|
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte value 10
|
1998-01-31 21:24:36 +00:00
|
|
|
|
1 byte reserved
|
|
|
|
|
n u32 recnum; n depends on th record length:
|
|
|
|
|
n = (reclen-2)/4 which yields 9 for the current record length
|
|
|
|
|
of 40 bytes.
|
|
|
|
|
|
|
|
|
|
the total number of surch record which makes up the table is:
|
|
|
|
|
m = (256+n-1) / n
|
|
|
|
|
which is 29 for a record length of 40.
|
|
|
|
|
|
|
|
|
|
To look up a key we use its lsb to get the recnum from this
|
1998-04-14 17:51:16 +00:00
|
|
|
|
hashtable and look up the addressed record:
|
1998-01-31 21:24:36 +00:00
|
|
|
|
- If this record is another hashtable, we use 2nd lsb
|
|
|
|
|
to index this hast table and so on.
|
1998-04-14 17:51:16 +00:00
|
|
|
|
- if this record is a hashlist, we walk thru the
|
|
|
|
|
reclist records until we found one whose hash field
|
1998-01-31 21:24:36 +00:00
|
|
|
|
matches the MSB of our keyid, and lookup this record
|
|
|
|
|
- if this record is a dir record, we compare the
|
|
|
|
|
keyid and if this is correct, we get the keyrecod and compare
|
1998-04-14 17:51:16 +00:00
|
|
|
|
the fingerprint to decide whether it is the requested key;
|
1998-01-31 21:24:36 +00:00
|
|
|
|
if this is not the correct dir record, we look at the next
|
|
|
|
|
dir record which is linked by the link field.
|
|
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
Record type 11 (hash list)
|
|
|
|
|
--------------
|
1998-01-31 21:24:36 +00:00
|
|
|
|
see hash table for an explanation.
|
|
|
|
|
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 byte value 11
|
1998-01-31 21:24:36 +00:00
|
|
|
|
1 byte reserved
|
1998-07-14 17:10:28 +00:00
|
|
|
|
1 u32 next next hash list record
|
1998-01-31 21:24:36 +00:00
|
|
|
|
n times n = (reclen-6)/5
|
|
|
|
|
1 byte hash
|
|
|
|
|
1 u32 recnum
|
|
|
|
|
|
|
|
|
|
For the current record length of 40, n is 6
|
|
|
|
|
|
1998-02-18 13:58:46 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Packet Headers
|
|
|
|
|
===============
|
|
|
|
|
|
1998-04-14 17:51:16 +00:00
|
|
|
|
GNUPG uses PGP 2 packet headers and also understands OpenPGP packet header.
|
|
|
|
|
There is one enhancement used with the old style packet headers:
|
1998-02-18 13:58:46 +00:00
|
|
|
|
|
|
|
|
|
CTB bits 10, the "packet-length length bits", have values listed in
|
|
|
|
|
the following table:
|
|
|
|
|
|
|
|
|
|
00 - 1-byte packet-length field
|
|
|
|
|
01 - 2-byte packet-length field
|
|
|
|
|
10 - 4-byte packet-length field
|
|
|
|
|
11 - no packet length supplied, unknown packet length
|
|
|
|
|
|
|
|
|
|
As indicated in this table, depending on the packet-length length
|
|
|
|
|
bits, the remaining 1, 2, 4, or 0 bytes of the packet structure field
|
|
|
|
|
are a "packet-length field". The packet-length field is a whole
|
|
|
|
|
number field. The value of the packet-length field is defined to be
|
|
|
|
|
the value of the whole number field.
|
|
|
|
|
|
|
|
|
|
A value of 11 is currently used in one place: on compressed data.
|
|
|
|
|
That is, a compressed data block currently looks like <A3 01 . . .>,
|
|
|
|
|
where <A3>, binary 10 1000 11, is an indefinite-length packet. The
|
|
|
|
|
proper interpretation is "until the end of the enclosing structure",
|
|
|
|
|
although it should never appear outermost (where the enclosing
|
|
|
|
|
structure is a file).
|
|
|
|
|
|
|
|
|
|
+ This will be changed with another version, where the new meaning of
|
|
|
|
|
+ the value 11 (see below) will also take place.
|
|
|
|
|
+
|
|
|
|
|
+ A value of 11 for other packets enables a special length encoding,
|
|
|
|
|
+ which is used in case, where the length of the following packet can
|
|
|
|
|
+ not be determined prior to writing the packet; especially this will
|
|
|
|
|
+ be used if large amounts of data are processed in filter mode.
|
|
|
|
|
+
|
|
|
|
|
+ It works like this: After the CTB (with a length field of 11) a
|
|
|
|
|
+ marker field is used, which gives the length of the following datablock.
|
|
|
|
|
+ This is a simple 2 byte field (MSB first) containig the amount of data
|
|
|
|
|
+ following this field, not including this length field. After this datablock
|
|
|
|
|
+ another length field follows, which gives the size of the next datablock.
|
|
|
|
|
+ A value of 0 indicates the end of the packet. The maximum size of a
|
|
|
|
|
+ data block is limited to 65534, thereby reserving a value of 0xffff for
|
|
|
|
|
+ future extensions. These length markers must be insereted into the data
|
|
|
|
|
+ stream just before writing the data out.
|
|
|
|
|
+
|
|
|
|
|
+ This 2 byte filed is large enough, because the application must buffer
|
|
|
|
|
+ this amount of data to prepend the length marker before writing it out.
|
|
|
|
|
+ Data block sizes larger than about 32k doesn't make any sense. Note
|
|
|
|
|
+ that this may also be used for compressed data streams, but we must use
|
|
|
|
|
+ another packet version to tell the application that it can not assume,
|
|
|
|
|
+ that this is the last packet.
|
|
|
|
|
|
1998-04-04 20:16:55 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-06-09 15:14:06 +00:00
|
|
|
|
|
|
|
|
|
|
1998-04-04 20:16:55 +00:00
|
|
|
|
Keyserver Message Format
|
|
|
|
|
-------------------------
|
|
|
|
|
|
|
|
|
|
The keyserver may be contacted by a Unix Domain socket or via TCP.
|
|
|
|
|
|
1998-04-20 14:47:21 +00:00
|
|
|
|
The format of a request is:
|
1998-04-04 20:16:55 +00:00
|
|
|
|
|
|
|
|
|
----
|
|
|
|
|
command-tag
|
|
|
|
|
"Content-length:" digits
|
|
|
|
|
CRLF
|
|
|
|
|
------
|
|
|
|
|
|
|
|
|
|
Where command-tag is
|
|
|
|
|
|
1998-04-20 14:47:21 +00:00
|
|
|
|
NOOP
|
1998-04-04 20:16:55 +00:00
|
|
|
|
GET <user-name>
|
|
|
|
|
PUT
|
|
|
|
|
DELETE <user-name>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The format of a response is:
|
|
|
|
|
|
|
|
|
|
------
|
|
|
|
|
"GNUPG/1.0" status-code status-text
|
|
|
|
|
"Content-length:" digits
|
|
|
|
|
CRLF
|
|
|
|
|
------------
|
|
|
|
|
followed by <digits> bytes of data
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Status codes are:
|
|
|
|
|
|
|
|
|
|
o 1xx: Informational - Request received, continuing process
|
|
|
|
|
|
|
|
|
|
o 2xx: Success - The action was successfully received, understood,
|
|
|
|
|
and accepted
|
|
|
|
|
|
|
|
|
|
o 4xx: Client Error - The request contains bad syntax or cannot be
|
|
|
|
|
fulfilled
|
|
|
|
|
|
|
|
|
|
o 5xx: Server Error - The server failed to fulfill an apparently
|
|
|
|
|
valid request
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1998-05-26 13:38:00 +00:00
|
|
|
|
Ich werde jetzt doch das HKP Protokoll implementieren:
|
|
|
|
|
|
|
|
|
|
Naja, die Doku ist so gut wie nichtexistent, da gebe ich Dir recht.
|
|
|
|
|
In kurzen Worten:
|
|
|
|
|
|
|
|
|
|
(Minimal-)HTTP-Server auf Port 11371, versteht ein GET auf /pks/lookup,
|
|
|
|
|
wobei die Query-Parameter (Key-Value-Paare mit = zwischen Key und
|
|
|
|
|
Value; die Paare sind hinter ? und durch & getrennt). G<>ltige
|
|
|
|
|
Operationen sind:
|
|
|
|
|
|
|
|
|
|
- - op (Operation) mit den M<>glichkeiten index (gleich wie -kv bei
|
|
|
|
|
PGP), vindex (-kvv) und get (-kxa)
|
|
|
|
|
- - search: Liste der Worte, die im Key vorkommen m<>ssen. Worte sind
|
|
|
|
|
mit Worttrennzeichen wie Space, Punkt, @, ... getrennt, Worttrennzeichen
|
|
|
|
|
werden nicht betrachtet, die Reihenfolge der Worte ist egal.
|
|
|
|
|
- - exact: (on=aktiv, alles andere inaktiv) Nur die Schl<68>ssel
|
|
|
|
|
zur<75>ckgeben, die auch den "search"-String beinhalten (d.h.
|
|
|
|
|
Wortreihenfolge und Sonderzeichen sind wichtig)
|
|
|
|
|
- - fingerprint (Bei [v]index auch den Fingerprint ausgeben), "on"
|
|
|
|
|
f<>r aktiv, alles andere inaktiv
|
|
|
|
|
|
|
|
|
|
Neu (wird von GNUPG benutzt):
|
|
|
|
|
/pks/lookup/<gnupg_formatierte_user_id>?op=<operation>
|
|
|
|
|
|
|
|
|
|
Zus<EFBFBD>tzlich versteht der Keyserver auch ein POST auf /pks/add, womit
|
|
|
|
|
man Keys hochladen kann.
|
|
|
|
|
|