⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rsa_nss.c

📁 一个windows上的加解密程式 提供方便的介面让使用者操作
💻 C
📖 第 1 页 / 共 2 页
字号:
/*             NSS keys for the Gaim encryption plugin                    *//*             Copyright (C) 2001 William Tompkins                        *//* This plugin is free software, distributed under the GNU General Public *//* License.                                                               *//* Please see the file "COPYING" distributed with the Gaim source code    *//* for more details                                                       *//*                                                                        *//*                                                                        *//*    This software 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.                             *//*   To compile and use:                                                  *//*     See INSTALL file.                                                  */#include <gdk/gdk.h>#include <gtk/gtk.h>#include <gtk/gtkplug.h>#include <debug.h>#include <gaim.h>#include <gtkdialogs.h>#include "glib/gmain.h"#include <string.h>#include <assert.h>#ifdef _WIN32#include "win32dep.h"#endif#include "rsa_nss.h"#include <nspr.h>#include <nss.h>#include <ssl.h>#include <secmod.h>#include <pk11func.h>#include <keyhi.h>#include <nssb64.h>#include "nls.h"#include "nss_mgf1.h"#include "nss_oaep.h"#include "nss_pss.h"#include "cryptutil.h"#include "keys.h"#include "cryptproto.h"#include "state_ui.h"char* rsa_nss_proto_string="NSS 1.0";crypt_proto* rsa_nss_proto;/*Functions exported through crypt_proto structure */static int              rsa_nss_encrypt(unsigned char**, unsigned char*, int, crypt_key*);static int              rsa_nss_decrypt(unsigned char**, unsigned char*, int, crypt_key*);static int              rsa_nss_sign(unsigned char**, unsigned char*, int, crypt_key*, crypt_key*);static int              rsa_nss_auth(unsigned char**, unsigned char*, int, crypt_key*, const char* name);static crypt_key*       rsa_nss_make_key_from_str(unsigned char *key_str);static GString*         rsa_nss_key_to_gstr(crypt_key* inkey);static unsigned char*   rsa_nss_parseable(unsigned char* key);static crypt_key*       rsa_nss_parse_sent_key(unsigned char *key_str);static GString*         rsa_nss_make_sendable_key(crypt_key* inkey, const char* name);static gchar*           rsa_nss_make_key_id(crypt_key* inkey);void                    rsa_nss_gen_key_pair(crypt_key **, crypt_key **,                                             const char* name, int keysize);static void             rsa_nss_free(crypt_key*);static crypt_key*       rsa_nss_make_pub_from_priv(crypt_key* priv);static int              rsa_nss_calc_unencrypted_size(struct crypt_key*, int);static int              rsa_nss_calc_unsigned_size(struct crypt_key*, int);/* internals */void rsa_nss_test(crypt_key *pub, crypt_key *priv);gboolean rsa_nss_init() {   gboolean nss_loaded_ok = FALSE;  	GaimPlugin *plugin = gaim_plugins_find_with_name("NSS");   if (plugin != NULL) {      nss_loaded_ok = gaim_plugin_is_loaded(plugin);      if (!nss_loaded_ok) {         nss_loaded_ok = gaim_plugin_load(plugin);      }   }   if (!nss_loaded_ok) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Initializing NSS without Gaim support\n");      /* Gaim doesn't seem to have NSS support: try to load it ourselves: */      PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);      NSS_NoDB_Init(NULL);            /* TODO: Fix this so autoconf does the work trying to find this lib. */      SECMOD_AddNewModule("Builtins",#ifndef _WIN32                          LIBDIR "/libnssckbi.so",#else                          "nssckbi.dll",#endif                          0, 0);      NSS_SetDomesticPolicy();      /*       gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", _("Can't load the NSS plugin\n")); */      /*       GE_error_window(_("Gaim was not compiled with the NSS plugin enabled.  " */      /*                       "Gaim-Encryption requires the NSS plugin to function.")); */      /*       return FALSE; */   }   rsa_nss_proto = g_malloc(sizeof(crypt_proto));   crypt_proto_list = g_slist_prepend(crypt_proto_list, rsa_nss_proto);   rsa_nss_proto->encrypt = rsa_nss_encrypt;   rsa_nss_proto->decrypt = rsa_nss_decrypt;   rsa_nss_proto->sign = rsa_nss_sign;   rsa_nss_proto->auth = rsa_nss_auth;         rsa_nss_proto->make_key_from_str = rsa_nss_make_key_from_str;   rsa_nss_proto->key_to_gstr = rsa_nss_key_to_gstr;   rsa_nss_proto->parseable = rsa_nss_parseable;   rsa_nss_proto->parse_sent_key = rsa_nss_parse_sent_key;   rsa_nss_proto->make_sendable_key = rsa_nss_make_sendable_key;   rsa_nss_proto->make_key_id = rsa_nss_make_key_id;   rsa_nss_proto->gen_key_pair = rsa_nss_gen_key_pair;   rsa_nss_proto->free = rsa_nss_free;   rsa_nss_proto->make_pub_from_priv = rsa_nss_make_pub_from_priv;   rsa_nss_proto->calc_unencrypted_size = rsa_nss_calc_unencrypted_size;   rsa_nss_proto->calc_unsigned_size = rsa_nss_calc_unsigned_size;   rsa_nss_proto->name = rsa_nss_proto_string;   return TRUE;}static void rsa_nss_free(crypt_key* key){   if (key->store.rsa_nss.pub) {      SECKEY_DestroyPublicKey(key->store.rsa_nss.pub);      key->store.rsa_nss.pub = 0;   }   if (key->store.rsa_nss.priv) {      SECKEY_DestroyPrivateKey(key->store.rsa_nss.priv);      key->store.rsa_nss.priv = 0;   }}static SECItem*get_random_iv(CK_MECHANISM_TYPE mechType){   int        iv_size = PK11_GetIVLength(mechType);   SECItem   *iv;   SECStatus  rv;       iv = PORT_ZNew(SECItem);   g_assert(iv != 0);   g_assert(iv_size != 0);   iv->data = PORT_NewArray(unsigned char, iv_size);   g_assert(iv->data != 0);   iv->len = iv_size;   rv = PK11_GenerateRandom(iv->data, iv->len);   g_assert(rv == SECSuccess);   return iv;}static void generate_digest(char* digest, SECKEYPublicKey* key) {   SECItem *hash = PK11_MakeIDFromPubKey(&key->u.rsa.modulus);   int i = 0, digestPos = 0;      while (i < hash->len && digestPos < KEY_DIGEST_LENGTH) {      sprintf(digest + digestPos, "%02x", hash->data[i]);      ++i;      digestPos += 2;   }}static void generate_fingerprint(char* print, SECKEYPublicKey* key) {   SECItem *hash = PK11_MakeIDFromPubKey(&key->u.rsa.modulus);   int i;      for (i= 0; i < hash->len - 1; ++i) {      sprintf(print + (3*i), "%02x:", hash->data[i]);   }   sprintf(print + 3 * (hash->len - 1), "%02x", hash->data[(hash->len - 1)]);}static SECKEYPublicKey *copy_public_rsa_key(SECKEYPublicKey *pubk) {   SECKEYPublicKey *copyk;   PRArenaPool *arena;   SECStatus rv;      arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);   g_assert(arena != NULL);      copyk = (SECKEYPublicKey *) PORT_ArenaZAlloc (arena, sizeof (SECKEYPublicKey));   g_assert(copyk != NULL);   copyk->arena = arena;   copyk->keyType = pubk->keyType;   copyk->pkcs11Slot = NULL;   /* go get own reference */   copyk->pkcs11ID = CK_INVALID_HANDLE;      rv = SECITEM_CopyItem(arena, &copyk->u.rsa.modulus,                         &pubk->u.rsa.modulus);   g_assert(rv == SECSuccess);      rv = SECITEM_CopyItem (arena, &copyk->u.rsa.publicExponent,                          &pubk->u.rsa.publicExponent);   g_assert(rv == SECSuccess);      return copyk;}void rsa_nss_gen_key_pair(crypt_key **pub_key, crypt_key **priv_key,                          const char* name, int keysize) {   GtkWidget *status_window, *main_box, *label1, *label2;   char labelText[1000];   PK11RSAGenParams rsaParams;   PK11SlotInfo *slot;   CK_MECHANISM_TYPE multiType[2] = {CKM_RSA_PKCS_KEY_PAIR_GEN, CKM_DES_CBC_PAD};   /* Create the widgets */   GAIM_DIALOG(status_window);   gtk_window_set_wmclass(GTK_WINDOW(status_window), "keygen", "Gaim");   gtk_widget_realize(status_window);   gtk_container_set_border_width(GTK_CONTAINER(status_window), 10);   gtk_widget_set_size_request(status_window, 350, 100);   gtk_window_set_title(GTK_WINDOW(status_window), "Status");   main_box = gtk_vbox_new(FALSE, 0);   gtk_container_add(GTK_CONTAINER(status_window), main_box);   gtk_widget_show(main_box);      g_snprintf(labelText, sizeof(labelText), _("Generating RSA Key Pair for %s"),              name);   label1 = gtk_label_new (labelText);   label2 = gtk_label_new (_("This may take a little bit..."));      gtk_container_add (GTK_CONTAINER (main_box), label1);   gtk_widget_show(label1);   gtk_container_add (GTK_CONTAINER (main_box), label2);   gtk_widget_show(label2);      gtk_widget_show (status_window);   // I don't understand: if I remove one of these   // two loops, the contents of the status window don't   // get drawn.  Hmm...   while (gtk_events_pending()) {      gtk_main_iteration_do(FALSE);   }   gtk_main_iteration();   while (gtk_events_pending()) {      gtk_main_iteration_do(FALSE);   }      *priv_key = g_malloc(sizeof(crypt_key));   rsaParams.keySizeInBits = keysize;   rsaParams.pe = 65537L;     slot = PK11_GetBestSlotMultiple(multiType, 2, 0);      /* Generate "session" (first FALSE), "not sensitive" (next FALSE) key */   (*priv_key)->store.rsa_nss.priv =       PK11_GenerateKeyPair(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &rsaParams,                           &(*priv_key)->store.rsa_nss.pub,                           PR_FALSE, PR_FALSE, 0);   if (!(*priv_key)->store.rsa_nss.priv) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption",                 _("Could not generate key.  NSS Error: %d\n"),                 PORT_GetError());      exit(0);   }   (*priv_key)->proto = rsa_nss_proto;   g_snprintf((*priv_key)->length, sizeof((*priv_key)->length), "%d", keysize);   generate_digest((*priv_key)->digest, (*priv_key)->store.rsa_nss.pub);   generate_fingerprint((*priv_key)->fingerprint, (*priv_key)->store.rsa_nss.pub);   (*pub_key) = rsa_nss_make_pub_from_priv(*priv_key);   gtk_widget_hide(status_window);   gtk_widget_destroy(status_window);}unsigned char* rsa_nss_parseable(unsigned char *key) {   /* If the key is ours, return a pointer to the ':' after our token */   /* otherwise return 0                                              */   /* if we were more sophisticated, we could look for older versions */   /* of our protocol here, and accept them too.                      */   if (strncmp(rsa_nss_proto_string, key, strlen(rsa_nss_proto_string)) == 0) {      return key + strlen(rsa_nss_proto_string);   } else {      return 0;   }}static GString* append_priv_key_to_gstr(GString *str, SECKEYPrivateKey* priv) {   /* for now, we hope that everyone can use DES3.  This is for wrapping   */   /* private keys, which isn't actually secure at this point anyways      */   /* (security provided by the OS: no one else can read/write the keyfile */   const CK_MECHANISM_TYPE SymEncryptionType = CKM_DES3_CBC_PAD;   PK11SlotInfo *symSlot;   PK11SymKey *symKey;   SECItem symKeyItem;  /* storage space for binary key import */   unsigned char symKeyData[24] = {0};    SECItem *iv = NULL;  /* IV for CBC encoding                 */   SECItem exportedKey; /* storage space for exported key */   unsigned char exportedKeyData[5000] = {0};   char* tmpstr;   int errCode;   if (priv == 0) return str;   /* Wrap key using a null symmetric key.  When/If we add password protection to      keys, we can generate the symmetric key from a hashed password instead */   symSlot = PK11_GetBestSlot(SymEncryptionType, NULL);   g_assert(symSlot != 0);      symKeyItem.data = &symKeyData[0];   symKeyItem.len = sizeof(symKeyData);      symKey  = PK11_ImportSymKey(symSlot, PK11_GetKeyGen(SymEncryptionType),                               PK11_OriginUnwrap, CKA_WRAP, &symKeyItem, NULL);      iv = get_random_iv(SymEncryptionType);      exportedKey.len = sizeof(exportedKeyData);   exportedKey.data = exportedKeyData;      errCode = PK11_WrapPrivKey(symSlot, symKey, priv, SymEncryptionType, iv,                              &exportedKey, NULL);   g_assert(errCode == SECSuccess);      g_string_append(str, ",");   tmpstr = NSSBase64_EncodeItem(0, 0, 0, iv);   g_string_append(str, tmpstr);   PORT_Free(tmpstr);      g_string_append(str, ",");      tmpstr = NSSBase64_EncodeItem(0, 0, 0, &exportedKey);   g_string_append(str, tmpstr);   PORT_Free(tmpstr);      g_string_append(str, ",");      PK11_FreeSymKey(symKey);   PORT_Free(iv->data);   PORT_Free(iv);   /* The Base64 routine may have inserted lots of return chars into the string: */   /*   take them out.                                                           */   GE_strip_returns(str);   return str;}static GString* append_pub_key_to_gstr(GString *str, SECKEYPublicKey* pub) {   char *tmpstr;   SECItem *exportedKey;      if (pub == 0) return str;   exportedKey = SECKEY_EncodeDERSubjectPublicKeyInfo(pub);   //   exportedKey = PK11_DEREncodePublicKey(pub);      tmpstr = NSSBase64_EncodeItem(0, 0, 0, exportedKey);   g_string_append(str, tmpstr);   PORT_Free(tmpstr);   PORT_Free(exportedKey->data);   PORT_Free(exportedKey);   /* The Base64 routine may have inserted lots of return chars into the string: take them out. */   GE_strip_returns(str);   return str;}GString* rsa_nss_make_sendable_key(crypt_key* inkey, const char* name) {   GString *outString = g_string_new("");   gchar* nonce_str = GE_new_incoming_nonce(name);   g_string_append(outString, nonce_str);   gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Sending Nonce with key: %s\n", nonce_str);      g_free(nonce_str);   g_string_append(outString, ",");      append_pub_key_to_gstr(outString, inkey->store.rsa_nss.pub);   return outString;}gchar* rsa_nss_make_key_id(crypt_key* inkey) {   return GE_nonce_to_str(&inkey->store.rsa_nss.nonce);}crypt_key* rsa_nss_parse_sent_key(unsigned char *key_str) {   gchar** split_key = g_strsplit(key_str, ",", 2);   crypt_key* key;      if ((split_key[0] == 0) || (split_key[1] == 0)) {      gaim_debug(GAIM_DEBUG_ERROR, "gaim-encryption", "Error parsing RSANSS nonce/key\n");      return 0;   }      key = rsa_nss_make_key_from_str(split_key[1]);   if (key == 0) return 0;   GE_str_to_nonce(&key->store.rsa_nss.nonce, split_key[0]);   gaim_debug(GAIM_DEBUG_INFO, "gaim-encryption", "Received Nonce with key: %s\n", split_key[0]);   g_strfreev(split_key);   return key;}GString* rsa_nss_key_to_gstr(crypt_key* inkey) {   GString *outString = g_string_new("");      append_pub_key_to_gstr(outString, inkey->store.rsa_nss.pub);   append_priv_key_to_gstr(outString, inkey->store.rsa_nss.priv);   return outString;}crypt_key* rsa_nss_make_key_from_str(unsigned char *key_str){   gchar **split_key;   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -