summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2007-05-11 22:35:00 +0000
committerStef Walter <stef@memberwebs.com>2007-05-11 22:35:00 +0000
commit014f22be6a744dd3d116476d95009dd654333311 (patch)
tree31470db52ae7776ec42cab3bbdcfbed379698d06
parent100c6af02cfe6f4b8b173d22bd93548a5dd79171 (diff)
Do proper usage vs. enhanced usage.
-rw-r--r--ckcapi-builtin.c4
-rw-r--r--ckcapi-cert.c10
-rw-r--r--ckcapi-trust.c162
-rw-r--r--ckcapi.h2
4 files changed, 137 insertions, 41 deletions
diff --git a/ckcapi-builtin.c b/ckcapi-builtin.c
index 26e9cd9..58a02d8 100644
--- a/ckcapi-builtin.c
+++ b/ckcapi-builtin.c
@@ -230,9 +230,9 @@ ckcapi_builtin_find(CkCapiSession* sess, CK_OBJECT_CLASS cls, CK_ATTRIBUTE_PTR m
{
/* Only apply built in objects to appropriate slots */
fl = ckcapi_token_get_flags(sess->slot) & all_builtins[i].slot_flags;
- if(fl != all_builtins[i].slot_flags)
+ /* if(fl != all_builtins[i].slot_flags)
continue;
-
+ */
bdata.attr = all_builtins[i].attr;
bdata.base.object = 0;
bdata.base.data_funcs = &builtin_objdata_vtable;
diff --git a/ckcapi-cert.c b/ckcapi-cert.c
index 15ab880..9937486 100644
--- a/ckcapi-cert.c
+++ b/ckcapi-cert.c
@@ -29,8 +29,6 @@
#define CERT_KEY_IDENTIFIER_PROP_ID 20
#endif
-#define USE_ENCODINGS (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
-
typedef struct _CertObject
{
CkCapiObject obj;
@@ -244,7 +242,7 @@ cert_load_data(CkCapiSession* sess, CkCapiObject* obj, CkCapiObjectData** objdat
memcpy(&info.SerialNumber, &cobj->serial, sizeof(info.SerialNumber));
memcpy(&info.Issuer, &cobj->issuer, sizeof(info.Issuer));
- cert = CertGetSubjectCertificateFromStore(sess->store, USE_ENCODINGS, &info);
+ cert = CertGetSubjectCertificateFromStore(sess->store, CKCAPI_ENCODINGS, &info);
if(!cert)
{
@@ -572,7 +570,7 @@ match_in_store(CkCapiSession* sess, PCERT_INFO info, CK_ATTRIBUTE_PTR match,
if(!sess->store)
return CKR_OK;
- cert = CertGetSubjectCertificateFromStore(sess->store, USE_ENCODINGS, info);
+ cert = CertGetSubjectCertificateFromStore(sess->store, CKCAPI_ENCODINGS, info);
if(cert == NULL)
{
err = GetLastError();
@@ -642,14 +640,14 @@ ckcapi_cert_find(CkCapiSession* sess, CK_OBJECT_CLASS cls, CK_ATTRIBUTE_PTR matc
}
else if(!serial && match[i].type == CKA_SERIAL_NUMBER)
{
- if(!CryptDecodeObject(USE_ENCODINGS, X509_MULTI_BYTE_INTEGER,
+ if(!CryptDecodeObject(CKCAPI_ENCODINGS, X509_MULTI_BYTE_INTEGER,
match[i].pValue, match[i].ulValueLen, 0, NULL, &size))
{
continue;
}
serial = calloc(1, size);
- if(!CryptDecodeObject(USE_ENCODINGS, X509_MULTI_BYTE_INTEGER,
+ if(!CryptDecodeObject(CKCAPI_ENCODINGS, X509_MULTI_BYTE_INTEGER,
match[i].pValue, match[i].ulValueLen, 0, serial, &size))
continue;
diff --git a/ckcapi-trust.c b/ckcapi-trust.c
index 327f385..16e3874 100644
--- a/ckcapi-trust.c
+++ b/ckcapi-trust.c
@@ -54,29 +54,42 @@ typedef struct _TrustObjectData
CkCapiObjectData base;
PCCERT_CONTEXT cert;
- CERT_ENHKEY_USAGE* usage;
+ CERT_ENHKEY_USAGE* enhanced_usage;
+
+ BOOL has_usage;
+ BYTE usage;
}
TrustObjectData;
-static CK_ULONG
-has_usage(TrustObjectData* tdata, const char* oid)
+static CK_TRUST
+has_usage(TrustObjectData* tdata, BYTE restriction)
+{
+ if(!tdata->has_usage)
+ CKT_NETSCAPE_TRUST_UNKNOWN;
+ if((tdata->usage & restriction) == restriction)
+ return CKT_NETSCAPE_TRUSTED;
+ return CKT_NETSCAPE_UNTRUSTED;
+
+}
+
+static CK_TRUST
+has_enhanced_usage(TrustObjectData* tdata, const char* oid)
{
- CERT_ENHKEY_USAGE* usage = tdata->usage;
+ CERT_ENHKEY_USAGE* eusage = tdata->enhanced_usage;
DWORD i;
/* No usages, means anything goes */
- if(usage == NULL)
+ if(eusage == NULL)
return CKT_NETSCAPE_TRUSTED_DELEGATOR;
- for(i = 0; i < usage->cUsageIdentifier; ++i)
+ for(i = 0; i < eusage->cUsageIdentifier; ++i)
{
- if(usage->rgpszUsageIdentifier[i] &&
- strcmp(oid, usage->rgpszUsageIdentifier[i]) == 0)
+ if(eusage->rgpszUsageIdentifier[i] &&
+ strcmp(oid, eusage->rgpszUsageIdentifier[i]) == 0)
return CKT_NETSCAPE_TRUSTED_DELEGATOR;
}
- /* TODO: What's the correct thing to return here? */
- return CKT_NETSCAPE_VALID_DELEGATOR;
+ return CKT_NETSCAPE_TRUST_UNKNOWN;
}
static CK_RV
@@ -107,10 +120,9 @@ trust_bool_attribute(CkCapiObjectData* objdata, CK_ATTRIBUTE_PTR attr)
/*
* If object can be modified.
- * TODO: This needs to be set to yes once we get change support.
*/
case CKA_MODIFIABLE:
- val = CK_FALSE;
+ val = CK_TRUE;
break;
/*
@@ -148,31 +160,56 @@ trust_ulong_attribute(CkCapiObjectData* objdata, CK_ATTRIBUTE_PTR attr)
break;
/*
+ * Key restrictions
+ */
+ case CKA_TRUST_DIGITAL_SIGNATURE:
+ val = has_usage(tdata, CERT_DIGITAL_SIGNATURE_KEY_USAGE);
+ break;
+ case CKA_TRUST_NON_REPUDIATION:
+ val = has_usage(tdata, CERT_NON_REPUDIATION_KEY_USAGE);
+ break;
+ case CKA_TRUST_KEY_ENCIPHERMENT:
+ val = has_usage(tdata, CERT_KEY_ENCIPHERMENT_KEY_USAGE);
+ break;
+ case CKA_TRUST_DATA_ENCIPHERMENT:
+ val = has_usage(tdata, CERT_DATA_ENCIPHERMENT_KEY_USAGE);
+ break;
+ case CKA_TRUST_KEY_AGREEMENT:
+ val = has_usage(tdata, CERT_KEY_AGREEMENT_KEY_USAGE);
+ break;
+ case CKA_TRUST_KEY_CERT_SIGN:
+ val = has_usage(tdata, CERT_KEY_CERT_SIGN_KEY_USAGE);
+ break;
+ case CKA_TRUST_CRL_SIGN:
+ val = has_usage(tdata, CERT_CRL_SIGN_KEY_USAGE);
+ break;
+
+ /*
* Various trust flags
*/
case CKA_TRUST_SERVER_AUTH:
- val = has_usage(tdata, X509_USAGE_SERVER_AUTH);
+ val = has_enhanced_usage(tdata, X509_USAGE_SERVER_AUTH);
break;
case CKA_TRUST_CLIENT_AUTH:
- val = has_usage(tdata, X509_USAGE_CLIENT_AUTH);
+ val = has_enhanced_usage(tdata, X509_USAGE_CLIENT_AUTH);
break;
case CKA_TRUST_CODE_SIGNING:
- val = has_usage(tdata, X509_USAGE_CODE_SIGNING);
+ val = has_enhanced_usage(tdata, X509_USAGE_CODE_SIGNING);
break;
case CKA_TRUST_EMAIL_PROTECTION:
- val = has_usage(tdata, X509_USAGE_EMAIL);
+ val = has_enhanced_usage(tdata, X509_USAGE_EMAIL);
break;
case CKA_TRUST_IPSEC_END_SYSTEM:
- val = has_usage(tdata, X509_USAGE_IPSEC_ENDPOINT);
+ val = has_enhanced_usage(tdata, X509_USAGE_IPSEC_ENDPOINT);
break;
case CKA_TRUST_IPSEC_TUNNEL:
- val = has_usage(tdata, X509_USAGE_IPSEC_TUNNEL);
+ val = has_enhanced_usage(tdata, X509_USAGE_IPSEC_TUNNEL);
break;
case CKA_TRUST_IPSEC_USER:
- val = has_usage(tdata, X509_USAGE_IPSEC_USER);
+ val = has_enhanced_usage(tdata, X509_USAGE_IPSEC_USER);
break;
case CKA_TRUST_TIME_STAMPING:
- val = has_usage(tdata, X509_USAGE_TIME_STAMPING);
+ val = has_enhanced_usage(tdata, X509_USAGE_TIME_STAMPING);
break;
default:
@@ -233,8 +270,8 @@ trust_release(void* data)
ASSERT(tdata->cert);
CertFreeCertificateContext(tdata->cert);
- if(tdata->usage)
- free(tdata->usage);
+ if(tdata->enhanced_usage)
+ free(tdata->enhanced_usage);
free(tdata);
}
@@ -251,27 +288,27 @@ static CK_RV
parse_usage(TrustObjectData* tdata, DWORD flags)
{
DWORD size, err;
- CERT_ENHKEY_USAGE* usage;
+ CERT_ENHKEY_USAGE* eusage;
- ASSERT(!tdata->usage);
+ ASSERT(!tdata->enhanced_usage);
- /* Get the size of the usage */
+ /* Get the size of the enhanced_usage */
if(!CertGetEnhancedKeyUsage(tdata->cert, flags, NULL, &size))
{
err = GetLastError();
- /* No usage data is not an error */
+ /* No enhanced_usage data is not an error */
if(err == CRYPT_E_NOT_FOUND)
return CKR_OK;
return ckcapi_winerr_to_ckr(err);
}
- usage = (CERT_ENHKEY_USAGE*)calloc(1, size);
- if(!usage)
+ eusage = (CERT_ENHKEY_USAGE*)calloc(1, size);
+ if(!eusage)
return CKR_HOST_MEMORY;
- /* Now get the actual usage property */
- if(!CertGetEnhancedKeyUsage(tdata->cert, flags, usage, &size))
+ /* Now get the actual enhanced usage property */
+ if(!CertGetEnhancedKeyUsage(tdata->cert, flags, eusage, &size))
{
err = GetLastError();
if(err == CRYPT_E_NOT_FOUND)
@@ -279,7 +316,58 @@ parse_usage(TrustObjectData* tdata, DWORD flags)
return ckcapi_winerr_to_ckr(err);
}
- tdata->usage = usage;
+ tdata->enhanced_usage = eusage;
+ return CKR_OK;
+}
+
+static CK_RV
+parse_restrictions(TrustObjectData* tdata)
+{
+ CRYPT_BIT_BLOB* rst;
+ CERT_EXTENSION* ext;
+ DWORD size;
+
+ ASSERT(tdata);
+ ASSERT(tdata->cert);
+
+ tdata->has_usage = CK_FALSE;
+ tdata->usage = 0x00;
+
+ ext = CertFindExtension(szOID_KEY_USAGE,
+ tdata->cert->pCertInfo->cExtension,
+ tdata->cert->pCertInfo->rgExtension);
+
+ /* No key usage, don't care */
+ if(!ext)
+ return CKR_OK;
+
+ /* Find the size of the decoded structure */
+ if(!CryptDecodeObject(CKCAPI_ENCODINGS, X509_KEY_USAGE,
+ ext->Value.pbData, ext->Value.cbData, 0, NULL, &size))
+ return ckcapi_winerr_to_ckr(GetLastError());
+
+ /* Allocate enough memory */
+ rst = (CRYPT_BIT_BLOB*)calloc(size, 1);
+ if(!rst)
+ return CKR_HOST_MEMORY;
+
+ /* And get the decoded structure */
+ if(CryptDecodeObject(CKCAPI_ENCODINGS, X509_KEY_USAGE,
+ ext->Value.pbData, ext->Value.cbData, 0, rst, &size))
+ {
+ if(rst->cbData != 1 &&
+ rst->cUnusedBits != 0)
+ {
+ DBG(("key usage are of invalid size"));
+ }
+ else
+ {
+ /* A valid byte of key restricted usage flags. Yes all that for one byte */
+ tdata->usage = *((BYTE*)(rst->pbData));
+ tdata->has_usage = TRUE;
+ }
+ }
+
return CKR_OK;
}
@@ -306,9 +394,17 @@ trust_load_data(CkCapiSession* sess, CkCapiObject* obj, CkCapiObjectData** objda
tdata->cert = ckcapi_cert_object_data_get_certificate (certdata);
ASSERT(tdata->cert);
- /* Dig up the usage data property, and then try the extension */
+ /* Dig up the restrictions data extension */
+ ret = parse_restrictions(tdata);
+ if(ret != CKR_OK)
+ {
+ free(tdata);
+ return ret;
+ }
+
+ /* Dig up the enhanced usage data property, and then try the extension */
ret = parse_usage(tdata, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG);
- if(ret == CKR_OK && !tdata->usage)
+ if(ret == CKR_OK && !tdata->enhanced_usage)
ret = parse_usage(tdata, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG);
if(ret != CKR_OK)
diff --git a/ckcapi.h b/ckcapi.h
index 4ccd1cb..b2f1893 100644
--- a/ckcapi.h
+++ b/ckcapi.h
@@ -43,6 +43,8 @@
#include <windows.h>
#include <wincrypt.h>
+#define CKCAPI_ENCODINGS (X509_ASN_ENCODING | PKCS_7_ASN_ENCODING)
+
#define CRYPTOKI_EXPORTS
#include "pkcs11/pkcs11.h"