Add functionality to help making self-signed certificate.

This commit is contained in:
Richard Levitte 2003-04-03 22:27:24 +00:00
parent 8152d88799
commit e6526fbf4d
7 changed files with 116 additions and 45 deletions

View File

@ -4,6 +4,11 @@
Changes between 0.9.7a and 0.9.8 [xx XXX xxxx] Changes between 0.9.7a and 0.9.8 [xx XXX xxxx]
*) Add functionality to check the public key of a certificate request
against a given private. This is useful to check that a certificate
request can be signed by that key (self-signing).
[Richard Levitte]
*) Make it possible to have multiple active certificates with the same *) Make it possible to have multiple active certificates with the same
subject in the CA index file. This is done only if the keyword subject in the CA index file. This is done only if the keyword
'unique_subject' is set to 'no' in the main CA section (default 'unique_subject' is set to 'no' in the main CA section (default

View File

@ -754,6 +754,8 @@ int EVP_PKEY_missing_parameters(EVP_PKEY *pkey);
int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode); int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
int EVP_PKEY_cmp_parameters(EVP_PKEY *a,EVP_PKEY *b); int EVP_PKEY_cmp_parameters(EVP_PKEY *a,EVP_PKEY *b);
int EVP_PKEY_cmp(EVP_PKEY *a,EVP_PKEY *b);
int EVP_CIPHER_type(const EVP_CIPHER *ctx); int EVP_CIPHER_type(const EVP_CIPHER *ctx);
/* calls methods */ /* calls methods */

View File

@ -237,6 +237,52 @@ int EVP_PKEY_cmp_parameters(EVP_PKEY *a, EVP_PKEY *b)
return(-1); return(-1);
} }
int EVP_PKEY_cmp(EVP_PKEY *a, EVP_PKEY *b)
{
if (a->type != b->type)
return -1;
switch (a->type)
{
#ifndef OPENSSL_NO_RSA
case EVP_PKEY_RSA:
if (BN_cmp(b->pkey.rsa->n,a->pkey.rsa->n) != 0
|| BN_cmp(b->pkey.rsa->e,a->pkey.rsa->e) != 0)
return 0;
break;
#endif
#ifndef OPENSSL_NO_DSA
case EVP_PKEY_DSA:
if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
return 0;
break;
#endif
#ifndef OPENSSL_NO_EC
case EVP_PKEY_EC:
{
int r = EC_POINT_cmp(b->pkey.eckey->group,
b->pkey.eckey->pub_key,a->pkey.eckey->pub_key,NULL);
if (r != 0)
{
if (r == 1)
return 0;
else
return -2;
}
}
break;
#endif
#ifndef OPENSSL_NO_DH
case EVP_PKEY_DH:
return -2;
#endif
default:
return -2;
}
return 1;
}
EVP_PKEY *EVP_PKEY_new(void) EVP_PKEY *EVP_PKEY_new(void)
{ {
EVP_PKEY *ret; EVP_PKEY *ret;

View File

@ -1038,6 +1038,8 @@ int X509_CRL_sort(X509_CRL *crl);
int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey);
int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); int X509_check_private_key(X509 *x509,EVP_PKEY *pkey);
int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b);
@ -1271,6 +1273,7 @@ void ERR_load_X509_strings(void);
#define X509_F_X509_PRINT_FP 118 #define X509_F_X509_PRINT_FP 118
#define X509_F_X509_PUBKEY_GET 119 #define X509_F_X509_PUBKEY_GET 119
#define X509_F_X509_PUBKEY_SET 120 #define X509_F_X509_PUBKEY_SET 120
#define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144
#define X509_F_X509_REQ_PRINT 121 #define X509_F_X509_REQ_PRINT 121
#define X509_F_X509_REQ_PRINT_FP 122 #define X509_F_X509_REQ_PRINT_FP 122
#define X509_F_X509_REQ_TO_X509 123 #define X509_F_X509_REQ_TO_X509 123

View File

@ -374,62 +374,36 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k)
int ok=0; int ok=0;
xk=X509_get_pubkey(x); xk=X509_get_pubkey(x);
if (xk->type != k->type) switch (EVP_PKEY_cmp(xk, k))
{
X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
goto err;
}
switch (k->type)
{ {
#ifndef OPENSSL_NO_RSA case 1:
case EVP_PKEY_RSA: ok=1;
if (BN_cmp(xk->pkey.rsa->n,k->pkey.rsa->n) != 0
|| BN_cmp(xk->pkey.rsa->e,k->pkey.rsa->e) != 0)
{
X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
goto err;
}
break; break;
#endif case 0:
#ifndef OPENSSL_NO_DSA X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
case EVP_PKEY_DSA:
if (BN_cmp(xk->pkey.dsa->pub_key,k->pkey.dsa->pub_key) != 0)
{
X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
goto err;
}
break; break;
#endif case -1:
X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
#ifndef OPENSSL_NO_EC #ifndef OPENSSL_NO_EC
case EVP_PKEY_EC: if (k->type == EVP_PKEY_EC)
{
int r = EC_POINT_cmp(xk->pkey.eckey->group,
xk->pkey.eckey->pub_key,k->pkey.eckey->pub_key,NULL);
if (r != 0)
{ {
if (r == 1) X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH); break;
else
X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
goto err;
} }
}
break;
#endif #endif
#ifndef OPENSSL_NO_DH #ifndef OPENSSL_NO_DH
case EVP_PKEY_DH: if (k->type == EVP_PKEY_DH)
/* No idea */ {
X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY); /* No idea */
goto err; X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
break;
}
#endif #endif
default:
X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE); X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
goto err;
} }
ok=1;
err:
EVP_PKEY_free(xk); EVP_PKEY_free(xk);
return(ok); return(ok);
} }

View File

@ -1,6 +1,6 @@
/* crypto/x509/x509_err.c */ /* crypto/x509/x509_err.c */
/* ==================================================================== /* ====================================================================
* Copyright (c) 1999 The OpenSSL Project. All rights reserved. * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -95,6 +95,7 @@ static ERR_STRING_DATA X509_str_functs[]=
{ERR_PACK(0,X509_F_X509_PRINT_FP,0), "X509_print_fp"}, {ERR_PACK(0,X509_F_X509_PRINT_FP,0), "X509_print_fp"},
{ERR_PACK(0,X509_F_X509_PUBKEY_GET,0), "X509_PUBKEY_get"}, {ERR_PACK(0,X509_F_X509_PUBKEY_GET,0), "X509_PUBKEY_get"},
{ERR_PACK(0,X509_F_X509_PUBKEY_SET,0), "X509_PUBKEY_set"}, {ERR_PACK(0,X509_F_X509_PUBKEY_SET,0), "X509_PUBKEY_set"},
{ERR_PACK(0,X509_F_X509_REQ_CHECK_PRIVATE_KEY,0), "X509_REQ_check_private_key"},
{ERR_PACK(0,X509_F_X509_REQ_PRINT,0), "X509_REQ_print"}, {ERR_PACK(0,X509_F_X509_REQ_PRINT,0), "X509_REQ_print"},
{ERR_PACK(0,X509_F_X509_REQ_PRINT_FP,0), "X509_REQ_print_fp"}, {ERR_PACK(0,X509_F_X509_REQ_PRINT_FP,0), "X509_REQ_print_fp"},
{ERR_PACK(0,X509_F_X509_REQ_TO_X509,0), "X509_REQ_to_X509"}, {ERR_PACK(0,X509_F_X509_REQ_TO_X509,0), "X509_REQ_to_X509"},

View File

@ -113,6 +113,46 @@ EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
return(X509_PUBKEY_get(req->req_info->pubkey)); return(X509_PUBKEY_get(req->req_info->pubkey));
} }
int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
{
EVP_PKEY *xk=NULL;
int ok=0;
xk=X509_REQ_get_pubkey(x);
switch (EVP_PKEY_cmp(xk, k))
{
case 1:
ok=1;
break;
case 0:
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
#ifndef OPENSSL_NO_EC
if (k->type == EVP_PKEY_EC)
{
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
break;
}
#endif
#ifndef OPENSSL_NO_DH
if (k->type == EVP_PKEY_DH)
{
/* No idea */
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
break;
}
#endif
X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
}
EVP_PKEY_free(xk);
return(ok);
}
/* It seems several organisations had the same idea of including a list of /* It seems several organisations had the same idea of including a list of
* extensions in a certificate request. There are at least two OIDs that are * extensions in a certificate request. There are at least two OIDs that are
* used and there may be more: so the list is configurable. * used and there may be more: so the list is configurable.