ASN1_ITEM versions of sign, verify, pack and unpack.
[openssl.git] / crypto / asn1 / a_sign.c
index 57595692e5b965478259ae3d6aba328130423c0c..5be077ddfc5a38519e7bf33c957c4a254c489518 100644 (file)
 
 #include <stdio.h>
 #include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 
 #include "cryptlib.h"
+
+#ifndef NO_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
 #include <openssl/bn.h>
 #include <openssl/evp.h>
 #include <openssl/x509.h>
@@ -105,9 +108,9 @@ int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
                        }
                }
        inl=i2d(data,NULL);
-       buf_in=(unsigned char *)Malloc((unsigned int)inl);
+       buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
        outll=outl=EVP_PKEY_size(pkey);
-       buf_out=(unsigned char *)Malloc((unsigned int)outl);
+       buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
        if ((buf_in == NULL) || (buf_out == NULL))
                {
                outl=0;
@@ -126,11 +129,84 @@ int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
                ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
                goto err;
                }
-       if (signature->data != NULL) Free((char *)signature->data);
+       if (signature->data != NULL) OPENSSL_free(signature->data);
+       signature->data=buf_out;
+       buf_out=NULL;
+       signature->length=outl;
+       /* In the interests of compatibility, I'll make sure that
+        * the bit string has a 'not-used bits' value of 0
+        */
+       signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
+       signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
+err:
+       memset(&ctx,0,sizeof(ctx));
+       if (buf_in != NULL)
+               { memset((char *)buf_in,0,(unsigned int)inl); OPENSSL_free(buf_in); }
+       if (buf_out != NULL)
+               { memset((char *)buf_out,0,outll); OPENSSL_free(buf_out); }
+       return(outl);
+       }
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+            ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
+            const EVP_MD *type)
+       {
+       EVP_MD_CTX ctx;
+       unsigned char *buf_in=NULL,*buf_out=NULL;
+       int i,inl=0,outl=0,outll=0;
+       X509_ALGOR *a;
+
+       for (i=0; i<2; i++)
+               {
+               if (i == 0)
+                       a=algor1;
+               else
+                       a=algor2;
+               if (a == NULL) continue;
+               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)
+                       {
+                       ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
+                       goto err;
+                       }
+               }
+       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);
+               goto err;
+               }
+
+       EVP_SignInit(&ctx,type);
+       EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl);
+       if (!EVP_SignFinal(&ctx,(unsigned char *)buf_out,
+                       (unsigned int *)&outl,pkey))
+               {
+               outl=0;
+               ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
+               goto err;
+               }
+       if (signature->data != NULL) OPENSSL_free(signature->data);
        signature->data=buf_out;
        buf_out=NULL;
        signature->length=outl;
-       /* In the interests of compatability, I'll make sure that
+       /* In the interests of compatibility, I'll make sure that
         * the bit string has a 'not-used bits' value of 0
         */
        signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
@@ -138,8 +214,8 @@ int ASN1_sign(int (*i2d)(), X509_ALGOR *algor1, X509_ALGOR *algor2,
 err:
        memset(&ctx,0,sizeof(ctx));
        if (buf_in != NULL)
-               { memset((char *)buf_in,0,(unsigned int)inl); Free((char *)buf_in); }
+               { memset((char *)buf_in,0,(unsigned int)inl); OPENSSL_free(buf_in); }
        if (buf_out != NULL)
-               { memset((char *)buf_out,0,outll); Free((char *)buf_out); }
+               { memset((char *)buf_out,0,outll); OPENSSL_free(buf_out); }
        return(outl);
        }