⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 certs.c

📁 This a good VPN source
💻 C
字号:
/* Certificate support for IKE authentication * Copyright (C) 2002-2004 Andreas Steffen, Zuercher Hochschule Winterthur * * 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.  See <http://www.fsf.org/copyleft/gpl.txt>. * * 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. * * RCSID $Id: certs.c,v 1.8 2004/06/27 20:43:41 mcr Exp $ */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <openswan.h>#include <openswan/ipsec_policy.h>#include "constants.h"#include "oswlog.h"#include "defs.h"#include "log.h"#include "asn1.h"#include "id.h"#include "x509.h"#include "pgp.h"#include "pem.h"#include "certs.h"#include "pkcs.h"#include "paths.h"#define BUF_LEN		256/* * used for initialization of private keys */const rsa_privkey_t empty_rsa_privkey = {    { NULL, 0 }, /* keyobject */    {	{ NULL, 0 },{ NULL, 0 },{ NULL, 0 },{ NULL, 0 },	{ NULL, 0 },{ NULL, 0 },{ NULL, 0 },{ NULL, 0 }    } 		 /* field[0..7] */};/* * used for initializatin of certs */const cert_t empty_cert = {FALSE, CERT_NONE, {NULL}};/* * extracts the certificate to be sent to the peer */chunk_tget_mycert(cert_t cert){    switch (cert.type)    {    case CERT_PGP:	return cert.u.pgp->certificate;    case CERT_X509_SIGNATURE:	return cert.u.x509->certificate;    default:	return empty_chunk;    }}/* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */boolload_coded_file(const char *filename, prompt_pass_t *pass, const char *type, chunk_t *blob, bool *pgp){    err_t ugh = NULL;    FILE *fd;    fd = fopen(filename, "r");    if (fd)    {	int bytes;	fseek(fd, 0, SEEK_END );	blob->len = ftell(fd);	rewind(fd);	blob->ptr = alloc_bytes(blob->len, type);	bytes = fread(blob->ptr, 1, blob->len, fd);	fclose(fd);	openswan_log("  loaded %s file '%s' (%d bytes)", type, filename, bytes);	*pgp = FALSE;	/* try DER format */	if (is_asn1(*blob))	{	    DBG(DBG_PARSING,		DBG_log("  file coded in DER format");	    )	    return TRUE;	}	/* try PEM format */	ugh = pemtobin(blob, pass, filename, pgp);	if (ugh == NULL)	{	    if (*pgp)	    {                DBG(DBG_PARSING,                    DBG_log("  file coded in armored PGP format");                )                return TRUE;	    }	    if (is_asn1(*blob))	    {		DBG(DBG_PARSING,		    DBG_log("  file coded in PEM format");		)		return TRUE;	    }	    ugh = "file coded in unknown format, discarded";	}	/* a conversion error has occured */	openswan_log("  %s", ugh);	pfree(blob->ptr);	*blob = empty_chunk;    }    else    {	openswan_log("  could not open %s file '%s'", type, filename);    }    return FALSE;}/* *  Loads a PKCS#1 or PGP private RSA key file */rsa_privkey_t*load_rsa_private_key(const char* filename, prompt_pass_t *pass){    bool pgp = FALSE;    chunk_t blob = empty_chunk;    char path[512];    if (*filename == '/')	/* absolute pathname */    	strncpy(path, filename, sizeof(path));    else			/* relative pathname */	snprintf(path, sizeof(path), "%s/%s", PRIVATE_KEY_PATH, filename);    if (load_coded_file(path, pass, "private key", &blob, &pgp))    {	rsa_privkey_t *key = alloc_thing(rsa_privkey_t, "rsa_privkey");	*key = empty_rsa_privkey;	if (pgp)	{	    if (parse_pgp(blob, NULL, key))		return key;	    else		openswan_log("  error in PGP private key");	}	else	{	    if (parse_pkcs1_private_key(blob, key))		return key;	    else		openswan_log("  error in PKCS#1 private key");	}	pfree(blob.ptr);	pfree(key);    }    return NULL;}/* *  Loads a X.509 or OpenPGP certificate */boolload_cert(bool forcedtype, const char *filename, const char *label, cert_t *cert){    bool pgp = FALSE;    chunk_t blob = empty_chunk;    /* initialize cert struct */    cert->forced = forcedtype;    cert->u.x509 = NULL;    if(!forcedtype) {	if (load_coded_file(filename, NULL, label, &blob, &pgp)) {	    if (pgp) {		pgpcert_t *pgpcert = alloc_thing(pgpcert_t, "pgpcert");		*pgpcert = empty_pgpcert;		if (parse_pgp(blob, pgpcert, NULL)) {		    cert->forced = FALSE;		    cert->type = CERT_PGP;		    cert->u.pgp = pgpcert;		    return TRUE;		} else {		    openswan_log("  error in OpenPGP certificate");		    free_pgpcert(pgpcert);		    return FALSE;		}			    } else {		x509cert_t *x509cert = alloc_thing(x509cert_t, "x509cert");		*x509cert = empty_x509cert;				if (parse_x509cert(blob, 0, x509cert)) {		    cert->forced = FALSE;		    cert->type = CERT_X509_SIGNATURE;		    cert->u.x509 = x509cert;		    return TRUE;		    		} else {		    openswan_log("  error in X.509 certificate");		    free_x509cert(x509cert);		    return FALSE;		}	    }	}    } else {	/*	 * if the certificate type was forced, then load the certificate	 * as a blob, don't interpret or validate it at all	 *	 */	FILE *fd;	int bytes;	    	fd = fopen(filename, "r");	if(fd == NULL) {	    openswan_log("  can not open certificate-blob filename '%s': %s\n",			 filename, strerror(errno));	    return FALSE;	}	fseek(fd, 0, SEEK_END );	cert->forced = TRUE;	cert->u.blob.len = ftell(fd);	rewind(fd);	cert->u.blob.ptr = alloc_bytes(cert->u.blob.len, " cert blob");	bytes = fread(cert->u.blob.ptr, 1, cert->u.blob.len, fd);	fclose(fd);    }    return FALSE;}/* *  Loads a host certificate */boolload_host_cert(enum ipsec_cert_type certtype, const char *filename, cert_t *cert){    char path[BUF_LEN];    if (*filename == '/')	/* absolute pathname */    	strncpy(path, filename, BUF_LEN);    else			/* relative pathname */	snprintf(path, BUF_LEN, "%s/%s", HOST_CERT_PATH, filename);    return load_cert(certtype, path, "host cert", cert);}/* * establish equality of two certificates */boolsame_cert(const cert_t *a, const cert_t *b){    return a->type == b->type && a->u.x509 == b->u.x509;}/*  for each link pointing to the certif icate "  increase the count by one */voidshare_cert(cert_t cert){    switch (cert.type)    {    case CERT_PGP:	share_pgpcert(cert.u.pgp);	break;    case CERT_X509_SIGNATURE:	share_x509cert(cert.u.x509);	break;    default:	break;    }}/*  release of a certificate decreases the count by one "  the certificate is freed when the counter reaches zero */voidrelease_cert(cert_t cert){   switch (cert.type)    {    case CERT_PGP:	release_pgpcert(cert.u.pgp);	break;    case CERT_X509_SIGNATURE:	release_x509cert(cert.u.x509);	break;    default:	break;    }}/* *  list all X.509 and OpenPGP end certificates */voidlist_certs(bool utc){    list_x509_end_certs(utc);    list_pgp_end_certs(utc);}/* * Local Variables: * c-basic-offset:4 * c-style: pluto * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -