Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

wvx509.h

Go to the documentation of this file.
00001 /* -*- Mode: C++ -*-
00002  * Worldvisions Weaver Software:
00003  *   Copyright (C) 1997-2002 Net Integration Technologies, Inc.
00004  *
00005  * X.509 certificate management classes.
00006  */ 
00007 #ifndef __WVX509_H
00008 #define __WVX509_H
00009 
00010 #include "wvrsa.h"
00011 #include "wvlog.h"
00012 
00013 // Structures to make the compiler happy so we don't have to include x509v3.h ;)
00014 struct x509_st;
00015 typedef struct x509_st X509;
00016 
00017 // workaround for the fact that OpenSSL initialization stuff must be called
00018 // only once.
00019 void wvssl_init();
00020 void wvssl_free();
00021 WvString wvssl_errstr();
00022 
00023 
00024 /**
00025  * X509 Class to handle certificates and their related
00026  * functions
00027  */
00028 class WvX509Mgr
00029 {
00030 public:
00031    /** Distinguished Name to be used in the certificate. */
00032     WvString dname;
00033 
00034    /**
00035     * Type for the @ref dump() method, which can output the information
00036     * in this class in a variety of formats
00037     */
00038     enum DumpMode { CertPEM = 0, RsaPEM, RsaRaw };
00039 
00040    /**
00041     * Initialize a blank X509 Object with the certificate *cert
00042     * (used for client side operations...)
00043     * 
00044     * This either initializes a completely empty object, or takes _cert, and extracts
00045     * the distinguished name into dname, and the the RSA public key into rsa. rsa->prv is empty.
00046     */
00047     WvX509Mgr(X509 *_cert = NULL);
00048 
00049     /** Constructor to initialize this object with a pre-existing certificate and key */
00050     WvX509Mgr(WvStringParm hexcert, WvStringParm hexrsa);
00051 
00052     /**
00053      * Constructor to create a selfsigned certificate for dn dname
00054      * NOTE: If you already have a WvRSAKey, then you can shove it
00055      * in here in the second parameter (i.e.: If you wanted to generate a
00056      * cert for an existing TunnelVision connection), or if you don't have an 
00057      * RSA Key yet, you can just give it a number of bits, and it will create 
00058      * one for you.
00059      *
00060      * Also: For SSL Servers:
00061      * the dname MUST be in the form: cn=FQDN,o=foo,c=CA
00062      * (actually, any part after the cn=FQDN is up to you... dc= works as well..)
00063      *
00064      * But the important bit is to use the Fully Qualified Domain Name in 
00065      * the cn= part - otherwise Web Clients get confused...(I imagine other
00066      * server clients will get equally confused, but I haven't checked).
00067      * I don't check for this, since other kinds of certificates are perfectly
00068      * valid without this... If you want to generate invalid certs, that's up
00069      * to you.
00070      */
00071     WvX509Mgr(WvStringParm _dname, WvRSAKey *_rsa);
00072     WvX509Mgr(WvStringParm _dname, int bits);
00073     
00074     /** Placeholder: this doesn't exist yet. */
00075     WvX509Mgr(const WvX509Mgr &mgr);
00076 
00077     /** Destructor */
00078     virtual ~WvX509Mgr();
00079 
00080     /** X.509v3 Certificate - this is why this class exists */
00081     X509     *cert;
00082 
00083     /**
00084      * The Public and Private RSA keypair associated with this certificate
00085      * Make sure that you save this somewhere!!! If you don't, then you won't
00086      * really be able to use the certificate for anything...
00087      */
00088     WvRSAKey *rsa;
00089     
00090     /**
00091      * Given the Distinguished Name dname and an already generated keypair in 
00092      * rsa, return a Self Signed Certificate in cert.
00093      */
00094     void create_selfsigned();
00095 
00096     /**
00097      * Create a certificate request (PKCS#10) using this function.. this 
00098      * request is what you would send off to Verisign, or Entrust.net (or any
00099      * other CA), to get your real certificate. It leaves the RSA key pair
00100      * in rsa, where you MUST save it for the certificate to be AT ALL
00101      * valid when you get it back. Returns a PEM Encoded PKCS#10 certificate
00102      * request, and leaves the RSA keypair in rsa, and a self-signed temporary
00103      * certificate in cert.
00104      */    
00105     WvString certreq();
00106     
00107     /**
00108      * test to make sure that a certificate and a keypair go together.
00109      * called internally by unhexify() although you can call it if 
00110      * you want to test a certificate yourself
00111      */
00112     bool test();
00113 
00114     /**
00115      * Given a hexified certificate, fill the cert member NOTE: ALWAYS load
00116      * your RSA Keys before calling this! It is best if you have hexify()'d
00117      * keys to simply use the proper constructor. 
00118      */
00119     void unhexify(WvStringParm encodedcert);
00120     
00121     /**
00122      * Given the X509 certificate object cert, return a hexified string
00123      * useful in a WvConf or UniConf file.
00124      * 
00125      * I don't provide a similar function for that for the rsa key, because
00126      * you can always call rsa->private_str() and rsa->public_str()
00127      * for that information.
00128      */
00129     WvString hexify();
00130 
00131     /**
00132      * Function to verify the validity of a certificate that has been
00133      * placed in cert. Currently, this only outputs some information about
00134      * the certificate but eventually, it should be used to verify that the
00135      * certificate is valid (has not expired, and was issued by a valid and
00136      * trusted CA) 
00137      */
00138     bool validate();
00139    
00140     /**
00141      * Check the certificate in cert against the CA certificates in
00142      * certfile - returns true if cert was signed by one of the CA
00143      * certificates.
00144      */
00145     bool signedbyCAindir(WvStringParm certdir);
00146    
00147     /**
00148      * Check the certificate in cert against the CA certificates in certdir
00149      * - returns true if cert was signed by one of the CA certificates. 
00150      */
00151    bool signedbyCAinfile(WvStringParm certfile);
00152 
00153     /**
00154      * Sign the X509 certificate in cert with CAKeypair
00155      *
00156      * NOT IMPLEMENTED
00157      */
00158     void sign(WvRSAKey CAKeypair);
00159    
00160     /**
00161      * Check and see if the certificate in cert has been revoked... currently
00162      * relies on the CRL Distribution Point X509v3 extension...
00163      * returns true if it has expired
00164      * 
00165      * NOT IMPLEMENTED
00166      */
00167     bool isinCRL();
00168 
00169     /** Return the information requested by mode as a WvString. */
00170     WvString encode(const DumpMode mode);
00171 
00172     /**
00173      * Load the information from the format requested by mode into
00174      * the class - this overwrites the certificate, and possibly the
00175      * key - and to enable two stage loading (the certificate first, then the
00176      * key), it DOES NOT call test() - that will be up to the programmer
00177      */
00178     void decode(DumpMode mode, WvStringParm PemEncoded);
00179 
00180     /**
00181      * And of course, since PKCS12 files are in the rediculous DER encoding 
00182      * format, which is binary, we can't use the encode/decode functions, so
00183      * we deal straight with files... *sigh*
00184      *  
00185      * As should be obvious, this writes the certificate and RSA keys in PKCS12
00186      * format to the file specified by filename.
00187      */
00188     void write_p12(WvStringParm filename);
00189     
00190     /**
00191      * And this reads from the file specified in filename, and fills the RSA and
00192      * cert members with the decoded information.
00193      */
00194     void read_p12(WvStringParm filename);
00195 
00196     /** Sets the PKCS12 password */
00197     void setPkcs12Password(WvStringParm passwd)
00198         { pkcs12pass = passwd; }
00199 
00200     /** 
00201      * Return the Certificate Issuer (usually the CA who issued 
00202      * the certificate)
00203      */
00204     WvString get_issuer();
00205 
00206     /**
00207      * Return the Subject field of the certificate
00208      */
00209     WvString get_subject();
00210 
00211     /**
00212      * Return the CRL Distribution points if they exist, WvString::null
00213      * if they don't.
00214      */
00215     WvString get_crl_dp();
00216 
00217     /**
00218      * Return the Certificate Policy OID if it exists, and WvString::null
00219      * it if doesn't.
00220      */
00221     WvString get_cp_oid();
00222 
00223     /**
00224      * Return the Subject alt name if it exists, and WvString::null if
00225      * it doesn't.
00226      */
00227     WvString get_altsubject();
00228 
00229     /**
00230      * Is this certificate Object valid, and in a non-error state
00231      */
00232     bool isok() const
00233         { return cert && rsa && !errstring; }
00234 
00235     /**
00236      * Accessor for the error string if !isok()
00237      */
00238     const WvString &errstr()
00239         { return errstring; }
00240 
00241 private:
00242     WvLog debug;
00243     WvString errstring;
00244 
00245    /** 
00246     * Password for PKCS12 dump - we don't handle this entirely correctly 
00247     * since we should erase it from memory as soon as we are done with it
00248     */
00249     WvString pkcs12pass;
00250 
00251     void seterr(WvStringParm s)
00252         { if (!errstring) errstring = s; }
00253 
00254     void seterr(WVSTRING_FORMAT_DECL)
00255         { seterr(WvString(WVSTRING_FORMAT_CALL)); }
00256 
00257     /**
00258      * Get the Extension information - returns NULL if extension doesn't exist
00259      */
00260     WvDynBuf *get_extension(int nid);
00261 };
00262 
00263 #endif // __WVX509_H

Generated on Wed Dec 15 15:08:12 2004 for WvStreams by  doxygen 1.3.9.1