The Certificate Manager

It is the Certificate managers job to retrieve Certificates, verify Certificates, install new certificates. Together with the Registration authority (whose job is currently done by the Certification Authority) the Certification Authority has to establish means of providing verifiable certificates of three different types, namely Attribute, Key Certificates and Hybrid Certificates. Because the underlying SecuDE-RCModule probably won't be able to deliver Attribute (and thereby Hybrid Certificates), we have to accept pure Key Certificates for now (and hope that GMD will finish the X.509-v3 certificates soon).

The proces of issuing certificates can be divided into two subprocesses, namely registration at the RA and issuing a new certificate by CA based upon a registration issued by a RA that the certificate-issuing CA accepts as a RA. As CA and RA are currently coupled as one entity, the CA in effect only accepts registrations issued by itself.

In order for a module to support the certificate manager, it at least implement the Certificate interface. In addition to this interface the certificate block defines an interface that can be used for registration in RCModuleInterface .

Before doing anything else, the Certificate Manager has to be initialized by calling init in CertificateMan, with myID being the distinguished name of CA/RA or user, isCA equalling true if this is a CA/RA, and template being a generic Template to be used by this RA in the registration proces. As yet the Certificate Manager doesn't support more than one template at a time, and it will not be possible to use more than one during the first trial.

If the CertificateMan is invoked by a client to CA/RA, the myID should be a unique ID for that person (for instance :IDCardNr, like "DK:090169-1754" could be a unique identifier for a danish citizen). The client will find the DN according to an RA when it is needed or retrieve a new one from RA under the registration proces). The Template should be null if the Manager is started by a user (though templ is currently ignored, if this is a client to a CA/RA, so it doesn't really matter). I will firstly describe what is (should) happen(ing) on the client side. All methods referred to are found in CertificateMan (unless otherwise mentioned).

The Registration Process

Before the user can get registrated, (s)he has to retrieve a trusted public key of the RA. How this public key actually is retrieved isn't considered yet, but it might for instance come on a disk (maybe it is downloadable through the 'welcome'-www-page of the RA). One might consider giving the user a chance to verify this public key against some hashvalue also to be placed on the disk or on the 'welcome'-www-page.

This public key is called a trusted public key, as the user principally trusts its validity. When the user has received the trusted public key of the RA, he has to call installTrustedPK(String raDN, CryptoKeyInfo trustedPK). Hereafter he has to send a request to the RA for a template to be filled in by the user. This is done by calling sendTemplateRequest(ComPointAddress srvAddr, Vector options), which returns a Template sent by the server (options is currently always null).

The template will contain one filled field, namely the ra's distinguished name (transferred in the sendTemplateRequest). All other fields will have to be filled in by the user (which happens later).

Hereafter the user calls CryptoMan.generatePubKeyPair to generate a public key pair to be registrated with, and calls fillinTemplate(Template templ, CryptoKeyInfo pkey) with the template received from the server and the public key of the newly generated public key pair.

FillinTemplate returns a filled-in template to be sent to the RA via sendFilledTemplate.

The user now has to wait for the server to make a registration based upon this filled in template. (S)he can issue the commands checkRegistrationStatus and getRegistration in the meantime. CheckRegistrationStatus will check the status of the registration process and if it returns CertiticateConstants.REGISTRATION_FINALIZED, the registration is made an can be retireved via getRegistration. getRegistration will return null, if the registration isn't finalized and otherwise the registration.

After receiving the registration, the user can call checkRegistration(Registration reg), which will check the validity of the registration (currently only whether the signature is correct with respect to the trusted public key as installed in the first step).

Finally the user should call installRegistration(Registration reg) to save the registration via ArchiveMan. This completes the registration part.

The Certificate issuing process

The client can after registrating at an RA as described above use the returned registration to get one certificate issued for him(her) by the CA (only one certificate will be issued per registration). The user calls issueCertificateReq(ComPointAddress srvAddr, int serialNr int scope, int type, Date startValid, Date endValid). This will look up the registration done by the RA and the nr serialNr (which the user can retrieve by calling reg.getSerialNr(), if reg is the Registration returned by the RA. This should invoke a proces at the CA to issue a certificate for the pkey contained in the registration with nr. serialNr. This certificateshould contain the other parameters as well (reservedSN, scope, type, startValid and endValid). The secret key corresponding to the public key stored in the registration will be used to sign this request.

The server will then check the registration and issue a Certificate if the signature on the request is correct and the user requesting the Certificate is the same as the username in the registration. Hereafter the server will send the newly issued Certificate back to the client, and issueCertificateReq will return this Certificate.

The certificate can then be installed by calling installCertificate(Certificate cert).

Other services to clients

Apart from issuing certificates the user of course wants to retrieve certificates and verify them as well. This is handled by getCertificate(String DN, long serialNr, CryptoKeyInfo pkey, String CADN). This method will return a Vector of Certificates, that match the search datacertList. If only the distinguished name is given, all Certificates issued by all CA's, at which the user has registrated himself, are returned. If only the serialNr is given, all Certificates (one per CA) from the CA's the user has a registration at, with that serialNr are returned. The same holds true for the pkey. If more than one of DN, serialNr and pkey is given, the search is limited to those certificates satisfying these requirements. If a CADN is given (ie CADN!=null), only the CA with name CADN is asked for certificates, otherwise all CA's, the user has contacted in the registration phase, are called.

Finally the user is able to call verifyCertificate(Certificate cert), which will verify the certificates signature, whether the certificate is still valid, etc.

These methods could be used to establish an authentication proces: A user connects to a site (let's say OTTO's Homepage). OTTO have registrated themselves at the CA, that the client uses and have a list of serialNr's and the corresponding CA's at which OTTO have registrated themselves:

Certification Authority | SerialNr
----------------------------------
VBZ Bayern              | 1239087
Stiftung Warentest      | 9801272
...
----------------------------------
Now the user has registrated himself at VBZ Bayern, and uses cert=getCertificate("OTTO",1239087,null,"VBZ Bayern") to retrieve a certificate from VBZ Bayern issued for OTTO under the serialNr 1239087. He can check this certificate by verifyCertificate(cert) and if it returns OK, then this certificate and the public Key inside this certificate are OK - as of now the user might still want to check, whether the certificate is to be used to sign messages with, but as the SecuDE-certificates to be used in the first trial probably aren't supporting this field, the getType() will only return CertificateConstants.TYPE_NYI (Type NotYetImplemented), so the check is of no real use right now.

If this certificate exists, the user can use the public Key given in this Certificate to verify signatures from OTTO. Of course he has to intially tell OTTO, that they should sign their messages with this CryptoKeyInfo, but this is not the concern of the certificate Manager.

Apart from these methods the user can issue the commands sendCertificateChangeReq(Certificate newCert, CryptoKeyInfo skey), where newCert is how the user would like the Certificate identified by newCert.getSerialNr() at newcert.getCADN() to look like after the change (this Certificate is signed through the skey, corresponding to the public Key in the Certificate). The user can also use sendRegistrationChangeReq(Registration newReg, CryptoKeyInfo skey), where newReg corresponds to the new look of the registration and the skey is the secret key corresponding to the public key inside the registration.

The Server Side

On the CA-server side things are currently much easier for other managers/layers. The server has to call CertificateMan.init() just as the client has to do (though isCA should be true and the Template should be a Template, ie not null, for instance new Template(). The server can thereafter go into an endless loop calling handleRequest(ChannelServicePointThread, Vector options), where the options-vector currently should be null.

This loop should run in thread for itself, while the server will also be able make other things (like revokeCertificate()).

All the incoming requests from the client (as stated before) are handled by this method (which in turn calls other methods that are doing the real work). Apart from the handling of requests the manager will provide the possibility of revoking certificates and registrations by revokeRegistration(Registration reg), revokeCertificate(certificate), revokeAllCertificates(String DN) and revokeAllRegistrations(String DN). The handleRequest() funtion will return CHANGE_CERTIFICATE_REQ and CHANGE_REGISTRATION_REQ respectively, if the user has asked to change something in the Certificate/Registration. The server should then provide means of checking whether the requested changes will be made or not. The existing Certificate/Registrations SerialNr which the user wants to change can be retrieved via getExistingCert(String DN) and getExistingReg(String DN) respectively, and it's only possible to change one Certificate/Registration at a time.

If the server accepts the changes, the Certificate Manager can call acceptChangeReg(String DN) and acceptChangeCert(String DN) in order to tell the server that the changes are accepted. number cert.getSerialNo() (if cert is returned by handleRequest) to content the data from cert.

This loop should run in thread for itself, while the server will also be able make other things (like revokeCertificate()).

All the incoming requests from the client (as stated before) are handled by this method (which in turn calls other methods that are doing the real work). Apart from the handling of requests the manager will provide the possibility of revoking certificates and registrations by revokeRegistration(Registration reg), revokeCertificate(certificate), revokeAllCertificates(String DN) and revokeAllRegistrations(String DN). The handleRequest() funtion will return CHANGE_CERTIFICATE_REQ and CHANGE_REGISTRATION_REQ respectively, if the user has asked to change something in the Certificate/Registration. The server should then provide means of checking whether the requested changes will be made or not. The existing Certificate/Registrations SerialNr which the user wants to change can be retrieved via getExistingCert(String DN) and getExistingReg(String DN) respectively, and it's only possible to change one Certificate/Registration at a time.

If the server accepts the changes, the Certificate Manager can call acceptChangeReg(String DN) and acceptChangeCert(String DN) in order to tell the server that the changes are accepted.