?? pki_x509.cpp
字號:
/* * Copyright (C) 2001 Christian Hohnstaedt. * * All rights reserved. * * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Neither the name of the author nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * * This program links to software with different licenses from: * * http://www.openssl.org which includes cryptographic software * written by Eric Young (eay@cryptsoft.com)" * * http://www.sleepycat.com * * http://www.trolltech.com * * * * http://www.hohnstaedt.de/xca * email: christian@hohnstaedt.de * * $Id: pki_x509.cpp,v 1.51 2003/01/06 19:35:51 chris Exp $ * */ #include "pki_x509.h"pki_x509::pki_x509(string d,pki_key *clientKey, pki_x509req *req, pki_x509 *signer, int days, int serial) :pki_base( d ){ init(); X509_NAME *issn, *reqn; if (!req) openssl_error("Request was null"); cert = X509_new(); openssl_error(); if (signer) { issn = X509_get_subject_name(signer->cert); trust =1; efftrust=1; } else { issn = X509_REQ_get_subject_name(req->request); signer = this; trust = 2; efftrust=2; // always trust our self created certs } // copy Requestinfo to New cert X509_set_pubkey(cert, X509_REQ_get_pubkey(req->request)); reqn = X509_REQ_get_subject_name(req->request); X509_set_subject_name(cert, X509_NAME_dup(reqn)); X509_set_issuer_name(cert, X509_NAME_dup(issn)); /* Set version to V3 */ X509_set_version(cert, 2); openssl_error(); setSerial(serial); setDates(days); /* Set up V3 context struct */ X509V3_set_ctx(&ext_ctx, signer->cert, cert, req->request, NULL, 0); X509V3_set_ctx_nodb((&ext_ctx)) setKey(req->getKey()); openssl_error();}pki_x509::pki_x509(X509 *c) : pki_base(){ init(); cert = c; openssl_error();}pki_x509::pki_x509(const pki_x509 *crt) :pki_base(crt->desc){ init(); cert = X509_dup(crt->cert); openssl_error(); psigner = crt->psigner; setKey(crt->pkey); trust = crt->trust; efftrust = crt->efftrust; revoked = M_ASN1_TIME_dup(crt->revoked); caSerial = crt->caSerial; caTemplate = crt->caTemplate; crlDays = crt->crlDays; lastCrl = M_ASN1_TIME_dup(crt->lastCrl); openssl_error();}pki_x509::pki_x509() : pki_base(){ init(); cert = X509_new(); openssl_error();}pki_x509::pki_x509(const string fname){ FILE *fp = fopen(fname.c_str(),"r"); init(); if (fp != NULL) { cert = PEM_read_X509(fp, NULL, NULL, NULL); if (!cert) { ign_openssl_error(); rewind(fp); CERR("Fallback to certificate DER"); cert = d2i_X509_fp(fp, NULL); } openssl_error(); int r = fname.rfind('.');#ifdef WIN32 int l = fname.rfind('\\');#else int l = fname.rfind('/');#endif desc = fname.substr(l+1,r-l-1); if (desc == "") desc = fname; openssl_error(); } else fopen_error(fname); fclose(fp); trust = 1; efftrust = 1;}pki_x509::~pki_x509(){ if (cert) { X509_free(cert); } if (revoked) { ASN1_TIME_free(revoked); } if (lastCrl) { ASN1_TIME_free(lastCrl); } if (pkey) pkey->decUcount(); openssl_error();}void pki_x509::init(){ psigner = NULL; pkey= NULL; trust = 0; efftrust = 0; revoked = NULL; caSerial = 1; caTemplate = ""; crlDays = 30; lastCrl = NULL; className = "pki_x509"; cert = NULL;}void pki_x509::setSerial(int serial){ ASN1_INTEGER_set(X509_get_serialNumber(cert), serial); openssl_error();}void pki_x509::setDates(int days){ X509_gmtime_adj(X509_get_notBefore(cert),0); X509_gmtime_adj(X509_get_notAfter(cert), (long)60*60*24*days); openssl_error();} void pki_x509::addV3ext(int nid, string exttext){ X509_EXTENSION *ext; int len; char *c = NULL; if ((len = exttext.length()) == 0) return; len++; c = (char *)OPENSSL_malloc(len); openssl_error(); strncpy(c, exttext.c_str(), len); ext = X509V3_EXT_conf_nid(NULL, &ext_ctx, nid, c); OPENSSL_free(c); if (!ext) { string x="v3 Extension: " + exttext; openssl_error(x); return; } X509_add_ext(cert, ext, -1); X509_EXTENSION_free(ext); openssl_error();}bool pki_x509::canSign(){ BASIC_CONSTRAINTS *bc; int crit; if (!pkey || pkey->isPubKey()) return false; bc = (BASIC_CONSTRAINTS *)X509_get_ext_d2i(cert, NID_basic_constraints, &crit, NULL); openssl_error(); if (!bc || !bc->ca) return false; return true;} bool pki_x509::hasSubAltName(){ STACK_OF(GENERAL_NAME) *subAlt; int crit; subAlt = (STACK_OF(GENERAL_NAME) *)X509_get_ext_d2i(cert, NID_subject_alt_name, &crit, NULL); openssl_error(); CERR("hasSubAlt: "<< sk_GENERAL_NAME_num(subAlt)); if (sk_GENERAL_NAME_num(subAlt) < 1) return false; return true;} void pki_x509::sign(pki_key *signkey){ if (!signkey) { openssl_error("There is no key for signing !"); } const EVP_MD *digest = EVP_md5(); X509_sign(cert, signkey->key, digest); openssl_error();}/* Save the Certificate to data and back: * Version 1: * int Version * int size of cert * cert * int trust * int size of revTime * revocationtime */ void pki_x509::fromData(unsigned char *p, int size){ int version, sCert, sRev, sLastCrl; unsigned char *p1 = p; version = intFromData(&p1); if (version >=1 || version <= 3) { sCert = intFromData(&p1); cert = d2i_X509(NULL, &p1, sCert); trust = intFromData(&p1); CERR( "Trust: " << trust ); sRev = intFromData(&p1); if (sRev) { revoked= d2i_ASN1_TIME(NULL, &p1, sRev); CERR("revoked time"); } else { revoked = NULL; } if (version == 1) { caTemplate=""; caSerial=1; lastCrl = NULL; crlDays=30; } if (version >= 2 ) { caSerial = intFromData(&p1); caTemplate = stringFromData(&p1); } if (version >= 3 ) { crlDays = intFromData(&p1); sLastCrl = intFromData(&p1); if (sLastCrl) { lastCrl = d2i_ASN1_TIME(NULL, &p1, sLastCrl); CERR("last CRL"<< sLastCrl); } else { lastCrl = NULL; } } } else { // old version cert = d2i_X509(NULL, &p, size); revoked = NULL; trust = 1; efftrust = 1; } openssl_error();}unsigned char *pki_x509::toData(int *size){#define PKI_DB_VERSION (int)3 CERR("cert toData"); unsigned char *p, *p1; int sCert = i2d_X509(cert, NULL); MARK int sRev = (revoked ? i2d_ASN1_TIME(revoked, NULL) : 0); MARK int sLastCrl = (lastCrl ? i2d_ASN1_TIME(lastCrl, NULL) : 0); MARK // calculate the needed size *size = caTemplate.length() + 1 + sCert + sRev + sLastCrl + (7 * sizeof(int)); openssl_error(); CERR("CertSize: "<<sCert << " RevSize: " <<sRev <<" CRLdatesize: "<< sLastCrl); p = (unsigned char*)OPENSSL_malloc(*size); p1 = p; intToData(&p1, (PKI_DB_VERSION)); // version intToData(&p1, sCert); // sizeof(cert) i2d_X509(cert, &p1); // cert intToData(&p1, trust); // trust intToData(&p1, sRev); // sizeof(revoked) if (sRev) { i2d_ASN1_TIME(revoked, &p1); // revokation date } // version 2 intToData(&p1, caSerial); // the serial if this is a CA stringToData(&p1, caTemplate); // the name of the template to use for signing // version 3 intToData(&p1, crlDays); // the CRL period
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -