Diff

Differences From Artifact [05aec72ac3]:

To Artifact [e7404c7b1a]:


    51     51   #define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
    52     52   #define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
    53     53   #ifndef NULL_PTR
    54     54   #  define NULL_PTR 0
    55     55   #endif
    56     56   
    57     57   #include "pkcs11.h"
           58  +#include "pkcs11n.h"
    58     59   #include "asn1-x509.h"
           60  +#include "sha1.h"
           61  +#include "md5.h"
    59     62   
    60     63   #ifndef CACKEY_CRYPTOKI_VERSION_CODE
    61     64   #  define CACKEY_CRYPTOKI_VERSION_CODE 0x021e00
    62     65   #endif
    63     66   
    64         -#ifndef CKA_TRUST_SERVER_AUTH
    65         -#  define CKA_TRUST_SERVER_AUTH 0xce536358
    66         -#endif
    67         -#ifndef CKA_TRUST_CLIENT_AUTH
    68         -#  define CKA_TRUST_CLIENT_AUTH 0xce536359
    69         -#endif
    70         -#ifndef CKA_TRUST_CODE_SIGNING
    71         -#  define CKA_TRUST_CODE_SIGNING 0xce53635a
    72         -#endif
    73         -#ifndef CKA_TRUST_EMAIL_PROTECTION
    74         -#  define CKA_TRUST_EMAIL_PROTECTION 0xce53635b
    75         -#endif
    76         -
    77     67   /* GSC-IS v2.1 Definitions */
    78     68   /** Classes **/
    79     69   #define GSCIS_CLASS_ISO7816           0x00
    80     70   #define GSCIS_CLASS_GLOBAL_PLATFORM   0x80
    81     71   
    82     72   /** Instructions **/
    83     73   #define GSCIS_INSTR_GET_RESPONSE      0xC0
................................................................................
   619    609   /* CACKEY Global Handles */
   620    610   static void *cackey_biglock = NULL;
   621    611   static struct cackey_session cackey_sessions[128];
   622    612   static struct cackey_slot cackey_slots[128];
   623    613   static int cackey_initialized = 0;
   624    614   static int cackey_biglock_init = 0;
   625    615   CK_C_INITIALIZE_ARGS cackey_args;
          616  +
          617  +/** Extra certificates to include in token **/
          618  +struct cackey_pcsc_identity extra_certs[] = {
          619  +#include "cackey_builtin_certs.h"
          620  +};
   626    621   
   627    622   /* PCSC Global Handles */
   628    623   static LPSCARDCONTEXT cackey_pcsc_handle = NULL;
   629    624   
   630    625   static unsigned long cackey_getversion(void) {
   631    626   	static unsigned long retval = 255;
   632    627   	unsigned long major = 0;
................................................................................
  1885   1880    *
  1886   1881    * NOTES
  1887   1882    *     ...
  1888   1883    *
  1889   1884    */
  1890   1885   static void cackey_free_certs(struct cackey_pcsc_identity *start, size_t count, int free_start) {
  1891   1886   	size_t idx;
         1887  +
         1888  +	if (start == NULL) {
         1889  +		return;
         1890  +	}
  1892   1891   
  1893   1892   	for (idx = 0; idx < count; idx++) {
  1894   1893   		if (start[idx].certificate) {
  1895   1894   			free(start[idx].certificate);
  1896   1895   		}
  1897   1896   	}
  1898   1897   
................................................................................
  2664   2663   
  2665   2664   	return(0);
  2666   2665   }
  2667   2666   
  2668   2667   static CK_ATTRIBUTE_PTR cackey_get_attributes(CK_OBJECT_CLASS objectclass, struct cackey_pcsc_identity *identity, unsigned long identity_num, CK_ULONG_PTR pulCount) {
  2669   2668   	static CK_BBOOL ck_true = 1;
  2670   2669   	static CK_BBOOL ck_false = 0;
         2670  +	static CK_TRUST ck_trusted = CK_TRUSTED_DELEGATOR;
  2671   2671   	CK_ULONG numattrs = 0, retval_count;
  2672   2672   	CK_ATTRIBUTE_TYPE curr_attr_type;
  2673   2673   	CK_ATTRIBUTE curr_attr, *retval;
  2674   2674   	CK_VOID_PTR pValue;
  2675   2675   	CK_ULONG ulValueLen;
  2676   2676   	CK_OBJECT_CLASS ck_object_class;
  2677   2677   	CK_CERTIFICATE_TYPE ck_certificate_type;
  2678   2678   	CK_KEY_TYPE ck_key_type;
  2679   2679   	CK_UTF8CHAR ucTmpBuf[1024];
         2680  +	SHA1Context sha1_ctx;
         2681  +	MD5_CTX md5_ctx;
         2682  +	uint8_t sha1_hash[SHA1HashSize];
         2683  +	uint8_t md5_hash[MD5HashSize];
  2680   2684   	unsigned char *certificate;
  2681   2685   	ssize_t certificate_len = -1, x509_read_ret;
  2682   2686   	int pValue_free;
  2683   2687   
  2684   2688   	CACKEY_DEBUG_PRINTF("Called (objectClass = %lu, identity_num = %lu).", (unsigned long) objectclass, identity_num);
  2685   2689   
  2686         -	if (objectclass != CKO_CERTIFICATE && objectclass != CKO_PUBLIC_KEY && objectclass != CKO_PRIVATE_KEY) {
         2690  +	*pulCount = 0;
         2691  +
         2692  +	if (objectclass != CKO_CERTIFICATE && objectclass != CKO_PUBLIC_KEY && objectclass != CKO_PRIVATE_KEY && objectclass != CKO_NETSCAPE_TRUST) {
  2687   2693   		CACKEY_DEBUG_PRINTF("Returning 0 objects (NULL), invalid object class");
  2688   2694   
  2689   2695   		return(NULL);
  2690   2696   	}
  2691   2697   
  2692   2698   	/* Get Cert */
  2693   2699   	if (identity == NULL) {
................................................................................
  2708   2714   	/* Verify that certificate is ASN.1 encoded X.509 certificate */
  2709   2715   	if (x509_to_serial(certificate, certificate_len, NULL) < 0) {
  2710   2716   		CACKEY_DEBUG_PRINTF("Returning 0 objects (NULL), the X.509 certificate associated with this identity is not valid");
  2711   2717   
  2712   2718   		return(NULL);
  2713   2719   	}
  2714   2720   
  2715         -	retval_count = 16;
         2721  +	retval_count = 64;
  2716   2722   	retval = malloc(retval_count * sizeof(*retval));
  2717   2723   
  2718         -	for (curr_attr_type = 0; curr_attr_type < 0xce53635f; curr_attr_type++) {
         2724  +	for (curr_attr_type = 0; curr_attr_type < 0xce5363bf; curr_attr_type++) {
  2719   2725   		if (curr_attr_type == 0x800) {
  2720   2726   			curr_attr_type = 0xce536300;
  2721   2727   		}
  2722   2728   
  2723   2729   		pValue_free = 0;
  2724   2730   		pValue = NULL;
  2725   2731   		ulValueLen = (CK_LONG) -1;
................................................................................
  2740   2746   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TOKEN (0x%08lx) ...", (unsigned long) curr_attr_type);
  2741   2747   
  2742   2748   				pValue = &ck_true;
  2743   2749   				ulValueLen = sizeof(ck_true);
  2744   2750   
  2745   2751   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2746   2752   
         2753  +				break;
         2754  +			case CKA_PRIVATE:
         2755  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_PRIVATE (0x%08lx) ...", (unsigned long) curr_attr_type);
         2756  +
         2757  +				if (objectclass != CKO_NETSCAPE_TRUST) {
         2758  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a Netscape trust object");
         2759  +
         2760  +					break;
         2761  +				}
         2762  +
         2763  +				pValue = &ck_false;
         2764  +				ulValueLen = sizeof(ck_false);
         2765  +
         2766  +				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
         2767  +
  2747   2768   				break;
  2748   2769   			case CKA_TRUSTED:
  2749   2770   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TRUSTED (0x%08lx) ...", (unsigned long) curr_attr_type);
         2771  +
         2772  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         2773  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         2774  +
         2775  +					break;
         2776  +				}
  2750   2777   
  2751   2778   				pValue = &ck_true;
  2752   2779   				ulValueLen = sizeof(ck_true);
  2753   2780   
  2754   2781   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2755   2782   
  2756   2783   				break;
................................................................................
  2781   2808   			case CKA_VALUE:
  2782   2809   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_VALUE (0x%08lx) ...", (unsigned long) curr_attr_type);
  2783   2810   
  2784   2811   				switch (objectclass) {
  2785   2812   					case CKO_PRIVATE_KEY:
  2786   2813   						CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a private key.");
  2787   2814   
         2815  +						break;
         2816  +					case CKO_NETSCAPE_TRUST:
         2817  +						CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         2818  +
  2788   2819   						break;
  2789   2820   					case CKO_PUBLIC_KEY:
  2790   2821   						/* XXX: TODO */
  2791   2822   
  2792   2823   						break;
  2793   2824   					case CKO_CERTIFICATE:
  2794   2825   						pValue = certificate;
................................................................................
  2799   2830   
  2800   2831   				CACKEY_DEBUG_PRINTF(" ... returning %p/%lu", pValue, (unsigned long) ulValueLen);
  2801   2832   
  2802   2833   				break;
  2803   2834   			case CKA_ISSUER:
  2804   2835   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_ISSUER (0x%08lx) ...", (unsigned long) curr_attr_type);
  2805   2836   
  2806         -				if (objectclass != CKO_CERTIFICATE) {
  2807         -					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a certificate.");
         2837  +				if (objectclass != CKO_CERTIFICATE && objectclass != CKO_NETSCAPE_TRUST) {
         2838  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a certificate or Netscape trust object");
  2808   2839   
  2809   2840   					break;
  2810   2841   				}
  2811   2842   
  2812   2843   				if (certificate_len >= 0) {
  2813   2844   					x509_read_ret = x509_to_issuer(certificate, certificate_len, &pValue);
  2814   2845   					if (x509_read_ret < 0) {
................................................................................
  2820   2851   
  2821   2852   				CACKEY_DEBUG_PRINTF(" ... returning %p/%lu", pValue, (unsigned long) ulValueLen);
  2822   2853   
  2823   2854   				break;
  2824   2855   			case CKA_SERIAL_NUMBER:
  2825   2856   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_SERIAL_NUMBER (0x%08lx) ...", (unsigned long) curr_attr_type);
  2826   2857   
  2827         -				if (objectclass != CKO_CERTIFICATE) {
  2828         -					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a certificate.");
         2858  +				if (objectclass != CKO_CERTIFICATE && objectclass != CKO_NETSCAPE_TRUST) {
         2859  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a certificate or Netscape trust object");
  2829   2860   
  2830   2861   					break;
  2831   2862   				}
  2832   2863   
  2833   2864   				if (certificate_len >= 0) {
  2834   2865   					x509_read_ret = x509_to_serial(certificate, certificate_len, &pValue);
  2835   2866   					if (x509_read_ret < 0) {
................................................................................
  2842   2873   				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);
  2843   2874   
  2844   2875   				break;
  2845   2876   			case CKA_SUBJECT:
  2846   2877   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_SUBJECT (0x%08lx) ...", (unsigned long) curr_attr_type);
  2847   2878   
  2848   2879   				if (objectclass != CKO_CERTIFICATE) {
  2849         -					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a certificate.");
         2880  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a certificate");
  2850   2881   
  2851   2882   					break;
  2852   2883   				}
  2853   2884   
  2854   2885   				if (certificate_len >= 0) {
  2855   2886   					x509_read_ret = x509_to_subject(certificate, certificate_len, &pValue);
  2856   2887   					if (x509_read_ret < 0) {
................................................................................
  2861   2892   				}
  2862   2893   
  2863   2894   				CACKEY_DEBUG_PRINTF(" ... returning %p/%lu", pValue, (unsigned long) ulValueLen);
  2864   2895   
  2865   2896   				break;
  2866   2897   			case CKA_ID:
  2867   2898   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_ID (0x%08lx) ...", (unsigned long) curr_attr_type);
         2899  +
         2900  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         2901  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         2902  +
         2903  +					break;
         2904  +				}
  2868   2905   
  2869   2906   				ucTmpBuf[0] = ((identity_num + 1) >> 8) & 0xff;
  2870   2907   				ucTmpBuf[1] =  (identity_num + 1) & 0xff;
  2871   2908   
  2872   2909   				pValue = &ucTmpBuf;
  2873   2910   				ulValueLen = 2;
  2874   2911   
................................................................................
  2909   2946   				ulValueLen = sizeof(ck_key_type);
  2910   2947   
  2911   2948   				CACKEY_DEBUG_PRINTF(" ... returning CKK_RSA (%lu) (%p/%lu)", (unsigned long) *((CK_CERTIFICATE_TYPE *) pValue), pValue, (unsigned long) ulValueLen);
  2912   2949   
  2913   2950   				break;
  2914   2951   			case CKA_SIGN:
  2915   2952   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_SIGN (0x%08lx) ...", (unsigned long) curr_attr_type);
         2953  +
         2954  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         2955  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         2956  +
         2957  +					break;
         2958  +				}
  2916   2959   
  2917   2960   				if (objectclass == CKO_PRIVATE_KEY) {
  2918   2961   					pValue = &ck_true;
  2919   2962   					ulValueLen = sizeof(ck_true);
  2920   2963   				} else {
  2921   2964   					pValue = &ck_false;
  2922   2965   					ulValueLen = sizeof(ck_false);
................................................................................
  2923   2966   				}
  2924   2967   
  2925   2968   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2926   2969   
  2927   2970   				break;
  2928   2971   			case CKA_SIGN_RECOVER:
  2929   2972   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_SIGN_RECOVER (0x%08lx) ...", (unsigned long) curr_attr_type);
         2973  +
         2974  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         2975  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         2976  +
         2977  +					break;
         2978  +				}
  2930   2979   
  2931   2980   				/* We currently only support "Sign with Appendix" */
  2932   2981   				pValue = &ck_false;
  2933   2982   				ulValueLen = sizeof(ck_false);
  2934   2983   
  2935   2984   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2936   2985   
  2937   2986   				break;
  2938   2987   			case CKA_DECRYPT:
  2939   2988   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_DECRYPT (0x%08lx) ...", (unsigned long) curr_attr_type);
         2989  +
         2990  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         2991  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         2992  +
         2993  +					break;
         2994  +				}
  2940   2995   
  2941   2996   				if (objectclass == CKO_PRIVATE_KEY || objectclass == CKO_PUBLIC_KEY) {
  2942   2997   					pValue = &ck_true;
  2943   2998   					ulValueLen = sizeof(ck_true);
  2944   2999   				} else {
  2945   3000   					pValue = &ck_false;
  2946   3001   					ulValueLen = sizeof(ck_false);
................................................................................
  2947   3002   				}
  2948   3003   
  2949   3004   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2950   3005   
  2951   3006   				break;
  2952   3007   			case CKA_SENSITIVE:
  2953   3008   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_SENSITIVE (0x%08lx) ...", (unsigned long) curr_attr_type);
         3009  +
         3010  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         3011  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         3012  +
         3013  +					break;
         3014  +				}
  2954   3015   
  2955   3016   				if (objectclass == CKO_PRIVATE_KEY) {
  2956   3017   					pValue = &ck_true;
  2957   3018   					ulValueLen = sizeof(ck_true);
  2958   3019   				} else {
  2959   3020   					pValue = &ck_false;
  2960   3021   					ulValueLen = sizeof(ck_false);
................................................................................
  2961   3022   				}
  2962   3023   
  2963   3024   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2964   3025   
  2965   3026   				break;
  2966   3027   			case CKA_EXTRACTABLE:
  2967   3028   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_EXTRACTABLE (0x%08lx) ...", (unsigned long) curr_attr_type);
         3029  +
         3030  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         3031  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         3032  +
         3033  +					break;
         3034  +				}
  2968   3035   
  2969   3036   				if (objectclass == CKO_PRIVATE_KEY) {
  2970   3037   					pValue = &ck_false;
  2971   3038   					ulValueLen = sizeof(ck_true);
  2972   3039   				} else {
  2973   3040   					pValue = &ck_true;
  2974   3041   					ulValueLen = sizeof(ck_false);
................................................................................
  2975   3042   				}
  2976   3043   
  2977   3044   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2978   3045   
  2979   3046   				break;
  2980   3047   			case CKA_MODULUS:
  2981   3048   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_MODULUS (0x%08lx) ...", (unsigned long) curr_attr_type);
         3049  +
         3050  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         3051  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         3052  +
         3053  +					break;
         3054  +				}
  2982   3055   
  2983   3056   				if (certificate_len >= 0) {
  2984   3057   					x509_read_ret = x509_to_modulus(certificate, certificate_len, &pValue);
  2985   3058   					if (x509_read_ret < 0) {
  2986   3059   						pValue = NULL;
  2987   3060   					} else {
  2988   3061   						ulValueLen = x509_read_ret;
................................................................................
  2990   3063   				}
  2991   3064   
  2992   3065   				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);
  2993   3066   
  2994   3067   				break;
  2995   3068   			case CKA_PUBLIC_EXPONENT:
  2996   3069   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_PUBLIC_EXPONENT (0x%08lx) ...", (unsigned long) curr_attr_type);
         3070  +
         3071  +				if (objectclass == CKO_NETSCAPE_TRUST) {
         3072  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are a Netscape trust object");
         3073  +
         3074  +					break;
         3075  +				}
  2997   3076   
  2998   3077   				if (certificate_len >= 0) {
  2999   3078   					x509_read_ret = x509_to_exponent(certificate, certificate_len, &pValue);
  3000   3079   					if (x509_read_ret < 0) {
  3001   3080   						pValue = NULL;
  3002   3081   					} else {
  3003   3082   						ulValueLen = x509_read_ret;
  3004   3083   					}
  3005   3084   				}
  3006   3085   
  3007   3086   				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);
  3008   3087   
  3009   3088   				break;
         3089  +			case CKA_TRUST_DIGITAL_SIGNATURE:
         3090  +			case CKA_TRUST_NON_REPUDIATION:
         3091  +			case CKA_TRUST_KEY_ENCIPHERMENT:
         3092  +			case CKA_TRUST_DATA_ENCIPHERMENT:
         3093  +			case CKA_TRUST_KEY_AGREEMENT:
         3094  +			case CKA_TRUST_KEY_CERT_SIGN:
         3095  +			case CKA_TRUST_CRL_SIGN:
  3010   3096   			case CKA_TRUST_SERVER_AUTH:
  3011         -				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TRUST_SERVER_AUTH (0x%08lx) ...", (unsigned long) curr_attr_type);
         3097  +			case CKA_TRUST_CLIENT_AUTH:
         3098  +			case CKA_TRUST_CODE_SIGNING:
         3099  +			case CKA_TRUST_EMAIL_PROTECTION:
         3100  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TRUST_... (0x%08lx) ...", (unsigned long) curr_attr_type);
  3012   3101   
  3013         -				pValue = &ck_true;
  3014         -				ulValueLen = sizeof(ck_true);
         3102  +				pValue = &ck_trusted;
         3103  +				ulValueLen = sizeof(ck_trusted);
  3015   3104   
  3016         -				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
         3105  +				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_TRUST *) pValue), pValue, (unsigned long) ulValueLen);
  3017   3106   
  3018   3107   				break;
  3019         -			case CKA_TRUST_CLIENT_AUTH:
  3020         -				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TRUST_CLIENT_AUTH (0x%08lx) ...", (unsigned long) curr_attr_type);
         3108  +			case CKA_CERT_SHA1_HASH:
         3109  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_CERT_SHA1_HASH (0x%08lx) ...", (unsigned long) curr_attr_type);
  3021   3110   
  3022         -				pValue = &ck_true;
  3023         -				ulValueLen = sizeof(ck_true);
         3111  +				if (objectclass != CKO_NETSCAPE_TRUST) {
         3112  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a Netscape trust object");
  3024   3113   
  3025         -				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
         3114  +					break;
         3115  +				}
         3116  +
         3117  +				SHA1Reset(&sha1_ctx);
         3118  +				SHA1Input(&sha1_ctx, certificate, certificate_len);
         3119  +				SHA1Result(&sha1_ctx, sha1_hash);
         3120  +
         3121  +				pValue = sha1_hash;
         3122  +				ulValueLen = sizeof(sha1_hash);
         3123  +
         3124  +				CACKEY_DEBUG_PRINTF(" ... returning %p/%lu", pValue, (unsigned long) ulValueLen);
  3026   3125   
  3027   3126   				break;
  3028         -			case CKA_TRUST_CODE_SIGNING:
  3029         -				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TRUST_CODE_SIGNING (0x%08lx) ...", (unsigned long) curr_attr_type);
         3127  +			case CKA_CERT_MD5_HASH:
         3128  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_CERT_MD5_HASH (0x%08lx) ...", (unsigned long) curr_attr_type);
  3030   3129   
  3031         -				pValue = &ck_true;
  3032         -				ulValueLen = sizeof(ck_true);
         3130  +				if (objectclass != CKO_NETSCAPE_TRUST) {
         3131  +					CACKEY_DEBUG_PRINTF(" ... but not getting it because we are not a Netscape trust object");
  3033   3132   
  3034         -				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
         3133  +					break;
         3134  +				}
  3035   3135   
  3036         -				break;
  3037         -			case CKA_TRUST_EMAIL_PROTECTION:
  3038         -				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TRUST_EMAIL_PROTECTION (0x%08lx) ...", (unsigned long) curr_attr_type);
         3136  +				MD5Init(&md5_ctx);
         3137  +				MD5Update(&md5_ctx, certificate, certificate_len);
         3138  +				MD5Final(md5_hash, &md5_ctx);
  3039   3139   
  3040         -				pValue = &ck_true;
  3041         -				ulValueLen = sizeof(ck_true);
         3140  +				pValue = md5_hash;
         3141  +				ulValueLen = sizeof(md5_hash);
  3042   3142   
  3043         -				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
         3143  +				CACKEY_DEBUG_PRINTF(" ... returning %p/%lu", pValue, (unsigned long) ulValueLen);
  3044   3144   
  3045   3145   				break;
  3046   3146   			default:
  3047   3147   				pValue = NULL;
  3048   3148   				ulValueLen = (CK_LONG) -1;
  3049   3149   				break;
  3050   3150   		}
................................................................................
  3058   3158   			memcpy(curr_attr.pValue, pValue, curr_attr.ulValueLen);
  3059   3159   
  3060   3160   			if (pValue_free && pValue) {
  3061   3161   				free(pValue);
  3062   3162   			}
  3063   3163   
  3064   3164   			if (numattrs >= retval_count) {
  3065         -				retval_count *= 2;
  3066   3165   				retval = realloc(retval, retval_count * sizeof(*retval));
  3067   3166   			}
  3068   3167   
  3069   3168   			memcpy(&retval[numattrs], &curr_attr, sizeof(curr_attr));
  3070   3169   			numattrs++;
  3071   3170   		}
  3072   3171   	}
................................................................................
  3116   3215   	free(identities);
  3117   3216   }
  3118   3217   
  3119   3218   static struct cackey_identity *cackey_read_identities(struct cackey_slot *slot, unsigned long *ids_found) {
  3120   3219   	struct cackey_pcsc_identity *pcsc_identities;
  3121   3220   	struct cackey_identity *identities;
  3122   3221   	unsigned long num_ids, id_idx, curr_id_type;
  3123         -	unsigned long num_certs, cert_idx;
         3222  +	unsigned long num_certs, num_extra_certs, cert_idx;
  3124   3223   
  3125   3224   	CACKEY_DEBUG_PRINTF("Called.");
         3225  +
         3226  +	num_extra_certs = sizeof(extra_certs) / sizeof(extra_certs[0]);
  3126   3227   
  3127   3228   	if (ids_found == NULL) {
  3128   3229   		CACKEY_DEBUG_PRINTF("Error.  ids_found is NULL");
  3129   3230   
  3130   3231   		return(NULL);
  3131   3232   	}
  3132   3233   
  3133   3234   	pcsc_identities = cackey_read_certs(slot, NULL, &num_certs);
  3134   3235   	if (pcsc_identities != NULL) {
  3135   3236   		/* Convert number of Certs to number of objects */
  3136   3237   		num_ids = (CKO_PRIVATE_KEY - CKO_CERTIFICATE + 1) * num_certs;
         3238  +		num_ids += num_extra_certs * 2;
  3137   3239   
  3138   3240   		identities = malloc(num_ids * sizeof(*identities));
  3139   3241   
         3242  +		/* Add certificates, public keys, and private keys from the smartcard */
  3140   3243   		id_idx = 0;
  3141   3244   		for (cert_idx = 0; cert_idx < num_certs; cert_idx++) {
  3142   3245   			for (curr_id_type = CKO_CERTIFICATE; curr_id_type <= CKO_PRIVATE_KEY; curr_id_type++) {
  3143   3246   				identities[id_idx].attributes = cackey_get_attributes(curr_id_type, &pcsc_identities[cert_idx], cert_idx, &identities[id_idx].attributes_count);
  3144   3247   
  3145         -				if (identities[id_idx].attributes == NULL) {
  3146         -					identities[id_idx].attributes_count = 0;
  3147         -				}
  3148         -
  3149   3248   				identities[id_idx].pcsc_identity = malloc(sizeof(*identities[id_idx].pcsc_identity));
  3150   3249   				memcpy(identities[id_idx].pcsc_identity, &pcsc_identities[cert_idx], sizeof(*identities[id_idx].pcsc_identity));
  3151   3250   
  3152   3251   				identities[id_idx].pcsc_identity->certificate = malloc(pcsc_identities[cert_idx].certificate_len);
  3153   3252   				memcpy(identities[id_idx].pcsc_identity->certificate, pcsc_identities[cert_idx].certificate, pcsc_identities[cert_idx].certificate_len);
  3154   3253   
  3155   3254   				id_idx++;
  3156   3255   			}
  3157   3256   		}
  3158   3257   
  3159   3258   		cackey_free_certs(pcsc_identities, num_certs, 1);
         3259  +
         3260  +		/* Add DoD Certificates and Netscape Trust Objects */
         3261  +		for (cert_idx = 0; cert_idx < num_extra_certs; cert_idx++) {
         3262  +			identities[id_idx].pcsc_identity = NULL;
         3263  +			identities[id_idx].attributes = cackey_get_attributes(CKO_CERTIFICATE, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
         3264  +
         3265  +			id_idx++;
         3266  +		}
         3267  +
         3268  +		for (cert_idx = 0; cert_idx < num_extra_certs; cert_idx++) {
         3269  +			identities[id_idx].pcsc_identity = NULL;
         3270  +			identities[id_idx].attributes = cackey_get_attributes(CKO_NETSCAPE_TRUST, &extra_certs[cert_idx], 0xf000 | cert_idx, &identities[id_idx].attributes_count);
         3271  +
         3272  +			id_idx++;
         3273  +		}
  3160   3274   
  3161   3275   		*ids_found = num_ids;
  3162   3276   		return(identities);
  3163   3277   	}
  3164   3278   
  3165   3279   	*ids_found = 0;
  3166   3280   	return(NULL);
................................................................................
  4630   4744   	return(CKR_OK);
  4631   4745   }
  4632   4746   
  4633   4747   static int cackey_pkcs11_compare_attributes(CK_ATTRIBUTE *a, CK_ATTRIBUTE *b) {
  4634   4748   	unsigned char *smallbuf, *largebuf;
  4635   4749   	size_t smallbuf_len, largebuf_len;
  4636   4750   
  4637         -	CACKEY_DEBUG_PRINTF("Called.");
  4638         -
  4639   4751   	if (a->type != b->type) {
  4640   4752   		return(0);
  4641   4753   	}
  4642   4754   
  4643   4755   	CACKEY_DEBUG_PRINTF("    ... found matching type ...");
  4644   4756   
  4645   4757   	CACKEY_DEBUG_PRINTBUF("    ... our value:", a->pValue, a->ulValueLen);