Add functionality to help making self-signed certificate.
authorRichard Levitte <levitte@openssl.org>
Thu, 3 Apr 2003 22:27:24 +0000 (22:27 +0000)
committerRichard Levitte <levitte@openssl.org>
Thu, 3 Apr 2003 22:27:24 +0000 (22:27 +0000)
CHANGES
crypto/evp/evp.h
crypto/evp/p_lib.c
crypto/x509/x509.h
crypto/x509/x509_cmp.c
crypto/x509/x509_err.c
crypto/x509/x509_req.c

diff --git a/CHANGES b/CHANGES
index 505ef51..0d76770 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@
 
  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
      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
index b084a35..4e4a667 100644 (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_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);
 
 /* calls methods */
index c7a3dee..8d23c0b 100644 (file)
@@ -237,6 +237,52 @@ int EVP_PKEY_cmp_parameters(EVP_PKEY *a, EVP_PKEY *b)
        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 *ret;
index 53a8f6c..049308b 100644 (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_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_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_PUBKEY_GET                          119
 #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_FP                        122
 #define X509_F_X509_REQ_TO_X509                                 123
index 9b28911..5dfdcd4 100644 (file)
@@ -374,62 +374,36 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k)
        int ok=0;
 
        xk=X509_get_pubkey(x);
-       if (xk->type != k->type)
-           {
-           X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
-           goto err;
-           }
-       switch (k->type)
+       switch (EVP_PKEY_cmp(xk, k))
                {
-#ifndef OPENSSL_NO_RSA
-       case EVP_PKEY_RSA:
-               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;
-                   }
+       case 1:
+               ok=1;
                break;
-#endif
-#ifndef OPENSSL_NO_DSA
-       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;
-                   }
+       case 0:
+               X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_VALUES_MISMATCH);
                break;
-#endif
+       case -1:
+               X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_KEY_TYPE_MISMATCH);
+               break;
+       case -2:
 #ifndef OPENSSL_NO_EC
-       case 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 (k->type == EVP_PKEY_EC)
                        {
-                       if (r == 1)
-                               X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH);
-                       else
-                               X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
-                       
-                       goto err;
+                       X509err(X509_F_X509_CHECK_PRIVATE_KEY, ERR_R_EC_LIB);
+                       break;
                        }
-               }
-               break;
 #endif
 #ifndef OPENSSL_NO_DH
-       case EVP_PKEY_DH:
-               /* No idea */
-               X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
-               goto err;
+               if (k->type == EVP_PKEY_DH)
+                       {
+                       /* No idea */
+                       X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_CANT_CHECK_DH_KEY);
+                       break;
+                       }
 #endif
-       default:
                X509err(X509_F_X509_CHECK_PRIVATE_KEY,X509_R_UNKNOWN_KEY_TYPE);
-               goto err;
                }
 
-       ok=1;
-err:
        EVP_PKEY_free(xk);
        return(ok);
        }
index 5bbf4ac..7a6d5a0 100644 (file)
@@ -1,6 +1,6 @@
 /* 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
  * 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_PUBKEY_GET,0), "X509_PUBKEY_get"},
 {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_FP,0),       "X509_REQ_print_fp"},
 {ERR_PACK(0,X509_F_X509_REQ_TO_X509,0),        "X509_REQ_to_X509"},
index 0affa3b..b4ad534 100644 (file)
@@ -113,6 +113,46 @@ EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req)
        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
  * extensions in a certificate request. There are at least two OIDs that are
  * used and there may be more: so the list is configurable.