Commit 09ab755c authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

ASN1_ITEM versions of sign, verify, pack and unpack.

The old function pointer versions will eventually go
away.
parent ec558b65
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -3,6 +3,10 @@

 Changes between 0.9.6 and 0.9.7  [xx XXX 2000]

  *) New ASN1 functions to handle sign, verify, digest, pack and
     unpack operations in terms of ASN1_ITEM.
     [Steve Henson]

  *) New extension functions for OCSP structures, these follow the
     same conventions as certificates and CRLs.
     [Steve Henson]
+18 −0
Original line number Diff line number Diff line
@@ -88,3 +88,21 @@ int ASN1_digest(int (*i2d)(), const EVP_MD *type, char *data,
	return(1);
	}


int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
		unsigned char *md, unsigned int *len)
	{
	EVP_MD_CTX ctx;
	int i;
	unsigned char *str = NULL;

	i=ASN1_item_i2d(asn,&str, it);
	if (!str) return(0);

	EVP_DigestInit(&ctx,type);
	EVP_DigestUpdate(&ctx,str,i);
	EVP_DigestFinal(&ctx,md,len);
	OPENSSL_free(str);
	return(1);
	}
+73 −0
Original line number Diff line number Diff line
@@ -146,3 +146,76 @@ err:
		{ 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 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);
	}
+48 −0
Original line number Diff line number Diff line
@@ -117,3 +117,51 @@ int ASN1_verify(int (*i2d)(), X509_ALGOR *a, ASN1_BIT_STRING *signature,
err:
	return(ret);
	}


int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, ASN1_BIT_STRING *signature,
	     void *asn, EVP_PKEY *pkey)
	{
	EVP_MD_CTX ctx;
	const EVP_MD *type;
	unsigned char *buf_in=NULL;
	int ret= -1,i,inl;

	i=OBJ_obj2nid(a->algorithm);
	type=EVP_get_digestbyname(OBJ_nid2sn(i));
	if (type == NULL)
		{
		ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
		goto err;
		}

	inl = ASN1_item_i2d(asn, &buf_in, it);
	
	if (buf_in == NULL)
		{
		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_MALLOC_FAILURE);
		goto err;
		}

	EVP_VerifyInit(&ctx,type);
	EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl);

	memset(buf_in,0,(unsigned int)inl);
	OPENSSL_free(buf_in);

	if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
			(unsigned int)signature->length,pkey) <= 0)
		{
		ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
		ret=0;
		goto err;
		}
	/* we don't need to zero the 'ctx' because we just checked
	 * public information */
	/* memset(&ctx,0,sizeof(ctx)); */
	ret=1;
err:
	return(ret);
	}

+2 −0
Original line number Diff line number Diff line
@@ -852,7 +852,9 @@ STACK *ASN1_seq_unpack(unsigned char *buf, int len, char *(*d2i)(),
unsigned char *ASN1_seq_pack(STACK *safes, int (*i2d)(), unsigned char **buf,
			     int *len );
void *ASN1_unpack_string(ASN1_STRING *oct, char *(*d2i)());
void *ASN1_unpack_item(ASN1_STRING *oct, const ASN1_ITEM *it);
ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_OCTET_STRING **oct);
ASN1_STRING *ASN1_pack_item(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct);

void ASN1_STRING_set_default_mask(unsigned long mask);
int ASN1_STRING_set_default_mask_asc(char *p);
Loading