reSIProcate/stack  9694
makeCert.cxx
Go to the documentation of this file.
00001 
00002 #if defined(HAVE_CONFIG_H)
00003   #include "config.h"
00004 #endif
00005 
00006 #if defined(USE_SSL)
00007 #include <openssl/ssl.h>
00008 #include <openssl/pem.h>
00009 #include <openssl/ossl_typ.h>
00010 #include <openssl/x509.h>
00011 #include <openssl/x509v3.h>
00012 #include "resip/stack/X509Contents.hxx"
00013 #include "resip/stack/Pkcs8Contents.hxx"
00014 #include "resip/stack/MultipartMixedContents.hxx"
00015 #include "resip/stack/Uri.hxx"
00016 #include "rutil/Random.hxx"
00017 
00018 using namespace resip;
00019 
00020 int makeSelfCert(X509** selfcert, EVP_PKEY* privkey);
00021 
00022 int main()
00023 {
00024    int err;
00025    Uri aor;
00026    Data passphrase;
00027    RSA *rsa = NULL;
00028    EVP_PKEY *privkey = NULL;
00029    X509 *selfcert = NULL;
00030    BUF_MEM *bptr = NULL;
00031 
00032    // initilization:  are these needed?
00033 //   CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
00034 //   bio_err=BIO_new_fp(stderr, BIO_NOCLOSE);
00035  
00036    Random::initialize();
00037 
00038    rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL);
00039    assert(rsa);    // couldn't make key pair
00040 
00041    EVP_PKEY_assign_RSA(privkey, rsa);
00042    assert(privkey);
00043 
00044    selfcert = X509_new();
00045    err = makeSelfCert(&selfcert, privkey);
00046    assert(!err);   // couldn't make cert
00047    
00048    unsigned char* buffer = NULL;     
00049    int len = i2d_X509(selfcert, &buffer);   // if buffer is NULL, openssl
00050                                   // assigns memory for buffer
00051    assert(buffer);
00052    Data derData((char *) buffer, len);
00053    X509Contents *certpart = new X509Contents( derData );
00054    assert(certpart);
00055     
00056    // make an in-memory BIO        [ see  BIO_s_mem(3) ]
00057    BIO *mbio = BIO_new(BIO_s_mem());
00058 
00059    // encrypt the the private key with the passphrase and put it in the BIO in DER format
00060    i2d_PKCS8PrivateKey_bio( mbio, privkey, EVP_des_ede3_cbc(), 
00061       (char *) passphrase.data(), 
00062       passphrase.size(), NULL, NULL);
00063 
00064    // dump the BIO into a Contents
00065    BIO_get_mem_ptr(mbio, &bptr);
00066    Pkcs8Contents *keypart = new Pkcs8Contents(Data(bptr->data, bptr->length));
00067    assert(keypart);
00068    BIO_free(mbio);
00069 
00070    MultipartMixedContents *certsbody = new MultipartMixedContents;
00071    certsbody->parts().push_back(certpart);
00072    certsbody->parts().push_back(keypart);
00073    assert(certsbody);
00074 }
00075 
00076 
00077 int makeSelfCert(X509 **cert, EVP_PKEY *privkey)   // should include a Uri type at the end of the function call
00078 {
00079   int serial;
00080   assert(sizeof(int)==4);
00081   const long duration = 60*60*24*30;   // make cert valid for 30 days
00082   X509* selfcert = NULL;
00083   X509_NAME *subject = NULL;
00084   X509_EXTENSION *ext = NULL;
00085 
00086   Data domain("example.org");
00087   Data userAtDomain("user@example.org");
00088 
00089   // Setup the subjectAltName structure here with sip:, im:, and pres: URIs
00090   // TODO:
00091 
00092   selfcert = *cert;
00093   
00094   X509_set_version(selfcert, 2L);       // set version to X509v3 (starts from 0)
00095 
00096   //  RAND_bytes((char *) serial , 4);
00097   //serial = 1;
00098   serial = Random::getRandom();  // get an int worth of randomness
00099   ASN1_INTEGER_set(X509_get_serialNumber(selfcert),serial);
00100 
00101   X509_NAME_add_entry_by_txt( subject, "O",  MBSTRING_UTF8, (unsigned char *) domain.data(), domain.size(), -1, 0);
00102   X509_NAME_add_entry_by_txt( subject, "CN", MBSTRING_UTF8, (unsigned char *) userAtDomain.data(), userAtDomain.size(), -1, 0);
00103 
00104   X509_set_issuer_name(selfcert, subject);
00105   X509_set_subject_name(selfcert, subject);
00106 
00107   X509_gmtime_adj(X509_get_notBefore(selfcert),0);
00108   X509_gmtime_adj(X509_get_notAfter(selfcert), duration);
00109 
00110   X509_set_pubkey(selfcert, privkey);
00111 
00112   // need to fiddle with this to make this work with lists of IA5 URIs and UTF8
00113   //ext = X509V3_EXT_conf_nid( NULL , NULL , NID_subject_alt_name, subjectAltNameStr.cstr() );
00114   //X509_add_ext( selfcert, ext, -1);
00115   //X509_EXTENSION_free(ext);
00116 
00117   ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, "CA:FALSE");
00118   X509_add_ext( selfcert, ext, -1);
00119   X509_EXTENSION_free(ext);
00120 
00121   // add extensions NID_subject_key_identifier and NID_authority_key_identifier
00122 
00123   X509_sign(selfcert, privkey, EVP_sha1());
00124 
00125   return true; 
00126 }
00127 #endif 
00128 
00129 /* ====================================================================
00130  * The Vovida Software License, Version 1.0 
00131  * 
00132  * Copyright (c) 2000-2005 Vovida Networks, Inc.  All rights reserved.
00133  * 
00134  * Redistribution and use in source and binary forms, with or without
00135  * modification, are permitted provided that the following conditions
00136  * are met:
00137  * 
00138  * 1. Redistributions of source code must retain the above copyright
00139  *    notice, this list of conditions and the following disclaimer.
00140  * 
00141  * 2. Redistributions in binary form must reproduce the above copyright
00142  *    notice, this list of conditions and the following disclaimer in
00143  *    the documentation and/or other materials provided with the
00144  *    distribution.
00145  * 
00146  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00147  *    and "Vovida Open Communication Application Library (VOCAL)" must
00148  *    not be used to endorse or promote products derived from this
00149  *    software without prior written permission. For written
00150  *    permission, please contact vocal@vovida.org.
00151  *
00152  * 4. Products derived from this software may not be called "VOCAL", nor
00153  *    may "VOCAL" appear in their name, without prior written
00154  *    permission of Vovida Networks, Inc.
00155  * 
00156  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00157  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00158  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00159  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00160  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00161  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00162  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00163  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00164  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00165  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00166  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00167  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00168  * DAMAGE.
00169  * 
00170  * ====================================================================
00171  * 
00172  * This software consists of voluntary contributions made by Vovida
00173  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00174  * Inc.  For more information on Vovida Networks, Inc., please see
00175  * <http://www.vovida.org/>.
00176  *
00177  */