Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision ae455377

Von aquamaniac vor etwa 21 Jahren hinzugefügt

  • ID ae455377cdf5d522e02ea35ffb794bd2953339d1
  • Vorgänger 814372b9
  • Nachfolger 66552aa3

- os/gwentime: added function to retrieve the time in milliseconds
- base/idlist: fixed two severe bugs
- crypt/ossl/nettransportssl: added functions to retrieve the peer certificate

git-svn-id: https://devel.aqbanking.de/svn/gwenhywfar/trunk@386 70169cfe-8b10-0410-8925-dcb4b91034d8

Unterschiede anzeigen:

src/crypt/ossl/nettransportssl.c
#include <openssl/pem.h>
#include <openssl/err.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
......
free(skd->ownCertFile);
free(skd->dhfile);
free(skd->cipherList);
free(skd->peerCertificate);
free(skd);
}
}
......
/* -------------------------------------------------------------- FUNCTION */
GWEN_DB_NODE*
GWEN_NetTransportSSL_GetPeerCertificate(const GWEN_NETTRANSPORT *tr) {
GWEN_NETTRANSPORTSSL *skd;
assert(tr);
skd=GWEN_INHERIT_GETDATA(GWEN_NETTRANSPORT, GWEN_NETTRANSPORTSSL, tr);
assert(skd);
return skd->peerCertificate;
}
/* -------------------------------------------------------------- FUNCTION */
GWEN_NETTRANSPORT_RESULT
GWEN_NetTransportSSL_StartConnect(GWEN_NETTRANSPORT *tr){
......
assert(tr);
skd=GWEN_INHERIT_GETDATA(GWEN_NETTRANSPORT, GWEN_NETTRANSPORTSSL, tr);
assert(skd);
GWEN_InetAddr_GetAddress(GWEN_NetTransport_GetPeerAddr(tr),
addrBuffer, sizeof(addrBuffer));
......
GWEN_DB_NODE *cert){
DBG_NOTICE(0, "Would ask user about this:");
GWEN_DB_Dump(cert, stderr, 2);
return GWEN_NetTransportSSL_AskAddCertResultPerm;
if (gwen_netransportssl_askAddCertFn)
return gwen_netransportssl_askAddCertFn(tr, cert);
......
0);
}
/* enable all workarounds for bugs in other SSL implementation for
* maximum compatibility */
SSL_CTX_set_options(skd->ssl_ctx, SSL_OP_ALL);
skd->ssl=SSL_new(skd->ssl_ctx);
/* tell SSL to use our socket */
......
int GWEN_NetTransportSSL__ASN_UTC2Db(ASN1_TIME *d,
GWEN_DB_NODE *db,
const char *name) {
if (d->data) {
const char *s;
unsigned int i;
struct tm t;
struct tm *lt;
time_t currTime;
int isUtc;
s=(const char*)(d->data);
i=strlen(s);
if (i<10) {
DBG_ERROR(0, "Bad time expression (%s)", s);
return -1;
}
currTime=time(0);
isUtc=(s[i-1]=='Z');
if (isUtc)
lt=gmtime(&currTime);
else
lt=localtime(&currTime);
memmove(&t, lt, sizeof(t));
t.tm_year=((s[0]-'0')*10)+(s[1]-'0')+100;
t.tm_mon=(((s[2]-'0')*10)+(s[3]-'0'))-1;
t.tm_mday=((s[4]-'0')*10)+(s[5]-'0');
t.tm_hour=((s[6]-'0')*10)+(s[7]-'0');
t.tm_min=((s[8]-'0')*10)+(s[9]-'0');
if (i>11)
t.tm_sec=((s[10]-'0')*10)+(s[11]-'0');
else
t.tm_sec=0;
t.tm_wday=0;
t.tm_yday=0;
currTime=mktime(&t);
GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
name, (unsigned int)currTime);
return 0;
}
else {
return -1;
}
}
/* -------------------------------------------------------------- FUNCTION */
GWEN_DB_NODE *GWEN_NetTransportSSL__Cert2Db(X509 *cert) {
GWEN_DB_NODE *dbCert;
X509_NAME *nm;
ASN1_TIME *d;
EVP_PKEY *pktmp;
nm=X509_get_subject_name(cert);
......
GWEN_NetTransportSSL__CertEntries2Db(nm, dbCert,
NID_stateOrProvinceName,
"stateOrProvinceName");
d=X509_get_notBefore(cert);
if (d) {
if (GWEN_NetTransportSSL__ASN_UTC2Db(d, dbCert, "notBefore")) {
DBG_ERROR(0, "Error in notBefore date");
}
}
d=X509_get_notAfter(cert);
if (d) {
if (GWEN_NetTransportSSL__ASN_UTC2Db(d, dbCert, "notAfter")) {
DBG_ERROR(0, "Error in notBefore date");
}
}
pktmp=X509_get_pubkey(cert);
if (pktmp) {
RSA *kd;
kd=EVP_PKEY_get1_RSA(pktmp);
if (kd) {
char buffer[256];
int l;
GWEN_DB_NODE *dbKey;
GWEN_DB_NODE *dbKeyData;
dbKey=GWEN_DB_GetGroup(dbCert, GWEN_DB_FLAGS_OVERWRITE_GROUPS,
"pubKey");
assert(dbKey);
dbKeyData=GWEN_DB_GetGroup(dbKey, GWEN_DB_FLAGS_OVERWRITE_GROUPS,
"data");
GWEN_DB_SetCharValue(dbKey,
GWEN_DB_FLAGS_OVERWRITE_VARS,
"type", "RSA");
GWEN_DB_SetIntValue(dbKeyData,
GWEN_DB_FLAGS_DEFAULT |
GWEN_DB_FLAGS_OVERWRITE_VARS,
"public", 1);
if (kd->n) {
l=BN_bn2bin(kd->n, (unsigned char*) &buffer);
GWEN_DB_SetBinValue(dbKeyData,
GWEN_DB_FLAGS_DEFAULT |
GWEN_DB_FLAGS_OVERWRITE_VARS,
"n", buffer, l);
}
if (kd->e) {
l=BN_bn2bin(kd->e, (unsigned char*) &buffer);
GWEN_DB_SetBinValue(dbKeyData,
GWEN_DB_FLAGS_DEFAULT |
GWEN_DB_FLAGS_OVERWRITE_VARS,
"e", buffer, l);
}
RSA_free(kd);
} /* if there is data for the public key */
EVP_PKEY_free(pktmp);
} /* if there is a pubkey */
return dbCert;
}
......
/* establish SSL */
int fd;
/* reset security */
GWEN_DB_Group_free(skd->peerCertificate);
skd->peerCertificate=0;
skd->isSecure=0;
/* get socket handle (I know, it's ugly, but the function below is
* not exported to the outside) */
fd=GWEN_Socket_GetSocketInt(skd->socket);
......
}
/* now logically connected */
GWEN_DB_Group_free(skd->peerCertificate);
skd->peerCertificate=0;
cert=SSL_get_peer_certificate(skd->ssl);
if (!cert) {
if (skd->secure) {
......
}
else {
DBG_NOTICE(0, "Peer certificate is valid");
/* TODO: check_cert? */
/* store peer certificate */
skd->peerCertificate=GWEN_NetTransportSSL__Cert2Db(cert);
skd->isSecure=1;
}
free(certbuf);
......
int GWEN_NetTransportSSL_GenerateCertAndKeyFile(const char *fname,
int bits,
int serial,
int days,
GWEN_DB_NODE *db) {
X509 *x;
EVP_PKEY *pk;
RSA *rsa;
X509_NAME *name=NULL;
X509_NAME_ENTRY *ne=NULL;
FILE *f;
const char *p;
X509V3_add_standard_extensions();
pk=EVP_PKEY_new();
if (!pk){
fprintf(stderr, "Could not create RSA key\n");
EVP_PKEY_free(pk);
X509V3_EXT_cleanup();
return -1;
}
x=X509_new();
if (!x) {
fprintf(stderr, "Could not create certificate\n");
EVP_PKEY_free(pk);
X509V3_EXT_cleanup();
return -1;
}
rsa=RSA_generate_key(bits, RSA_F4, NULL, NULL);
if (!EVP_PKEY_assign_RSA(pk, rsa)){
fprintf(stderr, "Could not assign RSA key\n");
X509_free(x);
EVP_PKEY_free(pk);
RSA_free(rsa);
X509V3_EXT_cleanup();
return -1;
}
rsa=NULL;
X509_set_version(x,3);
ASN1_INTEGER_set(X509_get_serialNumber(x),serial);
X509_gmtime_adj(X509_get_notBefore(x),0);
if (!days)
days=GWEN_NETTRANSPORTSSL_DEFAULT_CERT_DAYS;
X509_gmtime_adj(X509_get_notAfter(x),(long)60*60*24*days);
X509_set_pubkey(x, pk);
name=X509_NAME_new();
p=GWEN_DB_GetCharValue(db, "countryName", 0, "DE");
ne=X509_NAME_ENTRY_create_by_NID(NULL,
NID_countryName,
V_ASN1_APP_CHOOSE,
(unsigned char*)p,
-1);
X509_NAME_add_entry(name, ne, 0, 0);
p=GWEN_DB_GetCharValue(db, "commonName", 0, 0);
if (p) {
X509_NAME_ENTRY_create_by_NID(&ne, NID_commonName,
V_ASN1_APP_CHOOSE,
(unsigned char*)p,
-1);
X509_NAME_add_entry(name, ne, -1, 0);
}
p=GWEN_DB_GetCharValue(db, "organizationName", 0, 0);
if (p) {
X509_NAME_ENTRY_create_by_NID(&ne, NID_organizationName,
V_ASN1_APP_CHOOSE,
(unsigned char*)p,
-1);
X509_NAME_add_entry(name, ne, -1, 0);
}
p=GWEN_DB_GetCharValue(db, "organizationalUnitName", 0, 0);
if (p) {
X509_NAME_ENTRY_create_by_NID(&ne, NID_organizationalUnitName,
V_ASN1_APP_CHOOSE,
(unsigned char*)p,
-1);
X509_NAME_add_entry(name, ne, -1, 0);
}
p=GWEN_DB_GetCharValue(db, "localityName", 0, 0);
if (p) {
X509_NAME_ENTRY_create_by_NID(&ne, NID_localityName,
V_ASN1_APP_CHOOSE,
(unsigned char*)p,
-1);
X509_NAME_add_entry(name, ne, -1, 0);
}
p=GWEN_DB_GetCharValue(db, "stateOrProvinceName", 0, 0);
if (p) {
X509_NAME_ENTRY_create_by_NID(&ne, NID_stateOrProvinceName,
V_ASN1_APP_CHOOSE,
(unsigned char*)p,
-1);
X509_NAME_add_entry(name, ne, -1, 0);
}
X509_set_subject_name(x, name);
X509_set_issuer_name(x, name);
/* finished with structure */
X509_NAME_ENTRY_free(ne);
X509_NAME_free(name);
if (!X509_sign(x, pk, EVP_md5())) {
fprintf(stderr, "Could not sign\n");
X509_free(x);
EVP_PKEY_free(pk);
X509V3_EXT_cleanup();
return -1;
}
/* save key */
f=fopen(fname, "w+");
if (!f) {
fprintf(stderr, "Could not save private key\n");
X509_free(x);
EVP_PKEY_free(pk);
X509V3_EXT_cleanup();
return -1;
}
PEM_write_RSAPrivateKey(f,
pk->pkey.rsa,
NULL,
NULL,
0,
NULL,
NULL);
/* save cert */
PEM_write_X509(f, x);
if (fclose(f)) {
fprintf(stderr, "Could not close file\n");
X509_free(x);
EVP_PKEY_free(pk);
X509V3_EXT_cleanup();
return -1;
}
X509_free(x);
EVP_PKEY_free(pk);
X509V3_EXT_cleanup();
return 0;
}

Auch abrufbar als: Unified diff