mode used too early in EVP_PKEY_save_parameters.
[openssl.git] / crypto / evp / p_lib.c
index 11369048e7e08b18b829ab1e7dc28ba75849f585..14af3198dc1ccb346ed9cc24e4c2defe73df4ef4 100644 (file)
@@ -1,5 +1,5 @@
 /* crypto/evp/p_lib.c */
-/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
  * This package is an SSL implementation written
 
 #include <stdio.h>
 #include "cryptlib.h"
-#include "objects.h"
-#include "evp.h"
-#include "asn1_mac.h"
-#include "x509.h"
+#include <openssl/objects.h>
+#include <openssl/evp.h>
+#include <openssl/asn1_mac.h>
+#include <openssl/x509.h>
 
-/* EVPerr(EVP_F_D2I_PKEY,EVP_R_UNSUPPORTED_CIPHER); */
-/* EVPerr(EVP_F_D2I_PKEY,EVP_R_IV_TOO_LARGE); */
-
-#ifndef NOPROTO
 static void EVP_PKEY_free_it(EVP_PKEY *x);
-#else
-static void EVP_PKEY_free_it();
+int EVP_PKEY_bits(EVP_PKEY *pkey)
+       {
+#ifndef NO_RSA
+       if (pkey->type == EVP_PKEY_RSA)
+               return(BN_num_bits(pkey->pkey.rsa->n));
+       else
 #endif
+#ifndef NO_DSA
+               if (pkey->type == EVP_PKEY_DSA)
+               return(BN_num_bits(pkey->pkey.dsa->p));
+#endif
+       return(0);
+       }
 
-int EVP_PKEY_size(pkey)
-EVP_PKEY *pkey;
+int EVP_PKEY_size(EVP_PKEY *pkey)
        {
+       if (pkey == NULL)
+               return(0);
 #ifndef NO_RSA
        if (pkey->type == EVP_PKEY_RSA)
                return(RSA_size(pkey->pkey.rsa));
@@ -87,14 +94,12 @@ EVP_PKEY *pkey;
        return(0);
        }
 
-int EVP_PKEY_save_parameters(pkey,mode)
-EVP_PKEY *pkey;
-int mode;
+int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode)
        {
 #ifndef NO_DSA
        if (pkey->type == EVP_PKEY_DSA)
                {
-               int ret=pkey->save_parameters=mode;
+               int ret=pkey->save_parameters;
 
                if (mode >= 0)
                        pkey->save_parameters=mode;
@@ -104,19 +109,18 @@ int mode;
        return(0);
        }
 
-int EVP_PKEY_copy_parameters(to,from)
-EVP_PKEY *to,*from;
+int EVP_PKEY_copy_parameters(EVP_PKEY *to, EVP_PKEY *from)
        {
        if (to->type != from->type)
                {
                EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_DIFFERENT_KEY_TYPES);
-               return(0);
+               goto err;
                }
 
        if (EVP_PKEY_missing_parameters(from))
                {
-               EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARMATERS);
-               return(0);
+               EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS,EVP_R_MISSING_PARAMETERS);
+               goto err;
                }
 #ifndef NO_DSA
        if (to->type == EVP_PKEY_DSA)
@@ -141,8 +145,7 @@ err:
        return(0);
        }
 
-int EVP_PKEY_missing_parameters(pkey)
-EVP_PKEY *pkey;
+int EVP_PKEY_missing_parameters(EVP_PKEY *pkey)
        {
 #ifndef NO_DSA
        if (pkey->type == EVP_PKEY_DSA)
@@ -157,11 +160,27 @@ EVP_PKEY *pkey;
        return(0);
        }
 
-EVP_PKEY *EVP_PKEY_new()
+int EVP_PKEY_cmp_parameters(EVP_PKEY *a, EVP_PKEY *b)
+       {
+#ifndef NO_DSA
+       if ((a->type == EVP_PKEY_DSA) && (b->type == EVP_PKEY_DSA))
+               {
+               if (    BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
+                       BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
+                       BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
+                       return(0);
+               else
+                       return(1);
+               }
+#endif
+       return(-1);
+       }
+
+EVP_PKEY *EVP_PKEY_new(void)
        {
        EVP_PKEY *ret;
 
-       ret=(EVP_PKEY *)Malloc(sizeof(EVP_PKEY));
+       ret=(EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY));
        if (ret == NULL)
                {
                EVPerr(EVP_F_EVP_PKEY_NEW,ERR_R_MALLOC_FAILURE);
@@ -175,10 +194,7 @@ EVP_PKEY *EVP_PKEY_new()
        return(ret);
        }
 
-int EVP_PKEY_assign(pkey,type,key)
-EVP_PKEY *pkey;
-int type;
-char *key;
+int EVP_PKEY_assign(EVP_PKEY *pkey, int type, char *key)
        {
        if (pkey == NULL) return(0);
        if (pkey->pkey.ptr != NULL)
@@ -186,11 +202,68 @@ char *key;
        pkey->type=EVP_PKEY_type(type);
        pkey->save_type=type;
        pkey->pkey.ptr=key;
-       return(1);
+       return(key != NULL);
        }
 
-int EVP_PKEY_type(type)
-int type;
+#ifndef NO_RSA
+int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
+{
+       int ret = EVP_PKEY_assign_RSA(pkey, key);
+       if(ret) CRYPTO_add(&key->references, 1, CRYPTO_LOCK_RSA);
+       return ret;
+}
+
+RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
+       {
+       if(pkey->type != EVP_PKEY_RSA) {
+               EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+               return NULL;
+       }
+       CRYPTO_add(&pkey->pkey.rsa->references, 1, CRYPTO_LOCK_RSA);
+       return pkey->pkey.rsa;
+}
+#endif
+
+#ifndef NO_DSA
+int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
+{
+       int ret = EVP_PKEY_assign_DSA(pkey, key);
+       if(ret) CRYPTO_add(&key->references, 1, CRYPTO_LOCK_DSA);
+       return ret;
+}
+
+DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
+       {
+       if(pkey->type != EVP_PKEY_DSA) {
+               EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+               return NULL;
+       }
+       CRYPTO_add(&pkey->pkey.dsa->references, 1, CRYPTO_LOCK_DSA);
+       return pkey->pkey.dsa;
+}
+#endif
+
+#ifndef NO_DH
+
+int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key)
+{
+       int ret = EVP_PKEY_assign_DH(pkey, key);
+       if(ret) CRYPTO_add(&key->references, 1, CRYPTO_LOCK_DH);
+       return ret;
+}
+
+DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
+       {
+       if(pkey->type != EVP_PKEY_DH) {
+               EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY);
+               return NULL;
+       }
+       CRYPTO_add(&pkey->pkey.dh->references, 1, CRYPTO_LOCK_DH);
+       return pkey->pkey.dh;
+}
+#endif
+
+int EVP_PKEY_type(int type)
        {
        switch (type)
                {
@@ -198,8 +271,10 @@ int type;
        case EVP_PKEY_RSA2:
                return(EVP_PKEY_RSA);
        case EVP_PKEY_DSA:
+       case EVP_PKEY_DSA1:
        case EVP_PKEY_DSA2:
        case EVP_PKEY_DSA3:
+       case EVP_PKEY_DSA4:
                return(EVP_PKEY_DSA);
        case EVP_PKEY_DH:
                return(EVP_PKEY_DH);
@@ -208,14 +283,16 @@ int type;
                }
        }
 
-void EVP_PKEY_free(x)
-EVP_PKEY *x;
+void EVP_PKEY_free(EVP_PKEY *x)
        {
        int i;
 
        if (x == NULL) return;
 
        i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_EVP_PKEY);
+#ifdef REF_PRINT
+       REF_PRINT("EVP_PKEY",x);
+#endif
        if (i > 0) return;
 #ifdef REF_CHECK
        if (i < 0)
@@ -225,11 +302,10 @@ EVP_PKEY *x;
                }
 #endif
        EVP_PKEY_free_it(x);
-       Free((char *)x);
+       OPENSSL_free(x);
        }
 
-static void EVP_PKEY_free_it(x)
-EVP_PKEY *x;
+static void EVP_PKEY_free_it(EVP_PKEY *x)
        {
        switch (x->type)
                {
@@ -243,6 +319,7 @@ EVP_PKEY *x;
        case EVP_PKEY_DSA:
        case EVP_PKEY_DSA2:
        case EVP_PKEY_DSA3:
+       case EVP_PKEY_DSA4:
                DSA_free(x->pkey.dsa);
                break;
 #endif