This is version  0.41 of my certificate patcher.

Simple Program arguments.

-in cert.pem      input certificate.
-out cert.pem     output certificate.
-caset            set cA flag, add basic constraints
-caunset          don't set cA flag, add basic constraints
-caclr            delete basic constraints
-pathlen n        set path length to 'n'
-bscrit           make basic constraints critical
-nscrit           make nscertype critical (not recommended)
-nscertype num    set nscertype to num
-nsclr            delete nscertype
-inkey pkey.pem   private key of signer

Note: there are a few undocumented options that are currently under test. They
will be documented in due course.

E.g. for a normal CA:

ca-fix -in cacert.pem -inkey pkey.pem -caset -nscertype 6 -out newca.pem

Most of the arguments should be self explanatory. Note with -inkey you *must*
sign with the issuers private key or the certificate signature will fail. For
the usual self-signed CA this is the certficates own private key. For other
kinds it is the private key of the issuing CA. 

The -pathlen parameter specifies the maximum CA chain length. For example if
this is set to zero then any certificates signed by this CA cannot themselves
be CA certificates. Setting this to one would allow this CA to sign subordinate
CA certificates but the subordinate CAs would not be allowed to sign CA
certificates. If the software you are using interprets this parameter correctly
then it allows some control over what subordinate CAs are allowed to do.

The -bscrit option sets the critical flag for basic constraints: it is not set
by default. I've restored the no critical default behaviour because critical
extensions break Outlook 98. The -nobscrit flag is still accepted but it does
nothing.

The -nscrit flag sets the critical flag of netscape-certificate-type. It is
strongly recommended that this option is not used because any implementation
that does not interpret this extension will reject the certificate as invalid.
For example Outlook 98 does this. Of course if you *want* this behaviour feel
free to use the option...

Try using verify on the new certificate after using the program.

You can also use this program to mess around with user certificates to e.g.
change the value of nsCerType. Naturally you should use the issuing CAs private
key to sign the certificate.

Here are the currently used values for nsCertType or netscape-certificate-type
number may be decimal or hex with the 0x prefix. Add together the options you
need.

0x80 - Used for SSL client authentication.
0x40 - Used for an SSL server.
0x20 - Used for S/MIME email.
0x10 - Object signing certificate.
0x4  - SSL client CA.
0x2  - S/MIME CA.
0x1  - Object signing CA.

The extension is only really mandatory for object signing certificates (and CAs
according to the documentation but this is not enforced). It is also useful if
you want to restrict the uses of a certificate.

In actual fact the above value for nsCertType are those specified in the
Netscape documentation. Netscape Communicator for example is somewhat more
"generous" in its interpretation, for example it will allow certificates without
the S/MIME bit set to be used for S/MIME. Check my online documentation for a
fuller description of how Netscape Communicator actually interprets this
extension. If in doubt check to see if the restrictions you place on a
certificate are actually enforced.

Note Netscape 4.5PR1 doesn't like netscape-certificate-type in CA certificates
at all: this is a bug. If you want compatability with PR1 then don't include
this extension in CA certificates.

Advanced options.

WARNING: the following section should only be read by those who have a
reasonable undertanding of X509 and possibly ASN1 too. Use of these options by
the unwary can result in corrupt or invalid certificates.

-setkey           changed certificate public key to match signer
-delext ext       delete extension (can use OID)
-ext genopt  val  add several extensions
-Cext genopt val  add several critical extensions
genopt can be:    keyUsage, nsCertType, nsBaseUrl, nsRevocationUrl,
                  nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl,
                  nsSslServerName, nsComment
-rawext opt HEX   add raw extension (can use OID)
-Crawext opt HEX  add critical raw extension (can use OID)

I started adding these options when I occasionally wanted to mess around with
all kinds of certificates and trace problems or determine why they exhibit 
certain behaviour.

You can't use someone elses certificate directly because you don't have the
private key: however using the advanced -setkey option you can set the key
to anything you want.

Similarly extensions can do strange things. Using the -delext option you can
delete any extension to trace which ones are causing the trouble.

Using the -ext and -Cext you can add several simple extensions.

Finally using -rawext and -Crawext you can add any extension you like, however
you have to pass it the raw DER encoding of the extension.

Steve. shenson@drh-consultancy.demon.co.uk

