summaryrefslogtreecommitdiffstats
path: root/pki/base/tps/src/main
diff options
context:
space:
mode:
authorPKI Team <PKI Team@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2008-03-18 22:36:57 +0000
committerPKI Team <PKI Team@c9f7a03b-bd48-0410-a16d-cbbf54688b0b>2008-03-18 22:36:57 +0000
commitd0f2e4efbd3eb0f1d7f5a28e7f97c1fb4ec027bb (patch)
tree7e7473fae8af5ad7e6cda7eabbef787093fc59a7 /pki/base/tps/src/main
parent273f8d85df5c31293a908185622b378c8f3cf7e8 (diff)
downloadpki-d0f2e4efbd3eb0f1d7f5a28e7f97c1fb4ec027bb.tar.gz
pki-d0f2e4efbd3eb0f1d7f5a28e7f97c1fb4ec027bb.tar.xz
pki-d0f2e4efbd3eb0f1d7f5a28e7f97c1fb4ec027bb.zip
Initial open source version based upon proprietary Red Hat Certificate System (RHCS) 7.3.
git-svn-id: svn+ssh://svn.fedorahosted.org/svn/pki/trunk@2 c9f7a03b-bd48-0410-a16d-cbbf54688b0b
Diffstat (limited to 'pki/base/tps/src/main')
-rw-r--r--pki/base/tps/src/main/AttributeSpec.cpp115
-rw-r--r--pki/base/tps/src/main/AuthParams.cpp72
-rw-r--r--pki/base/tps/src/main/Authentication.cpp105
-rw-r--r--pki/base/tps/src/main/AuthenticationEntry.cpp91
-rw-r--r--pki/base/tps/src/main/Buffer.cpp243
-rw-r--r--pki/base/tps/src/main/ConfigStore.cpp553
-rw-r--r--pki/base/tps/src/main/Login.cpp72
-rw-r--r--pki/base/tps/src/main/Memory.cpp268
-rw-r--r--pki/base/tps/src/main/NameValueSet.cpp322
-rw-r--r--pki/base/tps/src/main/ObjectSpec.cpp500
-rw-r--r--pki/base/tps/src/main/PKCS11Obj.cpp454
-rw-r--r--pki/base/tps/src/main/RA_Context.cpp56
-rw-r--r--pki/base/tps/src/main/RA_Msg.cpp45
-rw-r--r--pki/base/tps/src/main/RA_Session.cpp75
-rw-r--r--pki/base/tps/src/main/RA_pblock.cpp176
-rw-r--r--pki/base/tps/src/main/SecureId.cpp71
-rw-r--r--pki/base/tps/src/main/Util.cpp1139
17 files changed, 4357 insertions, 0 deletions
diff --git a/pki/base/tps/src/main/AttributeSpec.cpp b/pki/base/tps/src/main/AttributeSpec.cpp
new file mode 100644
index 000000000..23c2cd978
--- /dev/null
+++ b/pki/base/tps/src/main/AttributeSpec.cpp
@@ -0,0 +1,115 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/AttributeSpec.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+AttributeSpec::AttributeSpec ()
+{
+}
+
+AttributeSpec::~AttributeSpec ()
+{
+}
+
+AttributeSpec *AttributeSpec::Parse(Buffer *b, int offset)
+{
+ AttributeSpec *o = new AttributeSpec();
+ unsigned long id = (((unsigned char *)*b)[offset+0] << 24) +
+ (((unsigned char *)*b)[offset+1] << 16) +
+ (((unsigned char *)*b)[offset+2] << 8) +
+ (((unsigned char *)*b)[offset+3]);
+ o->SetAttributeID(id);
+ // The following line generates the following known benign warning
+ // message on Windows platforms:
+ //
+ // AttributeSpec.cpp(40) : warning C4244: 'argument' : conversion
+ // from 'unsigned long' to 'unsigned char', possible loss of data
+ //
+ o->SetType((unsigned long)(((unsigned char *)*b)[offset+4]));
+ // DatatypeString contains two bytes for AttributeLen of AttributeData
+ Buffer data;
+ if (o->GetType() == (BYTE) 0)
+ data = b->substr(offset+5+2, b->size() - 5-2);
+ else
+ data = b->substr(offset+5, b->size() - 5);
+
+ o->SetData(data);
+ return o;
+}
+
+void AttributeSpec::SetAttributeID(unsigned long v)
+{
+ m_id = v;
+}
+
+unsigned long AttributeSpec::GetAttributeID()
+{
+ return m_id;
+}
+
+void AttributeSpec::SetType(BYTE v)
+{
+ m_type = v;
+}
+
+BYTE AttributeSpec::GetType()
+{
+ return m_type;
+}
+
+// sets AttributeData (for string type, contains AttributeLen+AttributeValue)
+void AttributeSpec::SetData(Buffer data)
+{
+ m_data = data;
+}
+
+// gets AttributeData
+Buffer AttributeSpec::GetValue()
+{
+ return m_data;
+}
+
+// gets AttributeSpec
+Buffer AttributeSpec::GetData()
+{
+ Buffer data = Buffer();
+ data += Buffer(1, (BYTE)(m_id >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_id >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_id >> 8) & 0xff);
+ data += Buffer(1, (BYTE)m_id & 0xff);
+ data += Buffer(1, m_type);
+ if (m_type == 0) { /* String */
+ data += Buffer(1, (m_data.size() >> 8) & 0xff);
+ data += Buffer(1, m_data.size() & 0xff);
+ }
+ data += m_data;
+ return data;
+}
+
diff --git a/pki/base/tps/src/main/AuthParams.cpp b/pki/base/tps/src/main/AuthParams.cpp
new file mode 100644
index 000000000..3a124252e
--- /dev/null
+++ b/pki/base/tps/src/main/AuthParams.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC AuthParams::AuthParams () {
+}
+
+/**
+ * Destructs processor.
+ */
+AuthParams::~AuthParams () {
+}
+
+TPS_PUBLIC void AuthParams::SetUID(char *uid) {
+ Add("UID", uid);
+}
+
+TPS_PUBLIC char *AuthParams::GetUID() {
+ return GetValue("UID");
+}
+
+TPS_PUBLIC void AuthParams::SetPassword(char *pwd) {
+ Add("PASSWORD", pwd);
+}
+
+TPS_PUBLIC char *AuthParams::GetPassword() {
+ return GetValue("PASSWORD");
+}
+
+void AuthParams::SetSecuridValue(char *securidValue) {
+ Add("SECURID_VALUE", securidValue);
+}
+
+TPS_PUBLIC char *AuthParams::GetSecuridValue() {
+ return GetValue("SECURID_VALUE");
+}
+
+void AuthParams::SetSecuridPin(char *securidPin) {
+ Add("SECURID_PIN", securidPin);
+}
+
+TPS_PUBLIC char *AuthParams::GetSecuridPin() {
+ return GetValue("SECURID_PIN");
+}
+
diff --git a/pki/base/tps/src/main/Authentication.cpp b/pki/base/tps/src/main/Authentication.cpp
new file mode 100644
index 000000000..34ab76f0a
--- /dev/null
+++ b/pki/base/tps/src/main/Authentication.cpp
@@ -0,0 +1,105 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include "main/RA_Session.h"
+#include "main/Login.h"
+#include "main/SecureId.h"
+#include "main/Util.h"
+#include "main/Memory.h"
+#include "authentication/Authentication.h"
+#include "authentication/AuthParams.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a base authentication
+ */
+TPS_PUBLIC Authentication::Authentication ()
+{
+}
+
+/**
+ * Destructs processor.
+ */
+TPS_PUBLIC Authentication::~Authentication ()
+{
+}
+
+void Authentication::Initialize(int index)
+{
+}
+
+int Authentication::Authenticate(AuthParams *params)
+{
+ return -1;
+}
+
+int Authentication::GetNumOfRetries() {
+ return m_retries;
+}
+
+const char *Authentication::GetTitle(char *locale)
+{
+ return NULL;
+}
+
+const char *Authentication::GetDescription(char *locale)
+{
+ return NULL;
+}
+
+int Authentication::GetNumOfParamNames()
+{
+ return 0;
+}
+
+char *Authentication::GetParamID(int index)
+{
+ return NULL;
+}
+
+const char *Authentication::GetParamName(int index, char *locale)
+{
+ return NULL;
+}
+
+char *Authentication::GetParamType(int index)
+{
+ return NULL;
+}
+
+const char *Authentication::GetParamDescription(int index, char *locale)
+{
+ return NULL;
+}
+
+char *Authentication::GetParamOption(int index)
+{
+ return NULL;
+}
+
diff --git a/pki/base/tps/src/main/AuthenticationEntry.cpp b/pki/base/tps/src/main/AuthenticationEntry.cpp
new file mode 100644
index 000000000..eb7f75419
--- /dev/null
+++ b/pki/base/tps/src/main/AuthenticationEntry.cpp
@@ -0,0 +1,91 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "plstr.h"
+#include "main/AuthenticationEntry.h"
+
+/**
+ * Constructs a base authentication
+ */
+AuthenticationEntry::AuthenticationEntry ()
+{
+ m_lib = NULL;
+ m_Id = NULL;
+ m_type = NULL;
+ m_authentication = NULL;
+}
+
+/**
+ * Destructs processor.
+ */
+AuthenticationEntry::~AuthenticationEntry ()
+{
+ if (m_lib != NULL) {
+ PR_UnloadLibrary(m_lib);
+ m_lib = NULL;
+ }
+
+ if( m_Id != NULL ) {
+ PL_strfree( m_Id );
+ m_Id = NULL;
+ }
+
+ if( m_type != NULL ) {
+ PL_strfree( m_type );
+ m_type = NULL;
+ }
+
+ m_authentication = NULL;
+}
+
+void AuthenticationEntry::SetLibrary(PRLibrary* lib) {
+ m_lib = lib;
+}
+
+PRLibrary *AuthenticationEntry::GetLibrary() {
+ return m_lib;
+}
+
+void AuthenticationEntry::SetId(const char *id) {
+ m_Id = PL_strdup(id);
+}
+
+char *AuthenticationEntry::GetId() {
+ return m_Id;
+}
+
+void AuthenticationEntry::SetAuthentication(Authentication *auth) {
+ m_authentication = auth;
+}
+
+Authentication *AuthenticationEntry::GetAuthentication() {
+ return m_authentication;
+}
+
+void AuthenticationEntry::SetType(const char *type) {
+ m_type = PL_strdup(type);
+}
+
+char *AuthenticationEntry::GetType() {
+ return m_type;
+}
diff --git a/pki/base/tps/src/main/Buffer.cpp b/pki/base/tps/src/main/Buffer.cpp
new file mode 100644
index 000000000..2a547feea
--- /dev/null
+++ b/pki/base/tps/src/main/Buffer.cpp
@@ -0,0 +1,243 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+
+#include "main/Buffer.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Buffer::Buffer(const BYTE *buf_, unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[len];
+ memcpy(buf, buf_, len);
+}
+
+TPS_PUBLIC Buffer::Buffer(const Buffer& cpy)
+{
+ buf = 0;
+ *this = cpy;
+}
+
+TPS_PUBLIC Buffer::Buffer(unsigned int len_) : len(len_), res(len_)
+{
+ buf = new BYTE[res];
+ memset(buf, 0, len_);
+}
+
+TPS_PUBLIC Buffer::Buffer(unsigned int len_, BYTE b) : len(len_), res(len_)
+{
+ if (len_ == 0) {
+ buf = NULL;
+ } else {
+ buf = new BYTE[res];
+ memset(buf, b, len);
+ }
+}
+
+TPS_PUBLIC Buffer::~Buffer()
+{
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+}
+
+TPS_PUBLIC bool
+Buffer::operator==(const Buffer& cmp) const
+{
+ if( len != cmp.len ) return false;
+ for( unsigned int i=0; i < len; ++i ) {
+ if( buf[i] != cmp.buf[i] ) {
+ return false;
+ }
+ }
+ return true;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator=(const Buffer& cpy)
+{
+ if( this == &cpy ) return *this;
+ len = cpy.len;
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ if (cpy.len == 0) {
+ buf = NULL;
+ } else {
+ buf = new BYTE[len];
+ memcpy(buf, cpy.buf, len);
+ }
+ res = len;
+
+ return *this;
+}
+
+TPS_PUBLIC void
+Buffer::zeroize()
+{
+ if( len > 0 ) {
+ memset( buf, 0, len );
+ }
+}
+
+TPS_PUBLIC Buffer
+Buffer::operator+(const Buffer& addend) const
+{
+ Buffer result(len + addend.len);
+ memcpy(result.buf, buf, len);
+ memcpy(result.buf+len, addend.buf, addend.len);
+ return result;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator+=(const Buffer& addend)
+{
+ unsigned int oldLen = len;
+ resize(len + addend.len);
+ memcpy(buf+oldLen, addend.buf, addend.len);
+ return *this;
+}
+
+TPS_PUBLIC Buffer&
+Buffer::operator+=(BYTE b)
+{
+ resize(len+1);
+ buf[len-1] = b;
+ return *this;
+}
+
+TPS_PUBLIC void
+Buffer::reserve(unsigned int n)
+{
+ if( n > res ) {
+ BYTE *newBuf = new BYTE[n];
+ memcpy(newBuf, buf, len);
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ buf = newBuf;
+ res = n;
+ }
+}
+
+TPS_PUBLIC void
+Buffer::resize(unsigned int newLen)
+{
+ if( newLen == len ) {
+ return;
+ } else if( newLen < len ) {
+ len = newLen;
+ } else if( newLen <= res ) {
+ assert( newLen > len );
+ memset(buf+len, 0, newLen-len);
+ len = newLen;
+ } else {
+ assert( newLen > len && newLen > res );
+ BYTE *newBuf = new BYTE[newLen];
+ memcpy(newBuf, buf, len);
+ memset(newBuf+len, 0, newLen-len);
+ if( buf != NULL ) {
+ delete [] buf;
+ buf = NULL;
+ }
+ buf = newBuf;
+ len = newLen;
+ res = newLen;
+ }
+}
+
+TPS_PUBLIC Buffer
+Buffer::substr(unsigned int i, unsigned int n) const
+{
+ assert( i < len && (i+n) <= len );
+ return Buffer( buf+i, n );
+}
+
+TPS_PUBLIC void
+Buffer::replace(unsigned int i, const BYTE* cpy, unsigned int n)
+{
+ if (len > i+n) {
+ resize( len);
+ }else {
+ resize( i+n );
+ }
+ memcpy(buf+i, cpy, n);
+}
+
+TPS_PUBLIC void
+Buffer::dump() const
+{
+ unsigned int i;
+
+ for( i=0; i < len; ++i ) {
+ printf("%02x ", buf[i]);
+ if( i % 16 == 15 ) printf("\n");
+ }
+ printf("\n");
+}
+
+/*
+ * if caller knows it's a string, pad with ending 0 and return.
+ * note:
+ * It is the caller's responsibility to make sure it's a string.
+ * Memory needs to be released by the caller.
+ */
+TPS_PUBLIC char *
+Buffer::string()
+{
+ unsigned int i;
+ char *s = (char *) PR_Malloc(len+1);
+ for (i = 0; i < len; i++) {
+ s[i] = buf[i];
+ }
+ s[i] = '\0';
+ return s;
+}
+
+TPS_PUBLIC char *
+Buffer::toHex()
+{
+ unsigned int i;
+
+ char *hx = (char *)PR_Malloc(1024);
+ if (hx == NULL)
+ return NULL;
+ for( i=0; i < len; ++i ) {
+ PR_snprintf(hx+(i*2),1024-(i*2),"%02x", (unsigned char)buf[i]);
+ }
+
+ return hx;
+}
+
+static const char hextbl[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+};
diff --git a/pki/base/tps/src/main/ConfigStore.cpp b/pki/base/tps/src/main/ConfigStore.cpp
new file mode 100644
index 000000000..26e74852f
--- /dev/null
+++ b/pki/base/tps/src/main/ConfigStore.cpp
@@ -0,0 +1,553 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "main/ConfigStore.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef XP_WIN32
+#define TOKENDB_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TOKENDB_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PR_CALLBACK void*
+_AllocTable(void* pool, PRSize size)
+{
+ return PR_MALLOC(size);
+}
+
+static PR_CALLBACK void
+_FreeTable(void* pool, void* item)
+{
+ PR_DELETE(item);
+}
+
+static PR_CALLBACK PLHashEntry*
+_AllocEntry(void* pool, const void* key)
+{
+ return PR_NEW(PLHashEntry);
+}
+
+static PR_CALLBACK void
+_FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
+{
+ if( he == NULL ) {
+ return;
+ }
+
+ if (flag == HT_FREE_VALUE) {
+ if( he->value != NULL ) {
+ PL_strfree( (char*) he->value );
+ he->value = NULL;
+ }
+ } else if (flag == HT_FREE_ENTRY) {
+ if( he->key != NULL ) {
+ PL_strfree( (char*) he->key );
+ he->key = NULL;
+ }
+ if( he->value != NULL ) {
+ PL_strfree( (char*) he->value );
+ he->value = NULL;
+ }
+ PR_DELETE(he);
+ }
+}
+
+static PLHashAllocOps _AllocOps = {
+ _AllocTable,
+ _FreeTable,
+ _AllocEntry,
+ _FreeEntry
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+///// ConfigStoreRoot
+
+ConfigStoreRoot::ConfigStoreRoot()
+{
+ m_set = PL_NewHashTable(3, PL_HashString,
+ PL_CompareStrings, PL_CompareValues,
+ &_AllocOps, NULL);
+
+ m_set_refcount = 0;
+}
+
+// If the ConfigStoreRoot goes out of scope, we can't destroy
+// the Hashtable because others maybe depending on the values
+// inside.
+ConfigStoreRoot::~ConfigStoreRoot ()
+{
+ if( m_set != NULL ) {
+ if (m_set_refcount==0) {
+ PL_HashTableDestroy( m_set );
+ m_set = NULL;
+ }
+ }
+}
+
+void ConfigStoreRoot::addref()
+{
+ m_set_refcount++;
+}
+
+void ConfigStoreRoot::release()
+{
+ m_set_refcount--;
+}
+
+PLHashTable *ConfigStoreRoot::getSet()
+{
+ return m_set;
+}
+
+
+// ConfigureStore
+
+ConfigStore::ConfigStore(ConfigStoreRoot* root, const char *subStoreName)
+{
+ m_substore_name = PL_strdup(subStoreName);
+ m_root = root;
+ root->addref();
+}
+
+ConfigStore::~ConfigStore ()
+{
+ if (m_substore_name != NULL) {
+ PR_Free(m_substore_name);
+ }
+ m_root->release();
+}
+
+
+
+/*
+ConfigStore::ConfigStore(const ConfigStore &X)
+{
+ m_substore_name = X.m_substore_name;
+ m_root = X.m_root;
+ m_root.addref();
+}
+
+*/
+
+
+
+ConfigStore ConfigStore::GetSubStore(const char *substore)
+{
+ char *newname=NULL;
+ const char *name = m_substore_name;
+ if (strlen(name)==0) { // this is the root
+ newname = PL_strdup(substore);
+ } else {
+ newname = PR_smprintf("%s.%s",name,substore);
+ }
+ return ConfigStore(m_root,newname);
+}
+
+
+/**
+ * Reads configuration file and puts name value
+ * pair into the global hashtable.
+ */
+static int ReadLine(PRFileDesc *f, char *buf, int buf_len, int *removed_return)
+{
+ char *cur = buf;
+ int sum = 0;
+ PRInt32 rc;
+
+ *removed_return = 0;
+ while (1) {
+ rc = PR_Read(f, cur, 1);
+ if (rc == -1 || rc == 0)
+ break;
+ if (*cur == '\r') {
+ continue;
+ }
+ if (*cur == '\n') {
+ *cur = '\0';
+ *removed_return = 1;
+ break;
+ }
+ sum++;
+ cur++;
+ }
+ return sum;
+}
+
+#define MAX_CFG_LINE_LEN 4096
+
+ConfigStore *ConfigStore::CreateFromConfigFile(const char *cfg_path)
+{
+ PRFileDesc *f = NULL;
+ int removed_return;
+ char line[MAX_CFG_LINE_LEN];
+ ConfigStoreRoot *root = NULL;
+ ConfigStore *cfg = NULL;
+
+ f = PR_Open(cfg_path, PR_RDWR, 00400|00200);
+ if (f == NULL)
+ goto loser;
+
+ root = new ConfigStoreRoot();
+ cfg = new ConfigStore(root,"");
+
+ while (1) {
+ int n = ReadLine(f, line, MAX_CFG_LINE_LEN, &removed_return);
+ if (n > 0) {
+ if (line[0] == '#') // handle comment line
+ continue;
+ int c = 0;
+ while ((c < n) && (line[c] != '=')) {
+ c++;
+ }
+ if (c < n) {
+ line[c] = '\0';
+ } else {
+ continue; /* no '=', skip this line */
+ }
+ cfg->Add(line, &line[c+1]);
+ } else if (n == 0 && removed_return == 1) {
+ continue; /* skip empty line */
+ } else {
+ break;
+ }
+ }
+ if( f != NULL ) {
+ PR_Close( f );
+ f = NULL;
+ }
+
+loser:
+ return cfg;
+}
+
+/**
+ * Parses string of format "n1=v1&n2=v2..."
+ * into a ConfigStore.
+ */
+ConfigStore *ConfigStore::Parse(const char *s, const char *separator)
+{
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+
+ if (s == NULL)
+ return NULL;
+ ConfigStoreRoot *root = new ConfigStoreRoot();
+ ConfigStore *set= new ConfigStore(root,"");
+
+ line = PL_strdup(s);
+ pair = PL_strtok_r(line, separator, &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ set->Add(&pair[0], &pair[i+1]);
+skip:
+ pair = PL_strtok_r(NULL, separator, &lasts);
+ }
+ if( line != NULL ) {
+ PL_strfree( line );
+ line = NULL;
+ }
+ return set;
+}
+
+typedef struct {
+ int index;
+ char *key;
+} Criteria;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PRIntn CountLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ criteria->index++;
+ return HT_ENUMERATE_NEXT;
+}
+
+static PRIntn Loop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ if (criteria != NULL && index == criteria->index) {
+ criteria->key = (char *)he->key;
+ return HT_ENUMERATE_STOP;
+ } else {
+ return HT_ENUMERATE_NEXT;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+int ConfigStore::Size()
+{
+ Criteria criteria;
+ criteria.index = 0;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_root->getSet(), &CountLoop, &criteria);
+ return criteria.index;
+}
+
+const char *ConfigStore::GetNameAt(int pos)
+{
+ Criteria criteria;
+ criteria.index = pos;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_root->getSet(), &Loop, &criteria);
+ return criteria.key;
+}
+
+/**
+ * Checks if a key is defined.
+ */
+int ConfigStore::IsNameDefined(const char *name)
+{
+ if (m_root->getSet()!= NULL) {
+ if (GetConfig(name) != NULL)
+ return 1;
+ }
+ return 0;
+}
+
+void ConfigStore::Add(const char *name, const char *value)
+{
+ if (IsNameDefined(name)) {
+ PL_HashTableRemove(m_root->getSet(), name);
+ PL_HashTableAdd(m_root->getSet(), PL_strdup(name), PL_strdup(value));
+ } else {
+ PL_HashTableAdd(m_root->getSet(), PL_strdup(name), PL_strdup(value));
+ }
+}
+
+const char *ConfigStore::GetConfig(const char *name)
+{
+ char buf[256];
+ if (m_root->getSet() ==NULL) {
+ return NULL;
+ }
+ if (PL_strlen(m_substore_name) == 0) {
+ PL_strncpy(buf,name,256);
+ } else {
+ PR_snprintf(buf,256,"%s.%s",m_substore_name,name);
+ }
+ return (char *)PL_HashTableLookupConst(m_root->getSet(), buf);
+}
+
+/**
+ * Retrieves configuration value as integer.
+ */
+int ConfigStore::GetConfigAsInt(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return 0;
+ return atoi(value);
+}
+
+/**
+ * Retrieves configuration value as integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int ConfigStore::GetConfigAsInt(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+ return atoi(value);
+}
+
+
+/**
+ * Retrieves configuration value as unsigned integer.
+ */
+unsigned int ConfigStore::GetConfigAsUnsignedInt(const char *name)
+{
+ char *value = NULL;
+ int i = 0;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL) {
+ return 0;
+ }
+
+ i = atoi(value);
+ if (i < 0) {
+ return 0;
+ }
+ return i;
+}
+
+/**
+ * Retrieves configuration value as unsigned integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC unsigned int ConfigStore::GetConfigAsUnsignedInt(const char *name, unsigned int def)
+{
+ char *value = NULL;
+ int i = 0;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL) {
+ return def;
+ }
+
+ i = atoi(value);
+ if (i < 0) {
+ return def;
+ }
+ return i;
+}
+
+
+/**
+ * Retrieves configuration value as boolean.
+ */
+bool ConfigStore::GetConfigAsBool(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return false;
+ if (PL_CompareStrings("true", value) != 0)
+ return true;
+ else
+ return false;
+}
+
+/**
+ * Retrieves configuration value as boolean. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC bool ConfigStore::GetConfigAsBool(const char *name, bool def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+
+ if (PL_CompareStrings("true", value) != 0)
+ return true;
+ else if (PL_CompareStrings("false", value) != 0)
+ return false;
+ else
+ return def;
+}
+
+/**
+ * Retrieves configuration value as string. If key is
+ * not defined, default value is returned.
+ */
+TOKENDB_PUBLIC const char *ConfigStore::GetConfigAsString(const char *name, const char *def)
+{
+ char *value = NULL;
+
+ value = (char *)GetConfig(name);
+ if (value == NULL)
+ return def;
+ return value;
+}
+
+/**
+ * Retrieves configuration value as string.
+ */
+TPS_PUBLIC const char *ConfigStore::GetConfigAsString(const char *name)
+{
+ return (char *)GetConfig(name);
+}
+
+
+/**
+ * Allow operator[] overloading for retrieval of config strings
+ */
+const char* ConfigStore::operator[](const char*name)
+{
+ return GetConfigAsString(name);
+}
+
+
+Buffer *ConfigStore::GetConfigAsBuffer(const char *key)
+{
+ return GetConfigAsBuffer(key, NULL);
+}
+
+Buffer *ConfigStore::GetConfigAsBuffer(const char *key, const char *def)
+{
+ const char *value = NULL;
+
+ value = (char *)GetConfig(key);
+ if (value == NULL) {
+ if (def == NULL) {
+ return NULL;
+ } else {
+ return Util::Str2Buf(def);
+ }
+ } else {
+ return Util::Str2Buf(value);
+ }
+}
+
diff --git a/pki/base/tps/src/main/Login.cpp b/pki/base/tps/src/main/Login.cpp
new file mode 100644
index 000000000..116ac7769
--- /dev/null
+++ b/pki/base/tps/src/main/Login.cpp
@@ -0,0 +1,72 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "main/Base.h"
+#include "main/Login.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a login object.
+ */
+Login::Login (char *uid, char *pwd)
+{
+ if (uid == NULL) {
+ m_uid = NULL;
+ } else {
+ m_uid = PL_strdup(uid);
+ }
+ if (pwd == NULL) {
+ m_pwd = NULL;
+ } else {
+ m_pwd = PL_strdup(pwd);
+ }
+}
+
+/**
+ * Destructs login object.
+ */
+Login::~Login ()
+{
+ if( m_uid != NULL ) {
+ PL_strfree( m_uid );
+ m_uid = NULL;
+ }
+ if( m_pwd != NULL ) {
+ PL_strfree( m_pwd );
+ m_pwd = NULL;
+ }
+}
+
+/**
+ * Retrieves user id.
+ */
+char *Login::GetUID()
+{
+ return m_uid;
+}
+
+/**
+ * Retrieves password.
+ */
+char *Login::GetPassword()
+{
+ return m_pwd;
+}
diff --git a/pki/base/tps/src/main/Memory.cpp b/pki/base/tps/src/main/Memory.cpp
new file mode 100644
index 000000000..1ee5027d0
--- /dev/null
+++ b/pki/base/tps/src/main/Memory.cpp
@@ -0,0 +1,268 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "plhash.h"
+#include "pk11func.h"
+
+#include "main/MemoryMgr.h"
+
+#ifdef MEM_PROFILING
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef struct _ref_block
+{
+ int id;
+ void *ptr;
+ const char *file;
+ const char *func;
+ const char *type;
+ int line;
+ int size;
+ int used;
+ PRTime time;
+} ref_block;
+
+#define MAX_BLOCKS 8096
+static ref_block m_rb[MAX_BLOCKS];
+
+static PRLock *m_free_block_lock = NULL;
+static PRLock *m_dump_lock = NULL;
+static PRLock *m_audit_lock = NULL;
+
+ref_block *get_free_block()
+{
+ int i;
+ PR_Lock(m_free_block_lock);
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (m_rb[i].used == 0) {
+ // lock
+ m_rb[i].used = 1;
+ m_rb[i].time = PR_Now();
+ PR_Unlock(m_free_block_lock);
+ return &m_rb[i];
+ }
+ }
+ PR_Unlock(m_free_block_lock);
+ return NULL;
+}
+
+ref_block *find_block(void *ptr)
+{
+ int i;
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (m_rb[i].used == 1 && m_rb[i].ptr == ptr) {
+ return &m_rb[i];
+ }
+ }
+ return NULL;
+}
+
+void free_block(ref_block *rb)
+{
+ rb->used = 0;
+}
+
+static PRFileDesc *m_audit_f = NULL;
+static PRFileDesc *m_dump_f = NULL;
+
+void MEM_init(char *audit_file, char *dump_file)
+{
+ m_audit_f = PR_Open(audit_file, PR_RDWR|PR_CREATE_FILE|PR_APPEND,
+ 00200|00400);
+ m_dump_f = PR_Open(dump_file, PR_RDWR|PR_CREATE_FILE|PR_APPEND,
+ 00200|00400);
+
+ int i;
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ m_rb[i].id = i;
+ m_rb[i].used = 0;
+ }
+ m_free_block_lock = PR_NewLock();
+ m_dump_lock = PR_NewLock();
+ m_audit_lock = PR_NewLock();
+}
+
+void MEM_shutdown()
+{
+ PR_DestroyLock(m_free_block_lock);
+ PR_DestroyLock(m_dump_lock);
+ PR_DestroyLock(m_audit_lock);
+ if (m_dump_f != NULL) {
+ PR_Close(m_dump_f);
+ }
+ if (m_audit_f != NULL) {
+ PR_Close(m_audit_f);
+ }
+}
+
+static void MEM_audit_block(ref_block *ref, const char *type, const char *func, const char *file, int line, PRFileDesc *f)
+{
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ char datetime1[1024];
+ PRExplodedTime time1;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+
+ PR_ExplodeTime(ref->time, PR_LocalTimeParameters, &time1);
+ PR_FormatTimeUSEnglish(datetime1, 1024, time_fmt, &time1);
+
+ PR_Lock(m_audit_lock);
+ PR_fprintf(f, "[%s] ID='%d' Size='%d' Type='%s' Func='%s' File='%s' Line='%d' Time='%s'\n",
+ datetime, ref->id, ref->size, type, func, file, line, datetime1);
+ PR_Sync(f);
+ PR_Unlock(m_audit_lock);
+}
+
+void MEM_dump_unfree()
+{
+ int i;
+ PRTime now;
+ const char* time_fmt = "%Y-%m-%d %H:%M:%S";
+ char datetime[1024];
+ PRExplodedTime time;
+ char datetime1[1024];
+ PRExplodedTime time1;
+ int sum_count = 0;
+ int sum_mem = 0;
+
+ now = PR_Now();
+ PR_ExplodeTime(now, PR_LocalTimeParameters, &time);
+ PR_FormatTimeUSEnglish(datetime, 1024, time_fmt, &time);
+
+ PR_Lock(m_dump_lock);
+ PR_fprintf(m_dump_f, "--------------------------------------------\n");
+ PR_fprintf(m_dump_f, "Memory Report - '%s'\n", datetime);
+ PR_fprintf(m_dump_f, "1) Unfree Blocks:\n");
+ PR_fprintf(m_dump_f, "\n");
+ for (i = 0; i < MAX_BLOCKS; i++) {
+ if (!m_rb[i].used)
+ continue;
+ PR_ExplodeTime(m_rb[i].time, PR_LocalTimeParameters, &time1);
+ PR_FormatTimeUSEnglish(datetime1, 1024, time_fmt, &time1);
+ PR_fprintf(m_dump_f, " ID='%d' Size='%d' Type='%s' Func='%s' File='%s' Line='%d' Time='%s'\n", m_rb[i].id, m_rb[i].size, m_rb[i].type, m_rb[i].func, m_rb[i].file, m_rb[i].line, datetime1);
+ sum_mem += m_rb[i].size;
+ sum_count += 1;
+ }
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "2) Total Unfree Memory Size:\n");
+ PR_fprintf(m_dump_f, " %d bytes\n", sum_mem);
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "3) Total Unfree Memory Blocks:\n");
+ PR_fprintf(m_dump_f, " %d\n", sum_count);
+ PR_fprintf(m_dump_f, "\n");
+ PR_fprintf(m_dump_f, "--------------------------------------------\n");
+ PR_Sync(m_dump_f);
+ PR_Unlock(m_dump_lock);
+}
+
+char *MEM_strdup(const char *s, const char *type, const char *func, const char *file, int line)
+{
+ ref_block *rb = get_free_block();
+ if (rb == NULL)
+ return NULL;
+
+ char *buf = strdup(s);
+
+ rb->ptr = buf;
+ rb->func = func;
+ rb->file = file;
+ rb->line = line;
+ rb->type = type;
+ rb->size = strlen(s) + 1;
+ MEM_audit_block(rb, rb->type, rb->func, rb->file, rb->line, m_audit_f);
+
+ return buf;
+}
+
+void *MEM_malloc(int size, const char *type, const char *func, const char *file, int line)
+{
+ ref_block *rb = get_free_block();
+ if (rb == NULL)
+ return NULL;
+ void *buf = malloc(size);
+
+ rb->ptr = buf;
+ rb->func = func;
+ rb->file = file;
+ rb->line = line;
+ rb->type = type;
+ rb->size = size;
+ MEM_audit_block(rb, rb->type, rb->func, rb->file, rb->line, m_audit_f);
+
+ return buf;
+}
+
+void MEM_free(void *p, const char *type, const char *func, const char *file, int line)
+{
+ if (p == NULL)
+ return;
+ ref_block *rb = find_block(p);
+ if (rb == NULL)
+ return;
+ MEM_audit_block(rb, type, func, file, line, m_audit_f);
+ free(p);
+ free_block(rb);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#if 0
+void *operator new(size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, func, file, line);
+}
+
+void *operator new[](size_t size, const char *func, const char *file, int line)
+{
+ return MEM_malloc(size, func, file, line);
+}
+
+#endif
+void operator delete(void *p)
+{
+ MEM_free(p,"delete","", "", 0);
+}
+
+void operator delete[](void *p)
+{
+ MEM_free(p,"delete[]","", "", 0);
+}
+
+#endif /* MEM_PROFILING */
+
diff --git a/pki/base/tps/src/main/NameValueSet.cpp b/pki/base/tps/src/main/NameValueSet.cpp
new file mode 100644
index 000000000..bd95a8e4a
--- /dev/null
+++ b/pki/base/tps/src/main/NameValueSet.cpp
@@ -0,0 +1,322 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <stdio.h>
+#include <string.h>
+#include "prmem.h"
+#include "prsystem.h"
+#include "plstr.h"
+#include "prio.h"
+#include "prprf.h"
+#include "main/NameValueSet.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PR_CALLBACK void*
+_AllocTable(void* pool, PRSize size)
+{
+ return PR_MALLOC(size);
+}
+
+static PR_CALLBACK void
+_FreeTable(void* pool, void* item)
+{
+ PR_DELETE(item);
+}
+
+static PR_CALLBACK PLHashEntry*
+_AllocEntry(void* pool, const void* key)
+{
+ return PR_NEW(PLHashEntry);
+}
+
+static PR_CALLBACK void
+_FreeEntry(void* pool, PLHashEntry* he, PRUintn flag)
+{
+ if( he == NULL ) {
+ return;
+ }
+
+ if (flag == HT_FREE_VALUE) {
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ } else if (flag == HT_FREE_ENTRY) {
+ if( he->key != NULL ) {
+ PL_strfree( ( char* ) he->key );
+ he->key = NULL;
+ }
+ if( he->value != NULL ) {
+ PL_strfree( ( char* ) he->value );
+ he->value = NULL;
+ }
+ PR_DELETE(he);
+ }
+}
+
+static PLHashAllocOps _AllocOps = {
+ _AllocTable,
+ _FreeTable,
+ _AllocEntry,
+ _FreeEntry
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+TPS_PUBLIC NameValueSet::NameValueSet()
+{
+ m_set = PL_NewHashTable(3, PL_HashString,
+ PL_CompareStrings, PL_CompareValues,
+ &_AllocOps, NULL);
+}
+
+TPS_PUBLIC NameValueSet::~NameValueSet ()
+{
+ if( m_set != NULL ) {
+ PL_HashTableDestroy( m_set );
+ m_set = NULL;
+ }
+
+ return;
+}
+
+/**
+ * Parsers string of format "n1=v1&n2=v2..."
+ * into a NameValueSet.
+ */
+TPS_PUBLIC NameValueSet *NameValueSet::Parse(const char *s, const char *separator)
+{
+ NameValueSet *set = NULL;
+ char *pair;
+ char *line = NULL;
+ int i;
+ int len;
+ char *lasts = NULL;
+
+ if (s == NULL)
+ return NULL;
+ set = new NameValueSet();
+ line = PL_strdup(s);
+ pair = PL_strtok_r(line, separator, &lasts);
+ while (pair != NULL) {
+ len = strlen(pair);
+ i = 0;
+ while (1) {
+ if (i >= len) {
+ goto skip;
+ }
+ if (pair[i] == '\0') {
+ goto skip;
+ }
+ if (pair[i] == '=') {
+ pair[i] = '\0';
+ break;
+ }
+ i++;
+ }
+ set->Add(&pair[0], &pair[i+1]);
+skip:
+ pair = PL_strtok_r(NULL, separator, &lasts);
+ }
+ if( line != NULL ) {
+ PL_strfree( line );
+ line = NULL;
+ }
+ return set;
+}
+
+typedef struct {
+ int index;
+ char *key;
+} Criteria;
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+static PRIntn CountLoop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ criteria->index++;
+ return HT_ENUMERATE_NEXT;
+}
+
+static PRIntn Loop(PLHashEntry *he, PRIntn index, void *arg)
+{
+ Criteria *criteria = (Criteria *)arg;
+ if (criteria != NULL && index == criteria->index) {
+ criteria->key = (char *)he->key;
+ return HT_ENUMERATE_STOP;
+ } else {
+ return HT_ENUMERATE_NEXT;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+TPS_PUBLIC int NameValueSet::Size()
+{
+ Criteria criteria;
+ criteria.index = 0;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_set, &CountLoop, &criteria);
+ return criteria.index;
+}
+
+TPS_PUBLIC char *NameValueSet::GetNameAt(int pos)
+{
+ Criteria criteria;
+ criteria.index = pos;
+ criteria.key = NULL;
+ PL_HashTableEnumerateEntries(m_set, &Loop, &criteria);
+ return criteria.key;
+}
+
+/**
+ * Checks if a key is defined.
+ */
+TPS_PUBLIC int NameValueSet::IsNameDefined(const char *name)
+{
+ if (GetValue(name) == NULL)
+ return 0;
+ else
+ return 1;
+}
+
+TPS_PUBLIC void NameValueSet::Add(const char *name, const char *value)
+{
+ if (IsNameDefined(name)) {
+ PL_HashTableAdd(m_set, PL_strdup(name), PL_strdup(value));
+ } else {
+ PL_HashTableAdd(m_set, PL_strdup(name), PL_strdup(value));
+ }
+}
+
+TPS_PUBLIC void NameValueSet::Remove(const char *name)
+{
+ if (IsNameDefined(name)) {
+ PL_HashTableRemove(m_set, name);
+ }
+}
+
+TPS_PUBLIC char *NameValueSet::GetValue(const char *name)
+{
+ return (char *)PL_HashTableLookupConst(m_set, name);
+}
+
+/**
+ * Retrieves configuration value as integer.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsInt(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return 0;
+ return atoi(value);
+}
+
+/**
+ * Retrieves configuration value as integer. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsInt(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ return atoi(value);
+}
+
+
+/**
+ * Retrieves configuration value as boolean.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsBool(const char *name)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return 0;
+ if (PL_CompareStrings("true", value) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Retrieves configuration value as boolean. If name is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC int NameValueSet::GetValueAsBool(const char *name, int def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ if (PL_CompareStrings("true", value) != 0)
+ return 1;
+ else
+ return 0;
+}
+
+/**
+ * Retrieves configuration value as string. If key is
+ * not defined, default value is returned.
+ */
+TPS_PUBLIC char *NameValueSet::GetValueAsString(const char *name, char *def)
+{
+ char *value = NULL;
+
+ value = (char *)GetValue(name);
+ if (value == NULL)
+ return def;
+ return value;
+}
+
+/**
+ * Retrieves configuration value as string.
+ */
+TPS_PUBLIC char *NameValueSet::GetValueAsString(const char *name)
+{
+ return (char *)GetValue(name);
+}
+
diff --git a/pki/base/tps/src/main/ObjectSpec.cpp b/pki/base/tps/src/main/ObjectSpec.cpp
new file mode 100644
index 000000000..b53ced3ad
--- /dev/null
+++ b/pki/base/tps/src/main/ObjectSpec.cpp
@@ -0,0 +1,500 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "main/Buffer.h"
+#include "main/ObjectSpec.h"
+#include "engine/RA.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+ObjectSpec::ObjectSpec ()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ m_attributeSpec[i] = NULL;
+ }
+ m_fixedAttributes = 0;
+}
+
+ObjectSpec::~ObjectSpec ()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] != NULL) {
+ delete m_attributeSpec[i];
+ m_attributeSpec[i] = NULL;
+ }
+ }
+}
+
+#define DATATYPE_STRING 0
+#define DATATYPE_INTEGER 1
+#define DATATYPE_BOOL_FALSE 2
+#define DATATYPE_BOOL_TRUE 3
+
+/**
+ * Parse 'c' object.
+ */
+void ObjectSpec::ParseAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ int curpos = 7;
+ unsigned long fixedAttrs = 0;
+ unsigned int xclass = 0;
+ unsigned int id = 0;
+
+ /* skip first 7 bytes */
+
+ while (curpos < ((int)(b->size()))) {
+ unsigned long attribute_id =
+ (((BYTE*)*b)[curpos] << 24) +
+ (((BYTE*)*b)[curpos+1] << 16) +
+ (((BYTE*)*b)[curpos+2] << 8) +
+ ((BYTE*)*b)[curpos+3];
+ unsigned short attribute_size =
+ (((BYTE*)*b)[curpos+4] << 8) +
+ ((BYTE*)*b)[curpos+5];
+ BYTE type = 0;
+ Buffer data;
+ int found = 0;
+ /* modify fixed attributes */
+
+ switch (attribute_id) {
+ case CKA_TOKEN:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000080;
+ }
+ break;
+ case CKA_PRIVATE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000100;
+ } else {
+ }
+ break;
+ case CKA_MODIFIABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000200;
+ }
+ break;
+ case CKA_DERIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000400;
+ }
+ break;
+ case CKA_LOCAL:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00000800;
+ }
+ break;
+ case CKA_ENCRYPT:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00001000;
+ }
+ break;
+ case CKA_DECRYPT:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00002000;
+ }
+ break;
+ case CKA_WRAP:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00004000;
+ }
+ break;
+ case CKA_UNWRAP:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00008000;
+ }
+ break;
+ case CKA_SIGN:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00010000;
+ }
+ break;
+ case CKA_SIGN_RECOVER:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00020000;
+ }
+ break;
+ case CKA_VERIFY:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00040000;
+ }
+ break;
+ case CKA_VERIFY_RECOVER:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00080000;
+ }
+ break;
+ case CKA_SENSITIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00100000;
+ }
+ break;
+ case CKA_ALWAYS_SENSITIVE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00200000;
+ }
+ break;
+ case CKA_EXTRACTABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00400000;
+ }
+ break;
+ case CKA_NEVER_EXTRACTABLE:
+ if (((BYTE*)*b)[curpos+6]) {
+ fixedAttrs |= 0x00800000;
+ }
+ break;
+ case CKA_SUBJECT:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_LABEL:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ found = 1;
+ break;
+ case CKA_MODULUS:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_ID:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_KEY_TYPE:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ /* build by PKCS11 */
+ break;
+ case CKA_CLASS:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ xclass = ((BYTE*)data)[0];
+ /* build by PKCS11 */
+ break;
+ case CKA_PUBLIC_EXPONENT:
+ type = DATATYPE_STRING;
+ data = b->substr(curpos+6, attribute_size);
+ /* build by PKCS11 */
+ break;
+ case CKA_CERTIFICATE_TYPE:
+ type = DATATYPE_INTEGER;
+ data = b->substr(curpos+6, 4);
+ /* build by PKCS11 */
+ break;
+ default:
+ RA::Debug("ObjectSpec::ParseKeyBlob",
+ "skipped attribute_id = %lx",
+ attribute_id);
+ break;
+ }
+
+
+ if (found) {
+ /* add attribute spec */
+ AttributeSpec *attrSpec = new AttributeSpec();
+ attrSpec->SetAttributeID(attribute_id);
+ attrSpec->SetType(type);
+
+ switch (type) {
+ case DATATYPE_STRING:
+ attrSpec->SetData(data);
+ break;
+ case DATATYPE_INTEGER:
+ attrSpec->SetData(data);
+ break;
+ case DATATYPE_BOOL_FALSE:
+ break;
+ case DATATYPE_BOOL_TRUE:
+ break;
+ default:
+ break;
+ }
+
+ ObjectSpec->AddAttributeSpec(attrSpec);
+ }
+
+
+ curpos += 4 + 2 + attribute_size;
+ }
+
+ int val = (objectID[1] - '0');
+ switch (objectID[0]) {
+ case 'c':
+ id = val;
+#if 0
+ fixedAttrs |=
+ 0x00000080 /* CKA_TOKEN */
+ ;
+#endif
+ break;
+ case 'k':
+ if (val % 2) {
+ id = (val-1)/2;
+ } else {
+ id = (val/2);
+ }
+#if 0
+ if (xclass == CKO_PUBLIC_KEY) {
+ fixedAttrs |=
+ 0x00000800 /* CKA_LOCAL */ |
+ 0x00000080 /* CKA_TOKEN */
+ ;
+ }
+ if (xclass == CKO_PRIVATE_KEY) {
+ fixedAttrs |=
+ 0x00000800 /* CKA_LOCAL */ |
+ 0x00000080 /* CKA_TOKEN */
+ ;
+ }
+#endif
+ break;
+ }
+
+ ObjectSpec->SetFixedAttributes(fixedAttrs | (xclass << 4) | id);
+}
+
+/**
+ * Parse 'c' object.
+ */
+void ObjectSpec::ParseCertificateAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ ParseAttributes(objectID, ObjectSpec, b);
+}
+
+/**
+ * Parse 'k' object.
+ */
+void ObjectSpec::ParseKeyAttributes(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ ParseAttributes(objectID, ObjectSpec, b);
+}
+
+/**
+ * Parse 'C' object.
+ */
+void ObjectSpec::ParseCertificateBlob(char *objectID, ObjectSpec *ObjectSpec, Buffer *b)
+{
+ unsigned long fixedAttrs = 0;
+ unsigned int xclass = 0;
+ unsigned int id = 0;
+
+ AttributeSpec *value = new AttributeSpec();
+ value->SetAttributeID(CKA_VALUE);
+ value->SetType(DATATYPE_STRING);
+ value->SetData(*b);
+ ObjectSpec->AddAttributeSpec(value);
+
+ fixedAttrs = 0x00000080; /* CKA_TOKEN */
+ xclass = CKO_CERTIFICATE;
+ id = objectID[1] - '0';
+
+ ObjectSpec->SetFixedAttributes(fixedAttrs| (xclass << 4) | id);
+}
+
+/**
+ * Convert object from token into object spec.
+ *
+ * Reference:
+ * http://netkey/design/applet_readable_object_spec-0.1.txt
+ * http://netkey/design/pkcs11obj.txt
+ */
+ObjectSpec *ObjectSpec::ParseFromTokenData(unsigned long objid, Buffer *b)
+{
+ char objectID[4];
+
+ ObjectSpec *o = new ObjectSpec();
+ o->SetObjectID(objid);
+
+ objectID[0] = (char)((objid >> 24) & 0xff);
+ objectID[1] = (char)((objid >> 16) & 0xff);
+ objectID[2] = (char)((objid >> 8) & 0xff);
+ objectID[3] = (char)((objid) & 0xff);
+
+ switch (objectID[0]) {
+ case 'c': /* certificate attributes */
+ ParseCertificateAttributes(objectID, o, b);
+ break;
+ case 'k': /* public key or private key attributes */
+ ParseKeyAttributes(objectID, o, b);
+ break;
+ case 'C': /* certificate in DER */
+ ParseCertificateBlob(objectID, o, b);
+ break;
+ default:
+ RA::Debug("ObjectSpec::ParseKeyBlob",
+ "unknown objectID = %c", objectID[0]);
+ /* error */
+ break;
+ }
+
+ return o;
+}
+
+ObjectSpec *ObjectSpec::Parse(Buffer *b, int offset, int *nread)
+{
+ int sum = 0;
+
+ ObjectSpec *o = new ObjectSpec();
+ unsigned long id =
+ (((unsigned char *)*b)[offset + 0] << 24) +
+ (((unsigned char *)*b)[offset + 1] << 16) +
+ (((unsigned char *)*b)[offset + 2] << 8) +
+ (((unsigned char *)*b)[offset + 3]);
+ o->SetObjectID(id);
+ unsigned long attribute =
+ (((unsigned char *)*b)[offset + 4] << 24) +
+ (((unsigned char *)*b)[offset + 5] << 16) +
+ (((unsigned char *)*b)[offset + 6] << 8) +
+ (((unsigned char *)*b)[offset + 7]);
+ o->SetFixedAttributes(attribute);
+ unsigned short count = (((unsigned char *)*b)[offset + 8] << 8) +
+ ((unsigned char *)*b)[offset + 9];
+ sum += 10;
+ int curpos = offset + 10;
+ for (int i = 0; i < count; i++) {
+ int len = 0;
+ switch (((unsigned char *)*b)[curpos+4]) {
+ case DATATYPE_STRING:
+ len = 4 + 1 + 2 + (((unsigned char *)*b)[curpos+5]<<8) + ((unsigned char *)*b)[curpos+6];
+ break;
+ case DATATYPE_INTEGER:
+ len = 4 + 1 + 4;
+ break;
+ case DATATYPE_BOOL_FALSE:
+ len = 4 + 1;
+ break;
+ case DATATYPE_BOOL_TRUE:
+ len = 4 + 1;
+ break;
+ }
+ Buffer attr = b->substr(curpos, len);
+ AttributeSpec *attrSpec = AttributeSpec::Parse(&attr, 0);
+ o->AddAttributeSpec(attrSpec);
+ curpos += len;
+ sum += len;
+ }
+ *nread = sum;
+ return o;
+}
+
+void ObjectSpec::SetObjectID(unsigned long v)
+{
+ m_objectID = v;
+}
+
+unsigned long ObjectSpec::GetObjectID()
+{
+ return m_objectID;
+}
+
+void ObjectSpec::SetFixedAttributes(unsigned long v)
+{
+ m_fixedAttributes = v;
+}
+
+unsigned long ObjectSpec::GetFixedAttributes()
+{
+ return m_fixedAttributes;
+}
+
+
+int ObjectSpec::GetAttributeSpecCount()
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] == NULL) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+AttributeSpec *ObjectSpec::GetAttributeSpec(int p)
+{
+ if (p < MAX_ATTRIBUTE_SPEC) {
+ if (m_attributeSpec[p] != NULL) {
+ return m_attributeSpec[p];
+ }
+ }
+ return NULL;
+}
+
+void ObjectSpec::AddAttributeSpec(AttributeSpec *p)
+{
+ for (int i = 0; i < MAX_ATTRIBUTE_SPEC; i++) {
+ if (m_attributeSpec[i] == NULL) {
+ m_attributeSpec[i] = p;
+ return;
+ }
+ }
+}
+
+void ObjectSpec::RemoveAttributeSpec(int p)
+{
+ if (p < MAX_ATTRIBUTE_SPEC) {
+ if (m_attributeSpec[p] != NULL) {
+ delete m_attributeSpec[p];
+ m_attributeSpec[p] = NULL;
+ }
+ // fill hole
+ int empty = p;
+ for (int x = p+1; x < MAX_ATTRIBUTE_SPEC; x++) {
+ if (m_attributeSpec[x] != NULL) {
+ m_attributeSpec[empty] = m_attributeSpec[x];
+ m_attributeSpec[x] = NULL;
+ empty++;
+ }
+ }
+ }
+
+}
+
+Buffer ObjectSpec::GetData()
+{
+ Buffer data = Buffer();
+
+ data += Buffer(1, (BYTE)(m_objectID >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID >> 8) & 0xff);
+ data += Buffer(1, (BYTE)(m_objectID & 0xff));
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 24) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 16) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes >> 8) & 0xff);
+ data += Buffer(1, (BYTE)(m_fixedAttributes & 0xff));
+
+ unsigned short attributeCount = GetAttributeSpecCount();
+ data += Buffer(1, (attributeCount >> 8) & 0xff);
+ data += Buffer(1, attributeCount & 0xff);
+ for (int i = 0; i < attributeCount; i++) {
+ AttributeSpec *spec = GetAttributeSpec(i);
+ data += spec->GetData();
+ }
+
+ return data;
+}
diff --git a/pki/base/tps/src/main/PKCS11Obj.cpp b/pki/base/tps/src/main/PKCS11Obj.cpp
new file mode 100644
index 000000000..57d63d215
--- /dev/null
+++ b/pki/base/tps/src/main/PKCS11Obj.cpp
@@ -0,0 +1,454 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "zlib.h"
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/PKCS11Obj.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+PKCS11Obj::PKCS11Obj ()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ m_objSpec[i] = NULL;
+ }
+}
+
+PKCS11Obj::~PKCS11Obj ()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] != NULL) {
+ delete m_objSpec[i];
+ m_objSpec[i] = NULL;
+ }
+ }
+}
+
+PKCS11Obj *PKCS11Obj::Parse(Buffer *b, int offset)
+{
+ PKCS11Obj *o = new PKCS11Obj();
+
+ unsigned short formatVersion = (((BYTE *)*b)[offset + 0] << 8) +
+ (((BYTE *)*b)[offset + 1]);
+ o->SetFormatVersion(formatVersion);
+ unsigned short objectVersion = (((BYTE *)*b)[offset + 2] << 8) +
+
+ (((BYTE *)*b)[offset + 3]);
+ o->SetObjectVersion(objectVersion);
+ o->SetCUID(b->substr(offset + 4, 10));
+
+ unsigned short compressionType =
+ (((BYTE *)*b)[offset + 14] << 8) + (((BYTE *)*b)[offset + 15]);
+ unsigned short compressedDataSize =
+ (((BYTE *)*b)[offset + 16] << 8) + (((BYTE *)*b)[offset + 17]);
+#if 0
+ unsigned short compressedDataOffset =
+ (unsigned short)(((unsigned char *)*b)[offset + 18] << 8) + (((unsigned char *)*b)[offset + 19]);
+#endif
+
+ Buffer data;
+ if (compressionType == 0) { /* no compression */
+ data = b->substr(offset + 20, compressedDataSize);
+ } else if (compressionType == 1) { /* zlib */
+ Buffer compressedData = b->substr(offset + 20, compressedDataSize);
+
+#define MAX_UNCOMPRESS_SIZE 20000
+ unsigned char buf[MAX_UNCOMPRESS_SIZE];
+ int len = MAX_UNCOMPRESS_SIZE;
+ uncompress((Bytef*)buf, (uLongf*)&len,
+ (Bytef*)((BYTE*)compressedData),
+ (uLong)compressedData.size());
+ data = Buffer(buf, len);
+ } else {
+ /* error */
+ }
+
+
+ unsigned short objOffset = (((BYTE *)data)[0] << 8) +
+ ((BYTE *)data)[1];
+ unsigned short objCount = (((BYTE *)data)[2] << 8) +
+ ((BYTE *)data)[3];
+ Buffer tokenName = data.substr(5, ((BYTE *)data)[4]);
+ o->SetTokenName(tokenName);
+
+
+ int curpos = (int)objOffset;
+ int nread = 0;
+ for (int i = 0; i < objCount; i++) {
+ ObjectSpec *objSpec = ObjectSpec::Parse(&data, curpos, &nread);
+ o->AddObjectSpec(objSpec);
+
+ unsigned long oid = objSpec->GetObjectID();
+ char b[2];
+ b[0] = (char)((oid >> 24) & 0xff);
+ b[1] = (char)((oid >> 16) & 0xff);
+
+ // add corresponding 'C' object for 'c'
+ if (b[0] == 'c') {
+ for (int j = 0; j < objSpec->GetAttributeSpecCount();
+ j++) {
+ AttributeSpec *as = objSpec->GetAttributeSpec(j);
+ if (as->GetAttributeID() == CKA_VALUE) {
+ if (as->GetType() == (BYTE) 0) {
+ Buffer cert = as->GetValue();
+
+ unsigned long certid =
+ ('C' << 24) + (b[1] << 16);
+ ObjectSpec *certSpec =
+ ObjectSpec::ParseFromTokenData(
+ certid, &cert);
+ o->AddObjectSpec(certSpec);
+
+ objSpec->RemoveAttributeSpec(j);
+ break;
+ }
+ }
+ }
+
+ }
+
+ Buffer objSpecData = objSpec->GetData();
+ curpos += nread;
+ }
+
+ return o;
+}
+
+
+void PKCS11Obj::SetFormatVersion(unsigned short v)
+{
+ m_formatVersion = v;
+}
+
+void PKCS11Obj::SetObjectVersion(unsigned short v)
+{
+ m_objectVersion = v;
+}
+
+unsigned short PKCS11Obj::GetFormatVersion()
+{
+ return m_formatVersion;
+}
+
+unsigned short PKCS11Obj::GetObjectVersion()
+{
+ return m_objectVersion;
+}
+
+void PKCS11Obj::SetCUID(Buffer CUID)
+{
+ m_CUID = CUID;
+}
+
+Buffer PKCS11Obj::GetCUID()
+{
+ return m_CUID;
+}
+
+void PKCS11Obj::SetTokenName(Buffer tokenName)
+{
+ m_tokenName = tokenName;
+}
+
+Buffer PKCS11Obj::GetTokenName()
+{
+ return m_tokenName;
+}
+
+int PKCS11Obj::GetObjectSpecCount()
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] == NULL) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+ObjectSpec *PKCS11Obj::GetObjectSpec(int p)
+{
+ if (p < MAX_OBJECT_SPEC) {
+ if (m_objSpec[p] != NULL) {
+ return m_objSpec[p];
+ }
+ }
+ return NULL;
+}
+
+void PKCS11Obj::AddObjectSpec(ObjectSpec *p)
+{
+ for (int i = 0; i < MAX_OBJECT_SPEC; i++) {
+ if (m_objSpec[i] == NULL) {
+ m_objSpec[i] = p;
+ return;
+ } else {
+ // check duplicated
+ if (p->GetObjectID() == m_objSpec[i]->GetObjectID()) {
+ delete m_objSpec[i];
+ m_objSpec[i] = p;
+ return;
+ }
+ }
+ }
+}
+
+void PKCS11Obj::RemoveObjectSpec(int p)
+{
+ if (p < MAX_OBJECT_SPEC) {
+ if (m_objSpec[p] != NULL) {
+ delete m_objSpec[p];
+ m_objSpec[p] = NULL;
+ }
+ // fill hole
+ int empty = p;
+ for (int x = p+1; x < MAX_OBJECT_SPEC; x++) {
+ if (m_objSpec[x] != NULL) {
+ m_objSpec[empty] = m_objSpec[x];
+ m_objSpec[x] = NULL;
+ empty++;
+ }
+ }
+ }
+}
+
+Buffer PKCS11Obj::GetData()
+{
+ Buffer data = Buffer();
+
+ unsigned short objectOffset = m_tokenName.size() + 2 + 3;
+ data += Buffer(1, (objectOffset >> 8) & 0xff);
+ data += Buffer(1, objectOffset & 0xff);
+ unsigned short objectCount = GetObjectSpecCount();
+ unsigned short objectCountX = objectCount;
+ if (objectCountX == 0) {
+ objectCountX = 0;
+ } else {
+ objectCountX = objectCountX - (objectCountX / 4);
+ }
+ data += Buffer(1, (objectCountX >> 8) & 0xff);
+ data += Buffer(1, objectCountX & 0xff);
+ data += Buffer(1, m_tokenName.size() & 0xff);
+ data += m_tokenName;
+ for (int i = 0; i < objectCount; i++) {
+ ObjectSpec *spec = GetObjectSpec(i);
+ unsigned long objectID = spec->GetObjectID();
+ char c = (char)((objectID >> 24) & 0xff);
+ unsigned long fixedAttrs = spec->GetFixedAttributes();
+ unsigned int xclass = (fixedAttrs & 0x70) >> 4;
+ unsigned int id = (fixedAttrs & 0x0f);
+ /* locate all certificate objects */
+ if (c == 'c' && xclass == CKO_CERTIFICATE) {
+ /* locate the certificate object */
+ for (int u = 0; u < objectCount; u++) {
+ ObjectSpec *u_spec = GetObjectSpec(u);
+ unsigned long u_objectID = u_spec->GetObjectID();
+ char u_c = (char)((u_objectID >> 24) & 0xff);
+ unsigned long u_fixedAttrs =
+ u_spec->GetFixedAttributes();
+ unsigned int u_xclass = (u_fixedAttrs & 0x70) >> 4;
+ unsigned int u_id = (u_fixedAttrs & 0x0f);
+ if (u_c == 'C' && u_xclass == CKO_CERTIFICATE && u_id == id) {
+ AttributeSpec * u_attr =
+ u_spec->GetAttributeSpec(0);
+ AttributeSpec * n_attr = new AttributeSpec();
+ n_attr->SetAttributeID(u_attr->GetAttributeID());
+ n_attr->SetType(u_attr->GetType());
+ n_attr->SetData(u_attr->GetValue());
+ spec->AddAttributeSpec(n_attr);
+ }
+ }
+
+ data += spec->GetData();
+
+ /* locate public object */
+ for (int x = 0; x < objectCount; x++) {
+ ObjectSpec *x_spec = GetObjectSpec(x);
+ unsigned long x_fixedAttrs =
+ x_spec->GetFixedAttributes();
+ unsigned int x_xclass = (x_fixedAttrs & 0x70) >> 4;
+ unsigned int x_id = (x_fixedAttrs & 0x0f);
+ if (x_xclass == CKO_PUBLIC_KEY && x_id == id) {
+ data += x_spec->GetData();
+ }
+ }
+
+ /* locate private object */
+ for (int y = 0; y < objectCount; y++) {
+ ObjectSpec *y_spec = GetObjectSpec(y);
+ unsigned long y_fixedAttrs =
+ y_spec->GetFixedAttributes();
+ unsigned int y_xclass = (y_fixedAttrs & 0x70) >> 4;
+ unsigned int y_id = (y_fixedAttrs & 0x0f);
+ if (y_xclass == CKO_PRIVATE_KEY && y_id == id) {
+ data += y_spec->GetData();
+ }
+ }
+ }
+ }
+
+ Buffer header = Buffer();
+ header += Buffer(1, (m_formatVersion >> 8) & 0xff);
+ header += Buffer(1, m_formatVersion & 0xff);
+ header += Buffer(1, (m_objectVersion >> 8) & 0xff);
+ header += Buffer(1, m_objectVersion & 0xff);
+ header += m_CUID;
+ // COMP_NONE = 0x00
+ // COMP_ZLIB = 0x01
+ unsigned short compressionType = 0x00;
+ header += Buffer(1, (compressionType >> 8) & 0xff);
+ header += Buffer(1, compressionType & 0xff);
+ unsigned short compressedDataSize = data.size();
+ header += Buffer(1, (compressedDataSize >> 8) & 0xff);
+ header += Buffer(1, compressedDataSize & 0xff);
+ unsigned short compressedDataOffset = 20;
+ header += Buffer(1, (compressedDataOffset >> 8) & 0xff);
+ header += Buffer(1, compressedDataOffset & 0xff);
+
+ return header + data;
+}
+
+Buffer PKCS11Obj::GetCompressedData()
+{
+ Buffer data = Buffer();
+
+ unsigned short objectOffset = m_tokenName.size() + 2 + 3;
+ data += Buffer(1, (objectOffset >> 8) & 0xff);
+ data += Buffer(1, objectOffset & 0xff);
+ unsigned short objectCount = GetObjectSpecCount();
+ unsigned short objectCountX = objectCount;
+ if (objectCountX == 0) {
+ objectCountX = 0;
+ } else {
+ objectCountX = objectCountX - (objectCountX / 4);
+ }
+ data += Buffer(1, (objectCountX >> 8) & 0xff);
+ data += Buffer(1, objectCountX & 0xff);
+ data += Buffer(1, m_tokenName.size() & 0xff);
+ data += m_tokenName;
+
+ for (int i = 0; i < objectCount; i++) {
+ ObjectSpec *spec = GetObjectSpec(i);
+ unsigned long objectID = spec->GetObjectID();
+ char c = (char)((objectID >> 24) & 0xff);
+ unsigned long fixedAttrs = spec->GetFixedAttributes();
+ unsigned int xclass = (fixedAttrs & 0x70) >> 4;
+ unsigned int id = (fixedAttrs & 0x0f);
+ /* locate all certificate objects */
+ if (c == 'c' && xclass == CKO_CERTIFICATE) {
+
+ /* locate the certificate object */
+ for (int u = 0; u < objectCount; u++) {
+ ObjectSpec *u_spec = GetObjectSpec(u);
+ unsigned long u_objectID = u_spec->GetObjectID();
+ char u_c = (char)((u_objectID >> 24) & 0xff);
+ unsigned long u_fixedAttrs =
+ u_spec->GetFixedAttributes();
+ unsigned int u_xclass = (u_fixedAttrs & 0x70) >> 4;
+ unsigned int u_id = (u_fixedAttrs & 0x0f);
+ if (u_c == 'C' && u_xclass == CKO_CERTIFICATE && u_id == id) {
+ AttributeSpec * u_attr =
+ u_spec->GetAttributeSpec(0);
+ AttributeSpec * n_attr = new AttributeSpec();
+ n_attr->SetAttributeID(u_attr->GetAttributeID());
+ n_attr->SetType(u_attr->GetType());
+ n_attr->SetData(u_attr->GetValue());
+ spec->AddAttributeSpec(n_attr);
+ }
+ }
+
+ /* output certificate attribute object */
+ data += spec->GetData();
+
+ /* locate public object */
+ for (int x = 0; x < objectCount; x++) {
+ ObjectSpec *x_spec = GetObjectSpec(x);
+ unsigned long x_fixedAttrs =
+ x_spec->GetFixedAttributes();
+ unsigned int x_xclass = (x_fixedAttrs & 0x70) >> 4;
+ unsigned int x_id = (x_fixedAttrs & 0x0f);
+ if (x_xclass == CKO_PUBLIC_KEY && x_id == id) {
+ data += x_spec->GetData();
+ }
+ }
+
+ /* locate private object */
+ for (int y = 0; y < objectCount; y++) {
+ ObjectSpec *y_spec = GetObjectSpec(y);
+ unsigned long y_fixedAttrs =
+ y_spec->GetFixedAttributes();
+ unsigned int y_xclass = (y_fixedAttrs & 0x70) >> 4;
+ unsigned int y_id = (y_fixedAttrs & 0x0f);
+ if (y_xclass == CKO_PRIVATE_KEY && y_id == id) {
+ data += y_spec->GetData();
+ }
+ }
+ }
+ }
+
+#define MAX_COMPRESS_SIZE 50000
+ char buffer[MAX_COMPRESS_SIZE];
+ unsigned long len = MAX_COMPRESS_SIZE ;
+
+ int rc = 0;
+
+ RA::Debug("PKCS11Obj", "before compress length = %d", len);
+
+ BYTE *src_buffer = (BYTE*)data;
+
+ RA::Debug("PKCS11Obj", "sizeof src_buffer = %d", sizeof(src_buffer));
+ RA::Debug("PKCS11Obj", "data size = %d", data.size());
+
+ rc = compress((Bytef*)buffer, (uLongf*)&len, (Bytef*)src_buffer,
+ (uLong)data.size());
+
+ RA::Debug("PKCS11Obj", "after compress length = %d", len);
+ RA::Debug("PKCS11Obj", "rc = %d", rc);
+
+ Buffer compressedData = Buffer((BYTE*)buffer, len);
+
+ Buffer header = Buffer();
+ header += Buffer(1, (m_formatVersion >> 8) & 0xff);
+ header += Buffer(1, m_formatVersion & 0xff);
+ header += Buffer(1, (m_objectVersion >> 8) & 0xff);
+ header += Buffer(1, m_objectVersion & 0xff);
+ header += m_CUID;
+ // COMP_NONE = 0x00
+ // COMP_ZLIB = 0x01
+ unsigned short compressionType = 0x01;
+ header += Buffer(1, (compressionType >> 8) & 0xff);
+ header += Buffer(1, compressionType & 0xff);
+ unsigned short compressedDataSize = compressedData.size();
+ header += Buffer(1, (compressedDataSize >> 8) & 0xff);
+ header += Buffer(1, compressedDataSize & 0xff);
+ unsigned short compressedDataOffset = 20;
+ header += Buffer(1, (compressedDataOffset >> 8) & 0xff);
+ header += Buffer(1, compressedDataOffset & 0xff);
+
+ return header + compressedData;
+}
+
diff --git a/pki/base/tps/src/main/RA_Context.cpp b/pki/base/tps/src/main/RA_Context.cpp
new file mode 100644
index 000000000..e3a66cdbb
--- /dev/null
+++ b/pki/base/tps/src/main/RA_Context.cpp
@@ -0,0 +1,56 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "main/RA_Msg.h"
+#include "main/RA_Context.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a session that represents the
+ * connection between RA and the netkey client.
+ */
+TPS_PUBLIC RA_Context::RA_Context ()
+{
+}
+
+/**
+ * Destructs the session.
+ */
+TPS_PUBLIC RA_Context::~RA_Context ()
+{
+}
+
+void RA_Context::LogError(const char *func, int line, const char *fmt,...)
+{
+}
+
+void RA_Context::LogInfo(const char *func, int line, const char *fmt,...)
+{
+}
+
+void RA_Context::InitializationError(const char *func, int line)
+{
+}
+
diff --git a/pki/base/tps/src/main/RA_Msg.cpp b/pki/base/tps/src/main/RA_Msg.cpp
new file mode 100644
index 000000000..d54db69fb
--- /dev/null
+++ b/pki/base/tps/src/main/RA_Msg.cpp
@@ -0,0 +1,45 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "main/RA_Msg.h"
+#include "main/Memory.h"
+
+/**
+ * Constructs a message that represents the
+ * message between RA and the netkey client.
+ */
+RA_Msg::RA_Msg ()
+{
+}
+
+/**
+ * Destructs the message.
+ */
+RA_Msg::~RA_Msg ()
+{
+}
+
+/**
+ * Retrieves the message type.
+ */
+RA_Msg_Type RA_Msg::GetType ()
+{
+ return MSG_UNDEFINED;
+}
diff --git a/pki/base/tps/src/main/RA_Session.cpp b/pki/base/tps/src/main/RA_Session.cpp
new file mode 100644
index 000000000..57f7e4efa
--- /dev/null
+++ b/pki/base/tps/src/main/RA_Session.cpp
@@ -0,0 +1,75 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "engine/RA.h"
+#include "main/RA_Msg.h"
+#include "main/RA_Session.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+/**
+ * Constructs a session that represents the
+ * connection between RA and the netkey client.
+ */
+TPS_PUBLIC RA_Session::RA_Session ()
+{
+}
+
+/**
+ * Destructs the session.
+ */
+TPS_PUBLIC RA_Session::~RA_Session ()
+{
+}
+
+char *RA_Session::GetRemoteIP()
+{
+ return NULL;
+}
+
+RA_pblock *RA_Session::create_pblock( char *data )
+{
+ // Since this method is virtual,
+ // report an error if no subclass method has been defined.
+ RA::Error( "RA_pblock::find_val",
+ "No subclass method has been defined for this virtual method!" );
+ return NULL;
+}
+
+/**
+ * Reads a message that is sent by
+ * the client.
+ */
+RA_Msg *RA_Session::ReadMsg()
+{
+ return NULL;
+}
+
+/**
+ * Sends a message to the client.
+ */
+void RA_Session::WriteMsg(RA_Msg *msg)
+{
+}
diff --git a/pki/base/tps/src/main/RA_pblock.cpp b/pki/base/tps/src/main/RA_pblock.cpp
new file mode 100644
index 000000000..bea84363a
--- /dev/null
+++ b/pki/base/tps/src/main/RA_pblock.cpp
@@ -0,0 +1,176 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "prmem.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <string.h>
+#include "engine/RA.h"
+#include "main/Buffer.h"
+#include "main/Memory.h"
+#include "main/Util.h"
+#include "main/RA_pblock.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC RA_pblock::RA_pblock( int tm_nargs, Buffer_nv** tm_nvs )
+{
+ m_nargs = tm_nargs;
+
+ if( tm_nvs != NULL ) {
+ for( int i = 0; i < MAX_NVS; i++ ) {
+ m_nvs[i] = tm_nvs[i];
+ }
+ } else {
+ for( int i = 0; i < MAX_NVS; i++ ) {
+ m_nvs[i] = NULL;
+ }
+ }
+}
+
+TPS_PUBLIC RA_pblock::~RA_pblock()
+{
+ free_pblock();
+}
+
+Buffer_nv **RA_pblock::GetNVs()
+{
+ return m_nvs;
+}
+
+// returns url-decoded value
+TPS_PUBLIC Buffer *RA_pblock::find_val( const char * name )
+{
+ for( int i = 0; i < m_nargs; i++ ) {
+ if( i >= MAX_NVS ) {
+ continue;
+ }
+
+ if( ( m_nvs[i] == NULL ) ||
+ ( m_nvs[i]->name == NULL ) ||
+ ( m_nvs[i]->value == NULL ) ) {
+ continue;
+ }
+
+ if( PR_CompareStrings( m_nvs[i]->name, name ) == 1 ) {
+ return m_nvs[i]->value;
+ }
+ }
+
+ return NULL;
+}
+
+TPS_PUBLIC char *RA_pblock::get_name( int i )
+{
+ return m_nvs[i]->name;
+}
+
+TPS_PUBLIC int RA_pblock::get_num_of_names()
+{
+ return m_nargs;
+}
+
+// returns non-urldecoded value
+TPS_PUBLIC char* RA_pblock::find_val_s( const char * name )
+{
+ RA::Debug( LL_PER_PDU, "RA_pblock::find_val_s",
+ "searching for name= %s", name );
+
+ int end = m_nargs;
+
+ if( MAX_NVS < m_nargs ) {
+ RA::Error( "RA_pblock::find_val_s",
+ "MAX_NVS too small, needs increasing... "
+ "m_nargs= %d, MAX_NVS=%d", m_nargs, MAX_NVS );
+ end = MAX_NVS;
+ }
+
+ for( int i = 0; i < end; i++ ) {
+ if( ( m_nvs[i] == NULL ) ||
+ ( m_nvs[i]->name == NULL ) ||
+ ( m_nvs[i]->value_s == NULL ) ) {
+ continue;
+ }
+
+ /* RA::Debug( LL_PER_PDU, "RA_pblock::find_val_s", */
+ /* "found %s", m_nvs[i]->name ); */
+
+ if( PR_CompareStrings( m_nvs[i]->name, name ) == 1 ) {
+ return m_nvs[i]->value_s;
+ }
+ }
+
+ return NULL;
+}
+
+void RA_pblock::free_pblock()
+{
+ RA::Debug( LL_PER_PDU, "RA_pblock::free_pblock", "in free_pblock" );
+
+ int end = m_nargs;
+
+ if( MAX_NVS < m_nargs ) {
+ RA::Error( "RA_pblock::free_pblock",
+ "MAX_NVS too small, needs increasing... "
+ "m_nargs= %d, MAX_NVS=%d", m_nargs, MAX_NVS );
+ end = MAX_NVS;
+ }
+
+ for( int i = 0; i < end ; i++ ) {
+ if( m_nvs[i] == NULL ) {
+ continue;
+ }
+
+ if( m_nvs[i]->value ) {
+ delete( m_nvs[i]->value );
+ m_nvs[i]->value = NULL;
+ }
+
+ if( m_nvs[i]->value_s ) {
+ delete( m_nvs[i]->value_s );
+ m_nvs[i]->value_s = NULL;
+ }
+
+ if( m_nvs[i]->name != NULL ) {
+ PL_strfree( m_nvs[i]->name );
+ m_nvs[i]->name = NULL;
+ }
+
+ if( m_nvs[i] != NULL ) {
+ PR_Free( m_nvs[i] );
+ m_nvs[i] = NULL;
+ }
+ }
+
+ RA::Debug( LL_PER_PDU, "RA_pblock::free_pblock", "in free_pblock done" );
+}
+
diff --git a/pki/base/tps/src/main/SecureId.cpp b/pki/base/tps/src/main/SecureId.cpp
new file mode 100644
index 000000000..46394100e
--- /dev/null
+++ b/pki/base/tps/src/main/SecureId.cpp
@@ -0,0 +1,71 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include "plstr.h"
+#include "main/SecureId.h"
+#include "main/Memory.h"
+
+/**
+ * Creates a Secure ID object.
+ */
+SecureId::SecureId (char *value, char *pin)
+{
+ if (value == NULL) {
+ m_value = NULL;
+ } else {
+ m_value = PL_strdup(value);
+ }
+ if (pin == NULL) {
+ m_pin = NULL;
+ } else {
+ m_pin = PL_strdup(pin);
+ }
+}
+
+/**
+ * Destructs a Secure ID object.
+ */
+SecureId::~SecureId ()
+{
+ if( m_value != NULL ) {
+ PL_strfree( m_value );
+ m_value = NULL;
+ }
+ if( m_pin != NULL ) {
+ PL_strfree( m_pin );
+ m_pin = NULL;
+ }
+}
+
+/**
+ * Retrieves the optional Secure ID value.
+ */
+char *SecureId::GetValue()
+{
+ return m_value;
+}
+
+/**
+ * Retrieves the Secure ID PIN.
+ */
+char *SecureId::GetPIN()
+{
+ return m_pin;
+}
diff --git a/pki/base/tps/src/main/Util.cpp b/pki/base/tps/src/main/Util.cpp
new file mode 100644
index 000000000..45d52c269
--- /dev/null
+++ b/pki/base/tps/src/main/Util.cpp
@@ -0,0 +1,1139 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation;
+// version 2.1 of the License.
+//
+// This 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor,
+// Boston, MA 02110-1301 USA
+//
+// Copyright (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#include <string.h>
+#include "prmem.h"
+#include "pk11func.h"
+#include "main/Util.h"
+#include "main/Buffer.h"
+#include "engine/RA.h"
+#include "main/Memory.h"
+
+#ifdef XP_WIN32
+#define TPS_PUBLIC __declspec(dllexport)
+#else /* !XP_WIN32 */
+#define TPS_PUBLIC
+#endif /* !XP_WIN32 */
+
+TPS_PUBLIC Util::Util ()
+{
+}
+
+TPS_PUBLIC Util::~Util ()
+{
+}
+
+TPS_PUBLIC int Util::ascii2numeric (char c)
+{
+ int num;
+ switch (c) {
+ case '0': case '1': case '2':case '3':case '4':case '5':
+ case '6': case '7': case '8': case '9':
+ num = c - '0';
+ break;
+ default:
+ num = -1;
+ break;
+ }
+ return num;
+}
+
+static BYTE ZERO[1] = { 0 };
+static BYTE ONE[1] = { 1 };
+
+TPS_PUBLIC BYTE* Util::bool2byte(bool b) {
+ if (b)
+ return ONE;
+ else
+ return ZERO;
+}
+
+static int isAlphaNumeric (char ch)
+{
+ return ((ch >='a') && (ch <= 'z') || /* logical AND &&, OR || */
+ (ch >='A') && (ch <= 'Z') ||
+ (ch >='0') && (ch <= '9') );
+}
+
+static char bin2hex (BYTE ch)
+{
+ ch = ch & 0x0f;
+ ch += '0';
+ if (ch > '9')
+ ch += 7;
+ return (ch);
+}
+
+static BYTE hex2bin (BYTE ch)
+{
+ if (ch > '9')
+ ch = ch - 'A' + 10;
+ else
+ ch = ch - '0';
+ return (ch);
+}
+
+
+TPS_PUBLIC char *Util::SpecialURLEncode(Buffer &data) {
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ char *ret = NULL;
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ sum+=1;
+ } else if (isAlphaNumeric(buf[i])) {
+ sum+=1;
+ } else {
+ sum+=3;
+ }
+ }
+ ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ if (ret == NULL)
+ return NULL;
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ *cur++ = '+';
+ } else if (isAlphaNumeric(buf[i])) {
+ *cur++ = buf[i];
+ } else {
+ *cur++ = '#';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char *Util::URLEncode (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ sum+=1;
+ } else if (isAlphaNumeric(buf[i])) {
+ sum+=1;
+ } else {
+ sum+=3;
+ }
+ }
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ if (buf[i] == ' ') {
+ *cur++ = '+';
+ } else if (isAlphaNumeric(buf[i])) {
+ *cur++ = buf[i];
+ } else {
+ *cur++ = '%';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char *Util::URLEncodeInHex (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ sum+=3;
+ }
+
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ *cur++ = '%';
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC char * Util::URLEncode1(const char *str)
+{
+ int sum = 0;
+ if (str == NULL)
+ return NULL;
+
+ // URL-encode the base-64 encoded public key. This code copies
+ // From input buffer str[] to output buffer encoded_str[]
+ int i = 0;
+ int j = 0;
+ char c;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ sum+=3;
+ } else if (c == '=') {
+ sum+=3;
+ } else if (c == '\r') {
+ sum+=3;
+ } else if (c == '\n') {
+ sum+=3;
+ } else if (c == '+') {
+ sum+=3;
+ } else if (c == '&') {
+ sum+=3;
+ } else if (c == ' ') {
+ sum+=1;
+ } else {
+ sum+=1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+
+ char *encoded_str = (char *)PR_Malloc(sum); //allocate more than we may need
+
+ if (encoded_str == NULL)
+ return NULL;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'F';
+ } else if (c == '&') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = '6';
+ } else if (c == '=') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '3';
+ encoded_str[i] = 'D';
+ } else if (c == '\r') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'D';
+ } else if (c == '\n') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'A';
+ } else if (c == '+') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'B';
+ } else if (c == ' ') {
+ encoded_str[i] = '+';
+ } else {
+ encoded_str[i] = str[j];
+ }
+ if (encoded_str[i] == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+ encoded_str[i] = '\0';
+
+ // DONT print, some of the sensitive information get printed.
+ /*
+ RA::Debug(LL_PER_PDU, "CertEnroll::urlEncode",
+ "URL-encoded encoded_str =%s",encoded_str);
+ */
+
+ return encoded_str;
+}
+/**
+ * this urlEncode function takes a char string
+ */
+TPS_PUBLIC char * Util::URLEncode(const char *str)
+{
+ int sum = 0;
+ if (str == NULL)
+ return NULL;
+
+ // URL-encode the base-64 encoded public key. This code copies
+ // From input buffer str[] to output buffer encoded_str[]
+ int i = 0;
+ int j = 0;
+ char c;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ sum+=3;
+ } else if (c == '=') {
+ sum+=3;
+ } else if (c == '\r') {
+ sum+=3;
+ } else if (c == '\n') {
+ sum+=3;
+ } else if (c == '+') {
+ sum+=3;
+ } else if (c == ' ') {
+ sum+=1;
+ } else {
+ sum+=1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+
+ char *encoded_str = (char *)PR_Malloc(sum); //allocate more than we may need
+
+ if (encoded_str == NULL)
+ return NULL;
+
+ i = 0;
+ j = 0;
+ while (1) {
+ c = str[j];
+ if (c == '/') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'F';
+ } else if (c == '=') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '3';
+ encoded_str[i] = 'D';
+ } else if (c == '\r') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'D';
+ } else if (c == '\n') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '0';
+ encoded_str[i] = 'A';
+ } else if (c == '+') {
+ encoded_str[i++] = '%';
+ encoded_str[i++] = '2';
+ encoded_str[i] = 'B';
+ } else if (c == ' ') {
+ encoded_str[i] = '+';
+ } else {
+ encoded_str[i] = str[j];
+ }
+ if (encoded_str[i] == '\0') {
+ break;
+ }
+ i++;
+ j++;
+ }
+ encoded_str[i] = '\0';
+
+ // DONT print, some of the sensitive information get printed.
+ /*
+ RA::Debug(LL_PER_PDU, "CertEnroll::urlEncode",
+ "URL-encoded encoded_str =%s",encoded_str);
+ */
+
+ return encoded_str;
+}
+
+/* s Format: 01AFEE */
+TPS_PUBLIC Buffer *Util::Str2Buf (const char *s)
+{
+ int len = strlen(s) / 2;
+ BYTE *ret = (BYTE *)PR_Malloc(len);
+ if (ret == NULL)
+ return NULL;
+
+ for (int i = 0; i < len; i ++) {
+ ret[i] = hex2bin(s[i*2]) * 16 + hex2bin(s[i*2+1]);
+ }
+
+ Buffer *newbuf = new Buffer(ret, len);
+ if( ret != NULL ) {
+ PR_Free( ret );
+ ret = NULL;
+ }
+ return newbuf;
+}
+
+TPS_PUBLIC char *Util::Buffer2String (Buffer &data)
+{
+ int i;
+ BYTE *buf = (BYTE*)data;
+ int len = (int)data.size();
+ int sum = 0;
+
+ for (i = 0; i < len; i ++) {
+ sum+=2;
+ }
+ char *ret = (char *)PR_Malloc(sum + 1); // allocate more than we may need
+ if (ret == NULL)
+ return NULL;
+ char *cur = ret;
+
+ for (i = 0; i < len; i ++) {
+ *cur++ = bin2hex(buf[i] >> 4);
+ *cur++ = bin2hex(buf[i]);
+ }
+ *cur = '\0'; // null-terminated
+ return ret;
+}
+
+TPS_PUBLIC Buffer *Util::SpecialURLDecode(const char *data)
+{
+ int i;
+ Buffer buf;
+ Buffer *ret = NULL;
+ int len = strlen(data);
+ BYTE *tmp = NULL;
+ int sum = 0;
+
+ if (len == 0)
+ return NULL;
+ tmp = (BYTE *)malloc(len);
+ if (tmp == NULL)
+ return NULL;
+ for (i = 0; i < len; i++) {
+ if (data[i] == '+') {
+ tmp[sum++] = ' ';
+ } else if (data[i] == '#') {
+ tmp[sum++] = (hex2bin(data[i+1]) << 4) + hex2bin(data[i+2]);
+ i+=2;
+ } else {
+ tmp[sum++] = (BYTE)data[i];
+ }
+ }
+
+ ret = new Buffer(tmp, sum);
+ if( tmp != NULL ) {
+ free( tmp );
+ tmp = NULL;
+ }
+ return ret;
+}
+
+TPS_PUBLIC Buffer *Util::URLDecode(const char *data)
+{
+ int i;
+ Buffer buf;
+ Buffer *ret = NULL;
+ int len = strlen(data);
+ BYTE *tmp = NULL;
+ int sum = 0;
+
+ if (len == 0)
+ return NULL;
+ tmp = (BYTE *)PR_Malloc(len);
+ for (i = 0; i < len; i++) {
+ if (data[i] == '+') {
+ tmp[sum++] = ' ';
+ } else if (data[i] == '%') {
+ tmp[sum++] = (hex2bin(data[i+1]) << 4) + hex2bin(data[i+2]);
+ i+=2;
+ } else {
+ tmp[sum++] = (BYTE)data[i];
+ }
+ }
+
+ ret = new Buffer(tmp, sum);
+ if( tmp != NULL ) {
+ PR_Free( tmp );
+ tmp = NULL;
+ }
+ return ret;
+}
+
+
+TPS_PUBLIC PRStatus Util::GetRandomChallenge(Buffer &random)
+{
+ PRStatus rv = PR_FAILURE;
+ SECStatus status;
+
+ status = PK11_GenerateRandom(random, random.size());
+ if (status != SECSuccess) {
+ goto loser;
+ }
+ rv = PR_SUCCESS;
+loser:
+ return rv;
+} /* GetRandomChallenge */
+
+#define DES2_WORKAROUND
+
+TPS_PUBLIC PK11SymKey *Util::DiversifyKey(PK11SymKey *masterKey, Buffer &data, PK11SlotInfo *slot)
+{
+ PK11SymKey *key = NULL;
+ PRStatus status = PR_FAILURE ;
+ PK11Context *context = NULL;
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ SECItem keyItem = { siBuffer, keyData, sizeof keyData };
+ SECStatus s;
+ int i;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+
+ /* XXX
+ - masterKey could be just a double-length
+ DES Key (16 bytes).
+ - we may need to add the first 8 bytes to
+ the end to make the key 24 bytes long (DES3 Key)
+ */
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT,
+ masterKey,
+ &noParams);
+ if (!context) goto done;
+
+ /* Part 1 */
+ s = PK11_CipherOp(context, &keyData[0], &len, 8, &((BYTE*)data)[0], 8);
+ if (s != SECSuccess) goto done;
+
+ /* Part 2 */
+ s = PK11_CipherOp(context, &keyData[8], &len, 8, &((BYTE*)data)[8], 8);
+ if (s != SECSuccess) goto done;
+
+#ifdef DES2_WORKAROUND
+ /* Part 3 */
+ for(i = 0;i < 8;i++)
+ {
+ keyData[i+16] = keyData[i];
+ }
+#endif
+
+ key = PK11_ImportSymKeyWithFlags(
+ slot,
+ CKM_DES3_ECB,
+ PK11_OriginGenerated,
+ CKA_ENCRYPT,
+ &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+
+ status = PR_SUCCESS;
+
+done:
+
+ return key;
+}
+
+TPS_PUBLIC PRStatus Util::ComputeKeyCheck(const Buffer& newKey, Buffer& output)
+{
+ PK11SymKey *key = NULL;
+ PRStatus status = PR_FAILURE ;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ SECItem keyItem = {siBuffer, keyData, sizeof(keyData) };
+ unsigned char value[8];
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(keyData, newKey, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(keyData+16, newKey, 8);
+#endif
+
+ memset(value, 0, sizeof value);
+
+ key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &keyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! key ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+ s = PK11_CipherOp(context, &value[0], &len, 8, &value[0], 8);
+ if (s != SECSuccess) {
+ goto done;
+ }
+
+ output.resize(3);
+ output.replace(0, value, 3);
+
+ status = PR_SUCCESS;
+done:
+ memset(keyData, 0, sizeof keyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( key != NULL ) {
+ PK11_FreeSymKey( key );
+ key = NULL;
+ }
+
+ return status;
+}
+
+TPS_PUBLIC PRStatus Util::ComputeCryptogram(PK11SymKey *key,
+ const Buffer &card_challenge, const Buffer &host_challenge,
+ Buffer &output)
+{
+ Buffer icv(8, (BYTE)0);
+ Buffer input = card_challenge + host_challenge;
+
+ return ComputeMAC(key, input, icv, output);
+} /* ComputeCryptogram */
+
+
+TPS_PUBLIC PRStatus Util::ComputeMAC(PK11SymKey *key, Buffer &x_input,
+ const Buffer &icv, Buffer &output)
+{
+ PRStatus rv = PR_SUCCESS;
+ PK11Context *context = NULL;
+// NetkeyICV temp;
+ unsigned char result[8];
+ int i;
+ SECStatus s;
+ int len;
+#ifdef USE_DESMAC
+ CK_ULONG macLen = sizeof result;
+ SECItem params = { siBuffer, (unsigned char *)&macLen, sizeof macLen };
+#endif
+ static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char macPad[] = {
+ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+ };
+ BYTE *input = (BYTE *) x_input;
+ int inputLen = x_input.size();
+
+#ifdef USE_DESMAC
+ context = PK11_CreateContextBySymKey(CKM_DES3_MAC_GENERAL, CKA_SIGN,
+ key, &params);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestBegin(context);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestOp(context, icv, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ while(inputLen >= 8)
+ {
+ s = PK11_DigestOp(context, input, 8);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+ for (i = 0;i < inputLen;i++)
+ {
+ result[i] = input[i];
+ }
+
+ input = macPad;
+ for(;i < 8;i++)
+ {
+ result[i] = *input++;
+ }
+
+ s = PK11_DigestOp(context, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+ s = PK11_DigestFinal(context, output, (unsigned int *)&len, sizeof output);
+ if (1 != SECSuccess) { rv = PR_FAILURE; goto done; }
+
+#else
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, key, &noParams);
+ if (!context) { rv = PR_FAILURE; goto done; }
+
+ memcpy(result, icv, sizeof result);
+
+ /* Process whole blocks */
+ while(inputLen >= 8)
+ {
+ for(i = 0;i < 8;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result) /* assert? */
+ {
+ //PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ input += 8;
+ inputLen -= 8;
+ }
+
+ /*
+ * Fold in remaining data (if any)
+ * Set i to number of bytes processed
+ */
+ for(i = 0;i < inputLen;i++)
+ {
+ result[i] ^= input[i];
+ }
+
+ /*
+ * Fill remainder of last block. There
+ * will be at least one byte handled here.
+ */
+ input = macPad;
+ while(i < 8)
+ {
+ result[i] ^= *input++;
+ i++;
+ }
+
+ s = PK11_CipherOp(context, result, &len, sizeof result, result, sizeof result);
+ if (s != SECSuccess) { rv = PR_FAILURE; goto done; }
+ if (len != sizeof result)
+ {
+ //PR_SetError(PR_UNKNOWN_ERROR, 0);
+ rv = PR_FAILURE;
+ goto done;
+ }
+
+ output.replace(0, result, sizeof result);
+#endif
+
+done:
+ if( context != NULL )
+ {
+ PK11_Finalize( context );
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ memset(result, 0, sizeof result);
+
+ return rv;
+} /* ComputeMAC */
+
+TPS_PUBLIC PK11SymKey *Util::DeriveKey(const Buffer& permKey,
+ const Buffer& hostChallenge,
+ const Buffer& cardChallenge)
+{
+ PK11SymKey *key = NULL, *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ unsigned char derivationData[16];
+#ifdef DES2_WORKAROUND
+ unsigned char keyData[24];
+#else
+ unsigned char keyData[16];
+#endif
+ int i;
+ SECStatus s;
+ int len;
+ SECItem keyItem = { siBuffer, keyData, sizeof keyData };
+ static SECItem noParams = { siBuffer, 0, 0 };
+ BYTE masterKeyData[24];
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, permKey, 16);
+ memcpy(masterKeyData+16, permKey, 8);
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! master ) goto done;
+
+ for(i = 0;i < 4;i++)
+ {
+ derivationData[i] = cardChallenge[i+4];
+ derivationData[i+4] = hostChallenge[i];
+ derivationData[i+8] = cardChallenge[i];
+ derivationData[i+12] = hostChallenge[i+4];
+ }
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+ if (!context) goto done;
+
+ /* Part 1 */
+ s = PK11_CipherOp(context, &keyData[0], &len, 8, &derivationData[0], 8);
+ if (s != SECSuccess) goto done;
+
+ /* Part 2 */
+ s = PK11_CipherOp(context, &keyData[8], &len, 8, &derivationData[8], 8);
+ if (s != SECSuccess) goto done;
+
+#ifdef DES2_WORKAROUND
+ /* Part 3 */
+ for(i = 0;i < 8;i++)
+ {
+ keyData[i+16] = keyData[i];
+ }
+#endif
+
+ key = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB, PK11_OriginGenerated,
+ CKA_ENCRYPT, &keyItem, CKF_SIGN | CKF_ENCRYPT, PR_FALSE, 0);
+
+done:
+ memset(keyData, 0, sizeof keyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return key;
+}
+
+/**
+ *
+ * 01
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (AUTH KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (MAC KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ * 81 10 B4 BA A8 9A 8C D0 29 2B 45 21 0E (KEK KEY)
+ * 1B C8 4B 1C 31
+ * 03 8B AF 47
+ *
+ */
+TPS_PUBLIC PRStatus Util::CreateKeySetData(Buffer &newMasterVer, Buffer &old_kek_key, Buffer &new_auth_key, Buffer &new_mac_key, Buffer &new_kek_key, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ Buffer result;
+
+ Buffer encrypted_auth_key(16);
+ Util::EncryptData(old_kek_key, new_auth_key, encrypted_auth_key);
+ Buffer kc_auth_key(3);
+ Util::ComputeKeyCheck(new_auth_key, kc_auth_key);
+ Buffer encrypted_mac_key(16);
+ Util::EncryptData(old_kek_key, new_mac_key, encrypted_mac_key);
+ Buffer kc_mac_key(3);
+ Util::ComputeKeyCheck(new_mac_key, kc_mac_key);
+ Buffer encrypted_kek_key(16);
+ Util::EncryptData(old_kek_key, new_auth_key, encrypted_kek_key);
+ Buffer kc_kek_key(3);
+ Util::ComputeKeyCheck(new_kek_key, kc_kek_key);
+
+ result = newMasterVer +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_auth_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_auth_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_mac_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_mac_key +
+ Buffer(1, (BYTE)0x81) +
+ Buffer(1, (BYTE)0x10) +
+ encrypted_kek_key +
+ Buffer(1, (BYTE)0x03) +
+ kc_kek_key;
+
+ output = result;
+
+ rv = PR_SUCCESS;
+ return rv;
+}
+
+
+/*
+ * for Secure Messaging in Secure Channel
+ */
+TPS_PUBLIC PRStatus Util::EncryptData(PK11SymKey *encSessionKey,
+ Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+ SECStatus s = SECFailure;
+ //static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char d[8] = { 0,0,0,0,0,0,0,0 };
+ static SECItem ivParams = { siBuffer, d, 8 };
+ PK11Context *context = NULL;
+ unsigned char result[8];
+ int len;
+ int i;
+
+ /* this is ECB mode
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, encSessionKey,
+ &noParams);
+ */
+ // use CBC mode
+ context = PK11_CreateContextBySymKey(CKM_DES3_CBC, CKA_ENCRYPT, encSessionKey,
+ &ivParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE*)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+// RA::Debug("Util::EncryptData", "success");
+done:
+
+ //#define VRFY_ENC_SESSION_KEY
+ // fix this to use CBC mode later
+#ifdef VRFY_ENC_SESSION_KEY
+ Buffer enc_key_buffer = Buffer((BYTE *) PK11_GetKeyData(encSessionKey)->data, PK11_GetKeyData(encSessionKey)->len);
+ RA::DebugBuffer("Util::EncryptData", "Verifying Encrypted Data",
+ &output);
+ Buffer out1 = Buffer(16, (BYTE)0);
+ PRStatus status = Util::DecryptData(enc_key_buffer, output, out1);
+ RA::DebugBuffer("Util::EncryptData", "Decrypted Data",
+ &out1);
+#endif
+
+
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+
+ return rv;
+}
+
+
+TPS_PUBLIC PRStatus Util::EncryptData(Buffer &kek_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11SymKey *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char masterKeyData[24];
+#else
+ unsigned char masterKeyData[16];
+#endif
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+ unsigned char result[8];
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, (BYTE*)kek_key, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(masterKeyData+16, (BYTE*)kek_key, 8);
+#endif
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_ENCRYPT, &masterKeyItem,
+ CKF_ENCRYPT, PR_FALSE, 0);
+ if( ! master ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_ENCRYPT, master,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE*)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ memset(masterKeyData, 0, sizeof masterKeyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return rv;
+}
+
+TPS_PUBLIC PRStatus Util::DecryptData(Buffer &kek_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11SymKey *master = NULL;
+ PK11SlotInfo *slot = PK11_GetInternalKeySlot();
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ static SECItem noParams = { siBuffer, 0, 0 };
+#ifdef DES2_WORKAROUND
+ unsigned char masterKeyData[24];
+#else
+ unsigned char masterKeyData[16];
+#endif
+ SECItem masterKeyItem = {siBuffer, masterKeyData, sizeof(masterKeyData) };
+ unsigned char result[8];
+
+ // convert 16-byte to 24-byte triple-DES key
+ memcpy(masterKeyData, (BYTE*)kek_key, 16);
+#ifdef DES2_WORKAROUND
+ memcpy(masterKeyData+16, (BYTE*)kek_key, 8);
+#endif
+
+ master = PK11_ImportSymKeyWithFlags(slot, CKM_DES3_ECB,
+ PK11_OriginGenerated, CKA_DECRYPT, &masterKeyItem,
+ CKF_DECRYPT, PR_FALSE, 0);
+ if( ! master ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_ECB, CKA_DECRYPT, master,
+ &noParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE *)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ memset(masterKeyData, 0, sizeof masterKeyData);
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot );
+ slot = NULL;
+ }
+ if( master != NULL ) {
+ PK11_FreeSymKey( master );
+ master = NULL;
+ }
+
+ return rv;
+}
+
+// this one takes PK11SymKey instead
+TPS_PUBLIC PRStatus Util::DecryptData(PK11SymKey* enc_key, Buffer &input, Buffer &output)
+{
+ PRStatus rv = PR_FAILURE;
+
+ PK11Context *context = NULL;
+ int i;
+ SECStatus s = SECFailure;
+ int len;
+ // static SECItem noParams = { siBuffer, 0, 0 };
+ static unsigned char d[8] = { 0,0,0,0,0,0,0,0 };
+ static SECItem ivParams = { siBuffer, d, 8 };
+ unsigned char result[8];
+
+ if( ! enc_key ) {
+ goto done;
+ }
+
+ context = PK11_CreateContextBySymKey(CKM_DES3_CBC, CKA_DECRYPT, enc_key,
+ &ivParams);
+ if (!context) {
+ goto done;
+ }
+
+ for(i = 0;i < (int)input.size();i += 8) {
+ s = PK11_CipherOp(context, result, &len, 8,
+ (unsigned char *)(((BYTE *)input)+i), 8);
+
+ if (s != SECSuccess) {
+ goto done;
+ }
+ output.replace(i, result, 8);
+ }
+
+ rv = PR_SUCCESS;
+
+done:
+
+ if( context != NULL ) {
+ PK11_DestroyContext( context, PR_TRUE );
+ context = NULL;
+ }
+
+ return rv;
+}
+