The program ca-fix is a certificate patching program. It was
originally designed to patch SSLeay generated V1 CA certificates but it
can be used to
patch end user certificates as well and as a test utility.
You can download version (0.41) of the program here.
The only changed from 0.4 is that the setkey option is now supported. The code got accidentally removed in the last version.
The original motivation was to allow SSLeay V1 CA certificates to be properly recognized as CA certificates by Netscape. For more details of why this is a good idea see: Netscape CA handling: When is a CA Not a CA?
E.g. for a typical CA:
ca-fix -in cacert.pem -inkey pkey.pem -caset -nscertype 6 -out newca.pem
Most of the arguments should be self explanatory. A few need further explanation.
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 certificates 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. Basic constraints is a standard certificate extension it should be interpreted correctly by any reasonable software: making this extension to critical is acceptable (and advisable). Unfortunately Microsoft Outlook 98 chokes on critical extensions so its now off by default.
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 non standard extension will reject the certificate as invalid. For example Outlook 98 does this. If you don't mind or want this behaviour then feel free to use the option...
Try using the verify program on the new certificate after using the program to check the signature.
You can also use this program to mess around with user certificates to e.g. change the value of nsCertType. 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||SSL client authentication.|
|0x04||SSL Client CA.|
|0x01||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.
If you check the Netscape documentation you will find that the above values seem to be wrong. They aren't: it's just due to the way the BIT STRINGS work. You need to reverse the order of the bits of each byte.
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 document Netscape Certificate Type Behaviour 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.
Firstly a bit of backround. ca-fix was originally intended just to fix up CA certificates. I found though that I would occasionally come across a certificate with unusual behaviour and I wanted to track down the cause.
You can't just use someone elses certificate because you don't know the private key. Similarly you can't just paste in you own public key because that would break the signature.
Similarly I wanted a way to delete and add various certificate extensions to see what they did.
Add all these requirements together and you get the advanced options.
Here is a list of these options followed by a brief explanation.
change 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,
-rawext opt HEX add raw extension (can use OID)
-Crawext opt HEX add critical raw extension (can use OID)
-rawfile opt fn add raw extension from file.
-Crawfile opt fn add critical raw extension from file.
-extusage OID add extended key usage OID (can be used more than once).
-extcrit make extended key usage critical.
-extparse ASN1 parse extensions.
-exthex hexdump extensions.
To see why setkey is useful suppose you have two certificates ca.pem (a root CA certificate) and user.pem (an end user certificate) which do something odd. You can't use them directly but you can use two almost identical certificates for diagnostic purposes. Firstly you would create two privake key files (with, for example, genrsa -out key.pem 1024) call these cakey.pem and userkey.pem.
First you need to set the ca public key and resign the certificate:
ca-fix -in ca.pem -setkey -inkey cakey.pem -out myca.pem
The CA public key now matches the generated key in cakey.pem.
Now you need to do the same with the end user certificate:
ca-fix -in user.pem -setkey -inkey userkey.pem -out usertmp.pem -nosign
Finally you need to sign the new user certificate with the CA key,
since you have already set the public key you don't use the setkey
ca-fix -in usertmp.pem -inkey cakey.pem -out myuser.pem
You would then want to check it worked using verify:
verify -CAfile myca.pem myuser.pem
You can now use the certificates because you have the referenced private keys. You should note this is not a security problem because you can't just forge the use of these certificates in a trusted environment because the keys have changed. Its only useful for test and diagnostic purposes.
Now suppose these new certificates exhibit the same unusual behaviour. Maybe it's caused by some weird extension? That's where the delext option comes in. Suppose you suspect an extension with OID 184.108.40.206 then you can delete it with:
ca-fix -in myuser.pem -out myuser2.pem -delext 220.127.116.11 -inkey cakey.pem
A note about the ext and Cext options. Using these you can set the standard extensions keyUsage, nsCertType, nsBaseUrl, nsRevocationUrl, nsCaRevocationUrl, nsRenewalUrl, nsCaPolicyUrl, nsSslServerName, nsComment.
keyUsage is a standard extension referenced in, for example the PKIX documentation. The others are Netscape specific extensions that are described here, it also describes how Netscape products handle keyUsage. keyUsage and nsCertType both take an integer argument (with 0x prefix for hex) all the others take a string argument. As is usual with integer BIT STRING arguments you should reverse the bit order of each byte.
Finally the really advanced options: rawext and Crawext. These allow you to add any extension you want, but unfortunately you need to give it the full DER encoding of the extension. Suppose for example you saw a certificate with an extension with OID 18.104.22.168 and its contents were: 30030101FF (in hex). You could do this with:
ca-fix -in myca.pem -out myca2.pem -rawext 22.214.171.124 30030101FF -inkey cakey.pem
This isn't the best example in the world because it's just basic constraints which you can more easily add with just the caset option.
The rawfile and Crawfile do the same but take extensions from a file.
The extparse option gives and ASN1 dump of the certificate extensions. To use it try:
ca-fix -in cert.pem -nosign -noout -extparse
The exthex option is similar except it gives a hex dump of the extensions. This make it possible to use the output in a rawext or Crawext option.
This can be used to print out a hex dump of an extension which can then be used to add the DER encoding of the extension manually in another product (e.g. NS certificate server). For example if you want the DER encoding of basicConstraints with a path length of 10:
ca-fix -in cert.pem -nosign -caset -pathlen 10 -exthex
will print it out.
All comments see my contact page.