/*
-   Copyright (c) 2002-5, Andrew McNab, University of Manchester
+   Copyright (c) 2002-10, Andrew McNab, University of Manchester
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or
 #include <openssl/bio.h>    
 #include <openssl/des.h>    
 #include <openssl/rand.h>
+#include <openssl/objects.h>
+#include <openssl/asn1.h>
 
 #include "gridsite.h"
 
 {   
 #define GRST_ASN1_COORDS_VOMS_DN   "-1-1-%d-1-3-1-1-1-%%d-1-%%d"
 #define GRST_ASN1_COORDS_VOMS_INFO "-1-1-%d-1"
+#define GRST_ASN1_COORDS_VOMS_HASH "-1-1-%d-2-1"
 #define GRST_ASN1_COORDS_VOMS_SIG  "-1-1-%d-3"
-   int            ret, isig, iinfo;
+   int            ret, isig, ihash, iinfo;
    char          *certpath, acvomsdn[200], dn_coords[200],
-                  info_coords[200], sig_coords[200];
-   unsigned char *q;
+                  info_coords[200], sig_coords[200], hash_coords[200];
+   unsigned char *q, *p;
    DIR           *vomsDIR;
    struct dirent *vomsdirent;
    X509          *cert;
    EVP_PKEY      *prvkey;
    FILE          *fp;
    EVP_MD_CTX     ctx;
+   EVP_MD       *md_type = NULL;
    time_t         voms_service_time1, voms_service_time2;
+   ASN1_OBJECT   *hash_obj = NULL;
 
    if ((vomsdir == NULL) || (vomsdir[0] == '\0')) return GRST_RET_FAILED;
 
             GRST_ASN1_COORDS_VOMS_INFO, acnumber);
    iinfo = GRSTasn1SearchTaglist(taglist, lasttag, info_coords);
 
+   snprintf(hash_coords, sizeof(hash_coords), 
+            GRST_ASN1_COORDS_VOMS_HASH, acnumber);
+   ihash  = GRSTasn1SearchTaglist(taglist, lasttag, hash_coords);
+
    snprintf(sig_coords, sizeof(sig_coords), 
             GRST_ASN1_COORDS_VOMS_SIG, acnumber);
    isig  = GRSTasn1SearchTaglist(taglist, lasttag, sig_coords);
 
-   if ((iinfo < 0) || (isig < 0)) return GRST_RET_FAILED;
+   if ((iinfo < 0) || (ihash < 0) || (isig < 0)) return GRST_RET_FAILED;
+
+   /* determine hash algorithm's type */
+
+   p = &asn1string[taglist[ihash].start];
+   
+   d2i_ASN1_OBJECT(&hash_obj, (const unsigned char **) &p, 
+                   (long) (taglist[ihash].length+taglist[ihash].headerlength));
+    
+   if (hash_obj == NULL) return GRST_RET_FAILED;
+
+   md_type = (EVP_MD *) EVP_get_digestbyname(OBJ_nid2sn(OBJ_obj2nid(hash_obj)));
+
+   if (md_type == NULL) return GRST_RET_FAILED;
+    
 
    vomsDIR = opendir(vomsdir);
    if (vomsDIR == NULL) return GRST_RET_FAILED;
           OpenSSL_add_all_digests();
 #if OPENSSL_VERSION_NUMBER >= 0x0090701fL
           EVP_MD_CTX_init(&ctx);
-          EVP_VerifyInit_ex(&ctx, EVP_md5(), NULL);
+          EVP_VerifyInit_ex(&ctx, md_type, NULL);
 #else
-          EVP_VerifyInit(&ctx, EVP_md5());
+          EVP_VerifyInit(&ctx, md_type);
 #endif
           
           EVP_VerifyUpdate(&ctx,