typo
[openssl.git] / crypto / asn1 / a_sign.c
index 52ce7e39740b877e81f9a74f43028b7679d7ab20..27deb8913792459c8b2b4c7ee549cfefe560da3d 100644 (file)
@@ -56,7 +56,7 @@
  * [including the GNU Public Licence.]
  */
 /* ====================================================================
- * Copyright (c) 1998-2002 The OpenSSL Project.  All rights reserved.
+ * Copyright (c) 1998-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
 #include <openssl/x509.h>
 #include <openssl/objects.h>
 #include <openssl/buffer.h>
+#include "asn1_locl.h"
 
 #ifndef NO_ASN1_OLD
 
-int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
-            ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
-            const EVP_MD *type)
+int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
+             ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
+             const EVP_MD *type)
        {
        EVP_MD_CTX ctx;
        unsigned char *p,*buf_in=NULL,*buf_out=NULL;
@@ -183,9 +184,9 @@ int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
        p=buf_in;
 
        i2d(data,&p);
-       EVP_SignInit_ex(&ctx,type, NULL);
-       EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
-       if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
+       if (!EVP_SignInit_ex(&ctx,type, NULL)
+               || !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
+               || !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
                        (unsigned int *)&outl,pkey))
                {
                outl=0;
@@ -218,61 +219,63 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
        {
        EVP_MD_CTX ctx;
        unsigned char *buf_in=NULL,*buf_out=NULL;
-       int i,inl=0,outl=0,outll=0;
-       X509_ALGOR *a;
+       size_t inl=0,outl=0,outll=0;
+       int signid, paramtype;
 
-       EVP_MD_CTX_init(&ctx);
-       for (i=0; i<2; i++)
+       if (type == NULL)
                {
-               if (i == 0)
-                       a=algor1;
-               else
-                       a=algor2;
-               if (a == NULL) continue;
-                if (type->pkey_type == NID_dsaWithSHA1)
-                       {
-                       /* special case: RFC 2459 tells us to omit 'parameters'
-                        * with id-dsa-with-sha1 */
-                       ASN1_TYPE_free(a->parameter);
-                       a->parameter = NULL;
-                       }
-               else if ((a->parameter == NULL) || 
-                       (a->parameter->type != V_ASN1_NULL))
-                       {
-                       ASN1_TYPE_free(a->parameter);
-                       if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
-                       a->parameter->type=V_ASN1_NULL;
-                       }
-               ASN1_OBJECT_free(a->algorithm);
-               a->algorithm=OBJ_nid2obj(type->pkey_type);
-               if (a->algorithm == NULL)
-                       {
-                       ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
-                       goto err;
-                       }
-               if (a->algorithm->length == 0)
+               int def_nid;
+               if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0)
+                       type = EVP_get_digestbynid(def_nid);
+               }
+
+       if (type == NULL)
+               {
+               ASN1err(ASN1_F_ASN1_ITEM_SIGN, ASN1_R_NO_DEFAULT_DIGEST);
+               return 0;
+               }
+
+       if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
+               {
+               if (!pkey->ameth ||
+                       !OBJ_find_sigid_by_algs(&signid, EVP_MD_nid(type),
+                                               pkey->ameth->pkey_id))
                        {
-                       ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
-                       goto err;
+                       ASN1err(ASN1_F_ASN1_ITEM_SIGN,
+                               ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+                       return 0;
                        }
                }
+       else
+               signid = type->pkey_type;
+
+       if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
+               paramtype = V_ASN1_NULL;
+       else
+               paramtype = V_ASN1_UNDEF;
+
+       if (algor1)
+               X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
+       if (algor2)
+               X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
+
+       EVP_MD_CTX_init(&ctx);
        inl=ASN1_item_i2d(asn,&buf_in, it);
        outll=outl=EVP_PKEY_size(pkey);
        buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
        if ((buf_in == NULL) || (buf_out == NULL))
                {
                outl=0;
-               ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE);
+               ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_MALLOC_FAILURE);
                goto err;
                }
 
-       EVP_SignInit_ex(&ctx,type, NULL);
-       EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
-       if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
-                       (unsigned int *)&outl,pkey))
+       if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)
+               || !EVP_DigestSignUpdate(&ctx, buf_in, inl)
+               || !EVP_DigestSignFinal(&ctx, buf_out, &outl))
                {
                outl=0;
-               ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
+               ASN1err(ASN1_F_ASN1_ITEM_SIGN,ERR_R_EVP_LIB);
                goto err;
                }
        if (signature->data != NULL) OPENSSL_free(signature->data);