summaryrefslogtreecommitdiffstats
path: root/base/symkey/src/com/netscape/symkey/EncryptData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'base/symkey/src/com/netscape/symkey/EncryptData.cpp')
-rw-r--r--base/symkey/src/com/netscape/symkey/EncryptData.cpp250
1 files changed, 250 insertions, 0 deletions
diff --git a/base/symkey/src/com/netscape/symkey/EncryptData.cpp b/base/symkey/src/com/netscape/symkey/EncryptData.cpp
new file mode 100644
index 000000000..ccb817f7c
--- /dev/null
+++ b/base/symkey/src/com/netscape/symkey/EncryptData.cpp
@@ -0,0 +1,250 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include "pk11func.h"
+#include "nspr.h"
+#ifdef __cplusplus
+#include <jni.h>
+#include <assert.h>
+#include <string.h>
+
+}
+#endif
+#include <memory.h>
+#include <assert.h>
+#include <stdio.h>
+#include <cstdarg>
+#include <string>
+#include <stdlib.h>
+#include "Buffer.h"
+#include "SymKey.h"
+#define DES2_WORKAROUND
+
+PRFileDesc *d = NULL;
+
+void GetKeyName(jbyte *keyVersion, char *keyname)
+{
+ int index=0;
+
+ if( !keyname || !keyVersion ||
+ (strlen(keyname) < KEYNAMELENGTH)) {
+ return;
+ }
+
+ if(strlen(masterKeyPrefix)!=0)
+ {
+ index= strlen(masterKeyPrefix);
+ strcpy(keyname,masterKeyPrefix);
+ }
+
+ if( (index + 3) >= KEYNAMELENGTH) {
+ return;
+ }
+
+ keyname[index+0]='#';
+ sprintf(keyname+index+1,"%.2d", keyVersion[0]);
+ keyname[index+3]='#';
+ sprintf(keyname+index+4,"%.2d", keyVersion[1]);
+}
+
+
+extern "C" JNIEXPORT jbyteArray JNICALL Java_com_netscape_symkey_SessionKey_EncryptData
+(JNIEnv *, jclass, jstring, jstring, jbyteArray, jbyteArray, jbyteArray, jbyteArray, jstring, jstring);
+
+extern "C" JNIEXPORT jbyteArray JNICALL
+Java_com_netscape_symkey_SessionKey_EncryptData(JNIEnv * env, jclass this2, jstring j_tokenName, jstring j_keyName, jbyteArray j_in, jbyteArray keyInfo, jbyteArray CUID, jbyteArray kekKeyArray, jstring useSoftToken_s,jstring keySet)
+{
+ jbyte * kek_key = NULL;
+
+ PK11SymKey *masterKey = NULL;
+ PK11SymKey *kekKey = NULL;
+
+ Buffer out = Buffer(KEYLENGTH, (BYTE)0);
+ BYTE kekData[KEYLENGTH];
+ char keyname[KEYNAMELENGTH];
+
+ int status = PR_FAILURE;
+
+ jbyte *cc = NULL;
+ int cc_len = 0;
+ jbyte * cuidValue = NULL;
+
+ if( kekKeyArray != NULL) {
+ kek_key = (jbyte*)(env)->GetByteArrayElements(kekKeyArray, NULL);
+ } else {
+ return NULL;
+ }
+
+ PK11SlotInfo *slot = NULL;
+ PK11SlotInfo *internal = PK11_GetInternalKeySlot();
+
+ Buffer kek_buffer = Buffer((BYTE*)kek_key, KEYLENGTH);
+ char *keySetStringChars = NULL;
+ if( keySet != NULL) {
+ keySetStringChars = (char *) (env)->GetStringUTFChars( keySet, NULL);
+ }
+
+ char *keySetString = keySetStringChars;
+
+ if ( keySetString == NULL ) {
+ keySetString = (char *) DEFKEYSET_NAME;
+ }
+
+ jbyte * keyVersion = NULL;
+ int keyVersion_len = 0;
+ if( keyInfo != NULL) {
+ keyVersion = (jbyte*)(env)->GetByteArrayElements( keyInfo, NULL);
+ if( keyVersion) {
+ keyVersion_len = (env)->GetArrayLength(keyInfo);
+ }
+ }
+
+ if( !keyVersion || (keyVersion_len < 2) ) {
+ goto done;
+ }
+
+ if( CUID != NULL) {
+ cuidValue = (jbyte*)(env)->GetByteArrayElements( CUID, NULL);
+ }
+
+ if( cuidValue == NULL) {
+ goto done;
+ }
+
+ if( j_in != NULL) {
+ cc = (jbyte*)(env)->GetByteArrayElements( j_in, NULL);
+ cc_len = (env)->GetArrayLength(j_in);
+ }
+
+ if( cc == NULL) {
+ goto done;
+ }
+
+ GetDiversificationData(cuidValue,kekData,kek);
+
+ PR_fprintf(PR_STDOUT,"In SessionKey: EncryptData! \n");
+
+ if(j_tokenName != NULL) {
+ char *tokenNameChars = (char *)(env)->GetStringUTFChars(j_tokenName, NULL);
+ slot = ReturnSlot(tokenNameChars);
+ (env)->ReleaseStringUTFChars(j_tokenName, (const char *)tokenNameChars);
+ tokenNameChars = NULL;
+ }
+
+ if(j_keyName != NULL) {
+ char *keyNameChars= (char *)(env)->GetStringUTFChars(j_keyName, NULL);
+ strcpy(keyname,keyNameChars);
+ env->ReleaseStringUTFChars(j_keyName, (const char *)keyNameChars);
+ keyNameChars = NULL;
+ }
+ else {
+ GetKeyName(keyVersion,keyname);
+ }
+
+ if ( (keyVersion[0] == 0x1 && keyVersion[1]== 0x1 && strcmp( keyname, "#01#01") == 0) ||
+ (keyVersion[0] == -1 && strstr(keyname, "#FF") ))
+ {
+ /* default development keyset */
+ Buffer devInput = Buffer((BYTE*)cc, cc_len);
+ Buffer empty = Buffer();
+
+ kekKey = ReturnDeveloperSymKey( internal, (char *) "kek", keySetString, empty);
+
+ if ( kekKey ) {
+ status = EncryptData(Buffer(),kekKey,devInput, out);
+ } else {
+ status = EncryptData(kek_buffer, NULL, devInput, out);
+ }
+ }
+ else
+ {
+ if (slot!=NULL)
+ {
+ masterKey = ReturnSymKey( slot,keyname);
+
+ /* We need to use internal so that the key
+ * can be exported by using PK11_GetKeyData()
+ */
+ if (masterKey != NULL)
+ {
+ kekKey = ComputeCardKeyOnToken(masterKey,kekData);
+ if (kekKey != NULL)
+ {
+ Buffer input = Buffer((BYTE*)cc, cc_len);
+ status = EncryptData(Buffer(), kekKey, input, out);
+ }
+ }
+ }
+ }
+
+done:
+
+ if (masterKey != NULL) {
+ PK11_FreeSymKey( masterKey);
+ masterKey = NULL;
+ }
+
+ if( slot != NULL ) {
+ PK11_FreeSlot( slot);
+ slot = NULL;
+ }
+
+ if( internal != NULL) {
+ PK11_FreeSlot( internal);
+ internal = NULL;
+ }
+
+ if ( kekKey != NULL) {
+ PK11_FreeSymKey( kekKey);
+ kekKey = NULL;
+ }
+
+ if( keySetStringChars ) {
+ (env)->ReleaseStringUTFChars(keySet, (const char *)keySetStringChars);
+ keySetStringChars = NULL;
+ }
+
+ jbyteArray handleBA=NULL;
+ if (status != PR_FAILURE && (out.size()>0) ) {
+ jbyte *handleBytes=NULL;
+ handleBA = (env)->NewByteArray( out.size());
+ handleBytes = (env)->GetByteArrayElements(handleBA, NULL);
+ BYTE* outp = (BYTE*)out;
+ memcpy(handleBytes, outp,out.size());
+ env->ReleaseByteArrayElements( handleBA, handleBytes, 0);
+ handleBytes=NULL;
+ }
+
+ if( cc != NULL) {
+ env->ReleaseByteArrayElements(j_in, cc, JNI_ABORT);
+ }
+
+ if( keyVersion != NULL) {
+ env->ReleaseByteArrayElements(keyInfo, keyVersion, JNI_ABORT);
+ }
+
+ if( cuidValue != NULL) {
+ env->ReleaseByteArrayElements(CUID, cuidValue, JNI_ABORT);
+ }
+
+ return handleBA;
+}