glooxd  0.3-svn
certificategenerator.cpp
1 /*
2  Copyright (c) 2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the glooxd library. http://camaya.net/glooxd
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 #include "certificategenerator.h"
15 
16 #if defined( _WIN32 ) || defined ( _WIN32_WCE )
17 # include "../config.h.win"
18 #else
19 # include "config.h"
20 #endif
21 
22 #if defined( _WIN32 ) && !defined( __SYMBIAN32__ )
23 #include <windows.h>
24 #endif
25 
26 #ifdef HAVE_OPENSSL
27 #include <openssl/pem.h>
28 #include <openssl/conf.h>
29 #include <openssl/x509v3.h>
30 #ifndef OPENSSL_NO_ENGINE
31 #include <openssl/engine.h>
32 #endif
33 #endif
34 
35 namespace glooxd
36 {
37 
38  namespace util
39  {
40 
41 // bool generatePrivateKey( const std::string& path )
42 // {
43 // (void)path;
44 // return false;
45 // }
46 
47  bool generateCertificate( const std::string& domain,
48  const std::string& key,
49  const std::string& path,
50  int bits, int days, int serial )
51  {
52  if( domain.empty() || key.empty() || path.empty()
53  || bits < 1024 || days < 0 || serial <= 0 )
54  {
55  printf( "sth is wrong with the generated certificate\n" );
56  return false;
57  }
58 
59 #ifdef HAVE_OPENSSL
60  CRYPTO_mem_ctrl( CRYPTO_MEM_CHECK_ON );
61 
62  X509* x = X509_new();
63  FILE* fp = fopen( key.c_str(), "r" );
64  if( !fp )
65  return false;
66 
67  EVP_PKEY* pk = PEM_read_PrivateKey( fp, 0, 0, 0 );
68  fclose( fp );
69  fp = 0;
70 
71  if( !pk )
72  {
73  printf( "PEM_read_PrivateKey failed\n" );
74  return false;
75  }
76 
77  if( !x )
78  {
79  printf( "X509_new failed\n" );
80  return false;
81  }
82 
83  X509_set_version( x, 2 );
84  ASN1_INTEGER_set( X509_get_serialNumber( x ), serial );
85 
86  X509_gmtime_adj( X509_get_notBefore( x ), 0 );
87  X509_gmtime_adj( X509_get_notAfter( x ),
88  static_cast<long>( 60 * 60 * 24 * days ) );
89  X509_set_pubkey( x, pk );
90 
91  X509_NAME* name = X509_get_subject_name( x );
92  X509_NAME_add_entry_by_txt( name, "CN", MBSTRING_ASC,
93  reinterpret_cast<const unsigned char*>( domain.c_str() ),
94  -1, -1, 0 );
95  X509_set_issuer_name( x, name );
96 
97  if( !X509_sign( x, pk, EVP_sha1() ) )
98  {
99  printf( "X509_sign failed\n" );
100  return false;
101  }
102 
103  fp = fopen( path.c_str(), "w" );
104  if( !fp )
105  return false;
106 
107  PEM_write_X509( fp, x );
108  fclose( fp );
109  return true;
110 #else
111  printf( "no openssl!\n");
112  return false;
113 #endif
114  }
115 
116  }
117 
118 }