// Verify_Cert.c
//
// Copyright 2009 Kim Sung-tae <pchero21@gmail.com>
//
// 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, or
// (at your option) any later version.
//
// 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., 51 Franklin Street, Fifth Floor, Boston,
// MA 02110-1301, USA.
#include <stdio.h>
#include <openssl/bio.h>
#include <openssl/conf.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/objects.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/rand.h>
#include <openssl/pem.h>
#define CA_CERT_FILE “rootcert.pem”
#define CRL_FILE “testcrl.pem”
#define CERT_FILE “newcert.pem”
int verifyCallbackfunc(int ok, X509_STORE_CTX *store)
{
X509 *cert;
if(!ok) {
cert = X509_STORE_CTX_get_current_cert(store);
printf(“error:%sn”, X509_verify_cert_error_string(store->error));
}
return ok;
}
int main(int argc, char** argv)
{
BIO *bio_err;
int retVal;
char *retString;
X509 *cert;
X509_STORE *store;
X509_LOOKUP *lookup;
X509_STORE_CTX *storeCtx;
BIO *certBIO = NULL;
OpenSSL_add_all_algorithms();
// 화면 출력용 BIO 생성
if((bio_err = BIO_new(BIO_s_file())) != NULL)
BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT);
// 인증할 인증서를 읽기 위한 BIO 생성
certBIO = BIO_new(BIO_s_file());
if(BIO_read_filename(certBIO, CERT_FILE) <= 0) {
BIO_printf(bio_err, “인증서 파일 [%s]을 여는데 에러가 발생 했습니다.”, CERT_FILE);
ERR_print_errors(bio_err);
exit(1);
}
// 인증할 인증서를 파일로부터 읽어 X509 구조체로 변환
cert = PEM_read_bio_X509(certBIO, NULL, NULL, NULL);
if(cert == NULL) {
BIO_printf(bio_err, “CA 인증서를 로드할 수 없습니다.”);
ERR_print_errors(bio_err);
exit(1);
}
// 인증서를 저장할 STORE 구조체 생성
store = X509_STORE_new();
if(store == NULL) {
BIO_printf(bio_err, “X509_STORE 를 생성할 수 없습니다.”);
ERR_print_errors(bio_err);
exit(1);
}
// 콜백 함수 설정
X509_STORE_set_verify_cb_func(store, verifyCallbackfunc);
// 파일로부터 CA 인증서 읽음
if(!X509_STORE_load_locations(store, CA_CERT_FILE, NULL)) {
BIO_printf(bio_err, “CA 인증서를 로드할 수 없습니다.”);
ERR_print_errors(bio_err);
exit(1);
}
// STORE에 CA 인증서 추가
lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
if(lookup == NULL) {
BIO_printf(bio_err, “X509_LOOKUP 를 생성할 수 없습니다.”);
ERR_print_errors(bio_err);
exit(1);
}
// CRL 읽음
if(!X509_load_crl_file(lookup, CRL_FILE, X509_FILETYPE_PEM)) {
BIO_printf(bio_err, “CRL을 로드 할 수 없습니다.”);
ERR_print_errors(bio_err);
exit(1);
}
// CA 인증서, CRL 인증 모두 지원
X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
// STORE 컨텍스트 생성
storeCtx = X509_STORE_CTX_new();
if(storeCtx == NULL) {
BIO_printf(bio_err, “X509_STORE_CTX를 생성 할 수 없습니다.”);
ERR_print_errors(bio_err);
exit(1);
}
if(!X509_STORE_CTX_init(storeCtx, store, cert, NULL)) {
BIO_printf(bio_err, “X509_STORE_CTX를 초기화 할 수 없습니다.”);
ERR_print_errors(bio_err);
exit(1);
}
// 인증서 인증
retVal = X509_verify_cert(storeCtx);
if(retVal == 1) {
BIO_printf(bio_err, “인증 되었습니다.”);
}
else {
BIO_printf(bio_err, “인증을 할 수 없습니다.”);
ERR_print_errors(bio_err);
}
return 0;
}