/* Copyright (C) 2003 Frédéric Giudicelli (contact_nos@yahoo.com). All rights reserved. This product includes cryptographic software written by Eric Young (eay@cryptsoft.com) This program is released under the GPL with the additional exemption that compiling, linking, and/or using OpenSSL is allowed. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ // PubStore.cpp: implementation of the PubStore class. // ////////////////////////////////////////////////////////////////////// #include "PubStore.h" #include ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// PubStore::PubStore(const mString & EntityName, ENGINE * e):NewPKIStore(EntityName, e, NEWPKISTORE_TYPE_RESPONDER) { } PubStore::~PubStore() { } bool PubStore::CreateTables(const SQL_Connection * DbConn) { SQL sql(DbConn); long i; char * CommonCreates[] = {PUBSTORE_CREATE_1, NULL}; //We execute each request for(i=0; CommonCreates[i]; i++) { if(!sql.Execute(CommonCreates[i])) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } } if(!CommonCreateTables(DbConn)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool PubStore::OnNewRevocation(unsigned long serial, time_t rev_date, const X509_NAME *issuer_name, const X509_PUBKEY *issuer_pkey) { SQL sql(m_DbConn); mString req; mString OcspIdStr; if(!GetOcspCertIdStr(serial, issuer_name, issuer_pkey, OcspIdStr)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } req.sprintf(PUBSTORE_INSERT_CERT, OcspIdStr.c_str(), rev_date); if(!sql.Execute(req)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool PubStore::OnNewCertificate(unsigned long serial, const X509_NAME *issuer_name, const X509_PUBKEY *issuer_pkey) { SQL sql(m_DbConn); mString req; mString OcspIdStr; if(!GetOcspCertIdStr(serial, issuer_name, issuer_pkey, OcspIdStr)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } req.sprintf(PUBSTORE_INSERT_CERT, OcspIdStr.c_str(), 0); if(!sql.Execute(req)) { NEWPKIerr(PKI_ERROR_TXT, ERROR_ABORT); return false; } return true; } bool PubStore::OnNewCrl(const PKI_CRL &Crl, const X509_NAME *issuer_name, const X509_PUBKEY *issuer_pkey) { long i; const REVOCATION_INFO* revinfo; for(i=0; iserial, revinfo->rev_date, issuer_name, issuer_pkey); } ERR_clear_error(); return true; } bool PubStore::GetCertStatus(unsigned long serial, const X509_NAME *issuer_name, const X509_PUBKEY *issuer_pkey, int &OcspStatus, time_t & rev_date) { SQL sql(m_DbConn); mString req; mString OcspIdStr; long ctr; if(!GetOcspCertIdStr(serial, issuer_name, issuer_pkey, OcspIdStr)) { NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); OcspStatus = V_OCSP_CERTSTATUS_UNKNOWN; return false; } req.sprintf(PUBSTORE_GET_REV, OcspIdStr.c_str()); if(!sql.Execute(req)) { NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); OcspStatus = V_OCSP_CERTSTATUS_UNKNOWN; return false; } if(!sql.NumRows(&ctr)) { NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); OcspStatus = V_OCSP_CERTSTATUS_UNKNOWN; return false; } if(!ctr) { OcspStatus = V_OCSP_CERTSTATUS_UNKNOWN; return true; } if(!sql.Value(0, "revdate", req)) { NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); OcspStatus = V_OCSP_CERTSTATUS_UNKNOWN; return false; } rev_date = req.c_ulng(); if(rev_date) OcspStatus = V_OCSP_CERTSTATUS_REVOKED; else OcspStatus = V_OCSP_CERTSTATUS_GOOD; return true; } bool PubStore::GetOcspCertIdStr(unsigned long serial, const X509_NAME *issuer_name, const X509_PUBKEY *issuer_pkey, mString &CertIdStr) { OCSP_CERTID* cid; ASN1_INTEGER * i_serial = NULL; ASN1_INTEGER_SET(&i_serial, serial); unsigned char * buf; unsigned int len; unsigned char * p; unsigned char md[SHA_DIGEST_LENGTH]; if(!i_serial) { NEWPKIerr(OCSP_ERROR_TXT, ERROR_MALLOC); return false; } cid = OCSP_cert_id_new(EVP_sha1(), (X509_NAME*)issuer_name, (ASN1_BIT_STRING*)issuer_pkey->public_key, (ASN1_INTEGER*)i_serial); if(!cid) { ASN1_INTEGER_free(i_serial); NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); return false; } ASN1_INTEGER_free(i_serial); len = ASN1_item_i2d((ASN1_VALUE*)cid, NULL, ASN1_ITEM_rptr(OCSP_CERTID)); if(len <= 0) { OCSP_CERTID_free(cid); NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); return false; } buf = (unsigned char *)malloc(len+100); if(!buf) { OCSP_CERTID_free(cid); NEWPKIerr(OCSP_ERROR_TXT, ERROR_MALLOC); return false; } p = buf; len = ASN1_item_i2d((ASN1_VALUE*)cid, &p, ASN1_ITEM_rptr(OCSP_CERTID)); if(len <= 0) { OCSP_CERTID_free(cid); free(buf); NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); return false; } OCSP_CERTID_free(cid); if(EVP_Digest(buf, len, md, &len, EVP_sha1(), NULL) <= 0) { free(buf); NEWPKIerr(OCSP_ERROR_TXT, ERROR_ABORT); return false; } free(buf); char tt[3]; CertIdStr = ""; for(unsigned int i=0; i < len; i++) { sprintf(tt, "%.2x", md[i]); CertIdStr += tt; } return true; }