ldap certificate problems (bugs?)

Brynjulv Hauksson (Brynjulv.Hauksson@nr.no)
Sat, 28 Jan 95 17:31:20 +0100

The Setting:

We are using a set of programs on a PC to handle certificates.
These programs are capable of reading X.500 Certificate's
in "raw" ASN.1 from a file. We thought it might be a good idea to
write a simple DOS LDAP client (using ldap-3.1) which could fetch
Certificate's from X.500.
Since the DOS client receives a Certificate in textual form, we would
need to parse it into some intermediate C-structure
(quipu's `struct certificate' possibly), and then encode
this (probably using routines from `liblber').

The Problem:

What is the textual syntax of an ldap certificate supposed to be like?
There seem to be at least four different candidates:
- rfc1488-cerificate-syntax
(which seems to omit a number of the values in a X.500 Certificate.
there are probably good reasons why it does so, but what are the resons?
is it possible to recreate a valid X.500 Certificate?)
- quipu-cerificate-syntax
(as described in the quipu manuals)
- ldapd-print-cerificate-syntax
(the syntax actually used by ldapd's certificate printer)
- ldapd-parse-cerificate-syntax
(the syntax actually used by ldapd's certificate parser)
the last two syntaxes seem to assume that two of the algoritms in an X.500
Certificate should be identical. Is this always a valid assumption?

Possible `ldapd' Bugs:

(Where should this sort of thing go -- to ldap@umich.edu,
to ldap-support@umich.edu, or to bug-ldap@umich.edu?)
- ldapd does not seem to parse the same Certificate syntax as it prints.
- ldapd installs a parser and a printer for Cerificate's,
but these are *not* used when printing values of type CertificatePair
(quipu's standard Certificate printer seems to be used instead).

Syntax Details:

The various syntaxes all seem to parse to/from a `struct certificate'
as defined in the header "quipu/authen.h".
looking at `dsap/x500as/af.py', a Certificate seems to be encoded/decoded
into the various fields of a `struct certificate' as follows:
Certificate ::= SEQUENCE { -- to/from field:
version [0] Version DEFAULT v1988 , -- version
serialNumber CertificateSerialNumber , -- serial
signature AlgorithmIdentifier, -- alg
issuer Name , -- issuer
validity Validity , -- valid
subject Name , -- subject
subjectPublicKeyInfo SEQUENCE {
algorithm AlgorithmIdentifier, -- key.alg
subjectPublicKey BIT STRING -- key.value
AlgorithmIdentifier, -- sig.alg
BIT STRING -- sig.encrypted

<rfc1488-cerificate-syntax> ::= -- to/from field (i'm guessing here):
<signature> '#' -- sig.alg (oid "#" param)
<issuer> '#' -- issuer (DN)
<validity> '#' -- valid
<subject> '#' -- subject (DN)
<public-key-info.algorithm-id> '#' -- key.alg (oid "#" param)
<public-key-info.encrypted-value> -- key.value (hexstring)
("missing" fields: version, serial, sig.encrypted, alg)

<quipu-cerificate-syntax> ::= -- to/from field:
<Algorithm> "#" -- sig.alg (oid "#" param)
<EncryptedValue> "#" -- sig.encrypted(hexstring)
<Issuer> "#" -- issuer (DN)
<Subject> "#" -- subject (DN)
<Algorithm> "#" -- alg (oid "#" param)
<ProtocolVersion> "#" -- version (integer)
<Serial> "#" -- serial (integer)
<Validity> "#" -- valid (UTCTime "#" UTCTime)
<Algorithm> "#" -- key.alg (oid "#" param)
<EncryptedValue> -- key.value (hexstring)

the ldapd Certificate printer uses the following syntax,
specified in `ldap-3.1/servers/ldapd/certificate.c'.
(actually, it appends an extra '#' at the end, as does the quipu printer):

<ldapd-print-cerificate-syntax> ::= -- from field:
<version> '#' -- version
<serial> '#' -- serial
<signature-algorithm-id> '#' -- sig.alg
<issuer> '#' -- issuer
<validity> '#' -- valid
<subject> '#' -- subject
<public-key-info.algorithm-id> '#' -- key.alg
<public-key-info.encrypted-value> '#' -- key.value
<encrypted-value> -- sig.encrypted
(and ignores the `alg' field)

Judging from the `ldap_str2cert' function,
the ldapd Certificate parser appears to want the following syntax:
<ldapd-parse-cerificate-syntax> ::= -- to field:
<algorithm-id> '#' -- sig.alg
<encrypted-value> '#' -- sig.encrypted
<version> '#' -- version
<serial> '#' -- serial
<issuer> '#' -- issuer
<validity> '#' -- valid
<subject> '#' -- subject
<algorithm-id> '#' -- key.alg
<encrypted> -- key.value
(and copies `sig.alg' to `alg')