>From 9ca6dd3bd19241243eb2a4995402d20385a3978c Mon Sep 17 00:00:00 2001
From: Rich Megginson <rmeggins@redhat.com>
Date: Tue, 14 Jul 2009 12:50:36 -0600
Subject: [PATCH] Fix attrcrypt usage of nsSymmetricKey
 The current attrcrypt is failing because it attempts to store the encryption
 symkey in the nsSymmetricKey attribute.  This attribute is not defined in the
 schema, so it defaults to DirectoryString syntax.  Storing the value then fails
 syntax validation because the binary values in the key do not conform to
 DirectoryString.  The code was poorly designed to handle and report errors of
 this nature.  The real fix is to add nsSymmetricKey as a BINARY syntax
 attribute.  I also cleaned up the error detection and reporting for this case.

---
 ldap/schema/50ns-directory.ldif               |    1 +
 ldap/servers/slapd/back-ldbm/dblayer.c        |    7 ++++-
 ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c |   35 +++++++++++++++++++++---
 3 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/ldap/schema/50ns-directory.ldif b/ldap/schema/50ns-directory.ldif
index 00cced9..943938d 100644
--- a/ldap/schema/50ns-directory.ldif
+++ b/ldap/schema/50ns-directory.ldif
@@ -110,6 +110,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.54 NAME 'replicaUseSSL' DESC 'Netscape d
 attributeTypes: ( 2.16.840.1.113730.3.1.57 NAME 'replicaRoot' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )
 attributeTypes: ( 2.16.840.1.113730.3.1.58 NAME 'replicaBindDn' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 X-ORIGIN 'Netscape Directory Server' )
 attributeTypes: ( 2.16.840.1.113730.3.1.69 NAME 'subtreeACI' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 X-ORIGIN 'Netscape Directory Server 1.0' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2084 NAME 'nsSymmetricKey' DESC 'A symmetric key - currently used by attribute encryption' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VALUE X-ORIGIN 'attribute encryption' )
 objectClasses: ( 2.16.840.1.113730.3.2.23 NAME 'netscapeDirectoryServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass ) X-ORIGIN 'Netscape Directory Server' )
 objectClasses: ( nsDirectoryServer-oid NAME 'nsDirectoryServer' DESC 'Netscape defined objectclass' SUP top MUST ( objectclass $ nsServerID ) MAY ( serverHostName $ nsServerPort $ nsSecureServerPort $ nsBindPassword $ nsBindDN $ nsBaseDN ) X-ORIGIN 'Netscape Directory Server' )
 objectClasses: ( 2.16.840.1.113730.3.2.8 NAME 'ntUser' DESC 'Netscape defined objectclass' SUP top MUST ( ntUserDomainId ) MAY ( description $ l $ ou $ seeAlso $ ntUserPriv $ ntUserHomeDir $ ntUserComment $ ntUserFlags $ ntUserScriptPath $ ntUserAuthFlags $ ntUserUsrComment $ ntUserParms $ ntUserWorkstations $ ntUserLastLogon $ ntUserLastLogoff $ ntUserAcctExpires $ ntUserMaxStorage $ ntUserUnitsPerWeek $ ntUserLogonHours $ ntUserBadPwCount $ ntUserNumLogons $ ntUserLogonServer $ ntUserCountryCode $ ntUserCodePage $ ntUserUniqueId $ ntUserPrimaryGroupId $ ntUserProfile $ ntUserHomeDirDrive $ ntUserPasswordExpired $ ntUserCreateNewAccount $ ntUserDeleteAccount $ ntUniqueId) X-ORIGIN 'Netscape NT Synchronization' )
diff --git a/ldap/servers/slapd/back-ldbm/dblayer.c b/ldap/servers/slapd/back-ldbm/dblayer.c
index 4eeb93c..42642b2 100644
--- a/ldap/servers/slapd/back-ldbm/dblayer.c
+++ b/ldap/servers/slapd/back-ldbm/dblayer.c
@@ -1837,7 +1837,12 @@ int dblayer_instance_start(backend *be, int mode)
         return 0;
     }
 
-    attrcrypt_init(inst);
+    if (attrcrypt_init(inst)) {
+        LDAPDebug(LDAP_DEBUG_ANY,
+                  "Error: unable to initialize attrcrypt system for %s\n",
+                  inst->inst_name, 0, 0);
+        return -1;
+    }
 
     /* Get the name of the directory that holds index files
      * for this instance. */
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
index a37c0ba..763bd2c 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
@@ -209,9 +209,14 @@ attrcrypt_keymgmt_store_key(ldbm_instance *li, attrcrypt_cipher_state *acs, SECK
 		slapi_value_free(&key_value);
 		/* Store the entry */
 		slapi_add_entry_internal_set_pb(pb, e, NULL, li->inst_li->li_identity, 0);
-        	if ((rc = slapi_add_internal_pb(pb)) != LDAP_SUCCESS) {
-            		LDAPDebug(LDAP_DEBUG_ANY, "attrcrypt_keymgmt_store_key: failed to add config key entries to the DSE: %d\n", rc, 0, 0);
-        	}
+		rc = slapi_add_internal_pb(pb);
+		slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &rc);
+		if (rc != LDAP_SUCCESS) {
+			char *resulttext = NULL;
+			slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &resulttext);
+			LDAPDebug(LDAP_DEBUG_ANY, "attrcrypt_keymgmt_store_key: failed to add config key entries to the DSE: %d: %s: %s\n", rc, ldap_err2string(rc), resulttext ? resulttext : "unknown");
+			ret = -1;
+		}
 		if (entry_string) {
 			slapi_ch_free((void**)&entry_string);
 		}
@@ -542,7 +547,7 @@ attrcrypt_get_acs(backend *be, attrcrypt_private *priv)
 #if defined(DEBUG_ATTRCRYPT)
 static void log_bytes(char* format_string, unsigned char *bytes, size_t length)
 {
-	size_t max_length = 20;
+	size_t max_length = 40;
 	size_t truncated_length = (length > max_length) ? max_length : length;
 	size_t x = 0;
 	char *print_buffer = NULL;
@@ -586,7 +591,7 @@ attrcrypt_crypto_op(attrcrypt_private *priv, backend *be, struct attrinfo *ai, c
 	if (encrypt) {
 		LDAPDebug(LDAP_DEBUG_ANY,"attrcrypt_crypto_op encrypt '%s' (%d)\n", in_data, in_size, 0);
 	} else {
-		log_bytes("attrcrypt_crypto_op decrypt '%s' (%d)\n", in_data, in_size);
+		log_bytes("attrcrypt_crypto_op decrypt '%s' (%d)\n", (unsigned char *)in_data, in_size);
 	}
 #endif
 	/* Allocate the output buffer */
@@ -623,15 +628,35 @@ attrcrypt_crypto_op(attrcrypt_private *priv, backend *be, struct attrinfo *ai, c
 		goto error;
 	} else {
 #if defined(DEBUG_ATTRCRYPT)
+		int recurse = 1;
 		if (encrypt) {
 			log_bytes("slapd_pk11_DigestFinal '%s' (%d)\n", output_buffer, output_buffer_size1 + output_buffer_size2);
 		} else {
 			LDAPDebug(LDAP_DEBUG_ANY,"slapd_pk11_DigestFinal '%s', %u\n", output_buffer, output_buffer_size2, 0);
 		}
+		if (*out_size == -1) {
+			recurse = 0;
+		}
 #endif
 		*out_size = output_buffer_size1 + output_buffer_size2;
 		*out_data = (char *)output_buffer;
 		ret = 0; /* success */
+#if defined(DEBUG_ATTRCRYPT)
+		if (recurse) {
+			char *redo_data = NULL;
+			size_t redo_size = -1;
+			int redo_ret;
+
+			LDAPDebug(LDAP_DEBUG_ANY,"------> check result of crypto op\n", 0, 0, 0);
+			redo_ret = attrcrypt_crypto_op(priv, be, ai, *out_data, *out_size, &redo_data, &redo_size, !encrypt);
+			slapi_log_error(SLAPI_LOG_FATAL, "DEBUG_ATTRCRYPT",
+							"orig length %ld redone length %ld\n", in_size, redo_size);
+			log_bytes("DEBUG_ATTRCRYPT orig bytes '%s' (%d)\n", (unsigned char *)in_data, in_size);
+			log_bytes("DEBUG_ATTRCRYPT redo bytes '%s' (%d)\n", (unsigned char *)redo_data, redo_size);
+
+			LDAPDebug(LDAP_DEBUG_ANY,"<------ check result of crypto op\n", 0, 0, 0);
+		}
+#endif
 	}
 error:
 	if (sec_context) {
-- 
1.5.5.6

