[gnome-keyring: 2/6] Add support for parsing and storing time attributes.



commit 10ecb163793305ceed6a3cee48f2e593daabdd20
Author: Stef Walter <stef memberwebs com>
Date:   Sat Jul 18 18:30:53 2009 +0000

    Add support for parsing and storing time attributes.
    
    These time attributes follow the PKCS#11 clock format.
    That is: YYYYmmddHHMMSS00 16 chars

 pkcs11/gck/gck-attributes.c             |   97 ++++++++++++++++++++++++
 pkcs11/gck/gck-attributes.h             |    8 ++
 pkcs11/gck/tests/Makefile.am            |    1 +
 pkcs11/gck/tests/unit-test-attributes.c |  125 +++++++++++++++++++++++++++++++
 4 files changed, 231 insertions(+), 0 deletions(-)
---
diff --git a/pkcs11/gck/gck-attributes.c b/pkcs11/gck/gck-attributes.c
index ad1b9de..f5c0102 100644
--- a/pkcs11/gck/gck-attributes.c
+++ b/pkcs11/gck/gck-attributes.c
@@ -28,6 +28,71 @@
 #include <stdio.h>
 #include <string.h>
 
+#ifndef HAVE_TIMEGM
+static time_t
+timegm (struct tm *t)
+{
+	time_t tl, tb;
+	struct tm *tg;
+
+	tl = mktime (t);
+	if (tl == -1)
+	{
+		t->tm_hour--;
+		tl = mktime (t);
+		if (tl == -1)
+			return -1; /* can't deal with output from strptime */
+		tl += 3600;
+	}
+	tg = gmtime (&tl);
+	tg->tm_isdst = 0;
+	tb = mktime (tg);
+	if (tb == -1)
+	{
+		tg->tm_hour--;
+		tb = mktime (tg);
+		if (tb == -1)
+			return -1; /* can't deal with output from gmtime */
+		tb += 3600;
+	}
+	return (tl - (tb - tl));
+}
+#endif // NOT_HAVE_TIMEGM
+
+CK_RV
+gck_attribute_get_time (CK_ATTRIBUTE_PTR attr, glong *when)
+{
+	struct tm tm;
+	gchar buf[15];
+	time_t time;
+
+	g_return_val_if_fail (attr, CKR_GENERAL_ERROR);
+	g_return_val_if_fail (when, CKR_GENERAL_ERROR);
+
+	if (attr->ulValueLen == 0) {
+		*when = (glong)-1;
+		return CKR_OK;
+	}
+
+	if (!attr->pValue || attr->ulValueLen != 16)
+		return CKR_ATTRIBUTE_VALUE_INVALID;
+
+	memset (&tm, 0, sizeof (tm));
+	memcpy (buf, attr->pValue, 14);
+	buf[14] = 0;
+
+	if (!strptime(buf, "%Y%m%d%H%M%S", &tm))
+		return CKR_ATTRIBUTE_VALUE_INVALID;
+
+	/* Convert to seconds since epoch */
+	time = timegm (&tm);
+	if (time < 0)
+		return CKR_ATTRIBUTE_VALUE_INVALID;
+
+	*when = time;
+	return CKR_OK;
+}
+
 CK_RV
 gck_attribute_set_bool (CK_ATTRIBUTE_PTR attr, CK_BBOOL value)
 {
@@ -80,6 +145,32 @@ gck_attribute_set_date (CK_ATTRIBUTE_PTR attr, time_t time)
 		
 	return gck_attribute_set_data (attr, &date, sizeof (date));
 }
+
+CK_RV
+gck_attribute_set_time (CK_ATTRIBUTE_PTR attr, glong when)
+{
+	struct tm tm;
+	gchar buf[20];
+
+	/* 'Empty' time as defined in PKCS#11 */
+	if (when == (glong)-1)
+		return gck_attribute_set_data (attr, NULL, 0);
+
+	if (!attr->pValue) {
+		attr->ulValueLen = 16;
+		return CKR_OK;
+	}
+
+	time_t time = when;
+	if (!gmtime_r (&time, &tm))
+		g_return_val_if_reached (CKR_GENERAL_ERROR);
+
+	if (!strftime(buf, sizeof (buf), "%Y%m%d%H%M%S00", &tm))
+		g_return_val_if_reached (CKR_GENERAL_ERROR);
+
+	return gck_attribute_set_data (attr, buf, 16);
+}
+
 CK_RV
 gck_attribute_set_data (CK_ATTRIBUTE_PTR attr, gconstpointer value, gsize n_value)
 {
@@ -173,6 +264,12 @@ gck_attribute_consumed (CK_ATTRIBUTE_PTR attr)
 }
 
 void
+gck_attribute_consume (CK_ATTRIBUTE_PTR attr)
+{
+	attr->type = (CK_ULONG)-1;
+}
+
+void
 gck_attributes_consume (CK_ATTRIBUTE_PTR attrs, CK_ULONG n_attrs, ...)
 {
 	CK_ATTRIBUTE_TYPE type;
diff --git a/pkcs11/gck/gck-attributes.h b/pkcs11/gck/gck-attributes.h
index 81b84a7..cfbb77d 100644
--- a/pkcs11/gck/gck-attributes.h
+++ b/pkcs11/gck/gck-attributes.h
@@ -28,6 +28,9 @@
 
 #include "pkcs11/pkcs11.h"
 
+CK_RV                 gck_attribute_get_time                           (CK_ATTRIBUTE_PTR attr,
+                                                                        glong *when);
+
 CK_RV                 gck_attribute_set_bool                           (CK_ATTRIBUTE_PTR attr,
                                                                         CK_BBOOL value);
 
@@ -40,6 +43,9 @@ CK_RV                 gck_attribute_set_string                         (CK_ATTRI
 CK_RV                 gck_attribute_set_date                           (CK_ATTRIBUTE_PTR attr,
                                                                         time_t when);
 
+CK_RV                 gck_attribute_set_time                           (CK_ATTRIBUTE_PTR attr,
+                                                                        glong when);
+
 CK_RV                 gck_attribute_set_data                           (CK_ATTRIBUTE_PTR attr,
                                                                         gconstpointer value,
                                                                         gsize n_value);
@@ -57,6 +63,8 @@ guint                 gck_attribute_hash                               (gconstpo
 gboolean              gck_attribute_equal                              (gconstpointer a,
                                                                         gconstpointer b);
 
+void                  gck_attribute_consume                            (CK_ATTRIBUTE_PTR attr);
+
 gboolean              gck_attribute_consumed                           (CK_ATTRIBUTE_PTR attr);
 
 
diff --git a/pkcs11/gck/tests/Makefile.am b/pkcs11/gck/tests/Makefile.am
index 7596afa..e1b72e8 100644
--- a/pkcs11/gck/tests/Makefile.am
+++ b/pkcs11/gck/tests/Makefile.am
@@ -7,6 +7,7 @@ asn1-def-test.h: test.asn
 	
 # Test files should be listed in order they need to run
 UNIT_AUTO = \
+	unit-test-attributes.c \
 	unit-test-crypto.c \
 	unit-test-data-asn1.c \
 	unit-test-data-der.c \
diff --git a/pkcs11/gck/tests/unit-test-attributes.c b/pkcs11/gck/tests/unit-test-attributes.c
new file mode 100644
index 0000000..d1add75
--- /dev/null
+++ b/pkcs11/gck/tests/unit-test-attributes.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* unit-test-attributes.c: Test attributes functionality
+
+   Copyright (C) 2009 Stefan Walter
+
+   The Gnome Keyring Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Keyring Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Stef Walter <stef memberwebs com>
+*/
+
+#include "run-auto-test.h"
+
+#include "gck/gck-attributes.h"
+
+DEFINE_TEST(attribute_consume)
+{
+	CK_ATTRIBUTE attr;
+	attr.type = CKA_LABEL;
+	
+	gck_attribute_consume (&attr);
+	g_assert (attr.type == (gulong)-1);
+}
+
+DEFINE_TEST(attribute_set_time)
+{
+	CK_ATTRIBUTE attr;
+	gchar buf[30];
+	CK_RV rv;
+	
+	attr.ulValueLen = 30;
+	attr.pValue = buf;
+	rv = gck_attribute_set_time (&attr, 1247930171);
+	g_assert (rv == CKR_OK);
+	g_assert (attr.ulValueLen == 16);
+	g_assert (memcmp (attr.pValue, "2009071815161100", 16) == 0);
+}
+
+DEFINE_TEST(attribute_set_time_empty)
+{
+	CK_ATTRIBUTE attr;
+	gchar buf[30];
+	CK_RV rv;
+	
+	attr.ulValueLen = 30;
+	attr.pValue = buf;
+	rv = gck_attribute_set_time (&attr, -1);
+	g_assert (rv == CKR_OK);
+	g_assert (attr.ulValueLen == 0);
+}
+
+DEFINE_TEST(attribute_set_time_length)
+{
+	CK_ATTRIBUTE attr;
+	CK_RV rv;
+	
+	attr.pValue = NULL;
+	attr.ulValueLen = 0;
+	rv = gck_attribute_set_time (&attr, 1247930171);
+	g_assert (rv == CKR_OK);
+	g_assert (attr.ulValueLen == 16);
+	g_assert (attr.pValue == NULL);
+}
+
+DEFINE_TEST(attribute_get_time)
+{
+	CK_ATTRIBUTE attr;
+	glong when;
+	CK_RV rv;
+	
+	attr.ulValueLen = 16;
+	attr.pValue = "2009071815161100";
+	rv = gck_attribute_get_time (&attr, &when);
+	g_assert (rv == CKR_OK);
+	g_assert (when == 1247930171);
+}
+
+DEFINE_TEST(attribute_get_time_empty)
+{
+	CK_ATTRIBUTE attr;
+	glong when;
+	CK_RV rv;
+	
+	attr.ulValueLen = 0;
+	attr.pValue = "";
+	rv = gck_attribute_get_time (&attr, &when);
+	g_assert (rv == CKR_OK);
+	g_assert (when == -1);
+}
+
+DEFINE_TEST(attribute_get_time_invalid)
+{
+	CK_ATTRIBUTE attr;
+	glong when;
+	CK_RV rv;
+	
+	attr.ulValueLen = 16;
+	attr.pValue = "aaaaaaaaaaaaaaaa";
+	rv = gck_attribute_get_time (&attr, &when);
+	g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
+}
+
+DEFINE_TEST(attribute_get_time_invalid_length)
+{
+	CK_ATTRIBUTE attr;
+	glong when;
+	CK_RV rv;
+	
+	attr.ulValueLen = 8;
+	attr.pValue = "2009071815161100";
+	rv = gck_attribute_get_time (&attr, &when);
+	g_assert (rv == CKR_ATTRIBUTE_VALUE_INVALID);
+}



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]