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]
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);
+ }
+
{ 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);
+ }
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);
+ }
+
+
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);
/* Pack an ASN1 object into an ASN1_STRING */
-ASN1_STRING *ASN1_pack_string (void *obj, int (*i2d)(), ASN1_STRING **oct)
+ASN1_STRING *ASN1_pack_string(void *obj, int (*i2d)(), ASN1_STRING **oct)
{
unsigned char *p;
ASN1_STRING *octmp;
return octmp;
}
+/* ASN1_ITEM versions of the above */
+
+ASN1_STRING *ASN1_pack_item(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
+{
+ ASN1_STRING *octmp;
+
+ if (!oct || !*oct) {
+ if (!(octmp = ASN1_STRING_new ())) {
+ ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ if (oct) *oct = octmp;
+ } else octmp = *oct;
+
+ if(octmp->data) {
+ OPENSSL_free(octmp->data);
+ octmp->data = NULL;
+ }
+
+ if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
+ ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR);
+ return NULL;
+ }
+ if (!octmp->data) {
+ ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ return octmp;
+}
+
+/* Extract an ASN1 object from an ASN1_STRING */
+
+void *ASN1_unpack_item(ASN1_STRING *oct, const ASN1_ITEM *it)
+{
+ unsigned char *p;
+ void *ret;
+
+ p = oct->data;
+ if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
+ ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR);
+ return ret;
+}
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_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data,
+ unsigned char *md,unsigned int *len);
+
+int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1,
+ ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey);
+
+int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
+ ASN1_BIT_STRING *signature,
+ void *data, EVP_PKEY *pkey, const EVP_MD *type);
#endif
int X509_set_version(X509 *x,long version);