summaryrefslogtreecommitdiffstats
path: root/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'util.c')
-rw-r--r--util.c288
1 files changed, 288 insertions, 0 deletions
diff --git a/util.c b/util.c
new file mode 100644
index 0000000..338b89d
--- /dev/null
+++ b/util.c
@@ -0,0 +1,288 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Netscape security libraries.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1994-2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Rob Crittenden (rcritten@redhat.com)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* cribbed from secutil.c */
+
+#include "prtypes.h"
+#include "prtime.h"
+#include "prlong.h"
+#include "prerror.h"
+#include "prprf.h"
+#include "plgetopt.h"
+#include "prenv.h"
+#include "prnetdb.h"
+#include "base.h"
+#include "base64.h"
+
+#include "cryptohi.h"
+#include "secpkcs7.h"
+#include "secerr.h"
+#include <stdarg.h>
+
+#define CHUNK_SIZE 512
+#define PUT_Object(obj,err) \
+ { \
+ if (count >= size) { \
+ *derlist = *derlist ? \
+ nss_ZREALLOCARRAY(*derlist, SECItem *, \
+ (size+CHUNK_SIZE) ) : \
+ nss_ZNEWARRAY(NULL, SECItem *, \
+ (size+CHUNK_SIZE) ) ; \
+ if ((SECItem **)NULL == *derlist) { \
+ err = CKR_HOST_MEMORY; \
+ goto loser; \
+ } \
+ size += CHUNK_SIZE; \
+ } \
+ (*derlist)[ count ] = (obj); \
+ count++; \
+ }
+
+/* Read certificates from a flat file */
+
+static SECItem *AllocItem(SECItem * item, unsigned int len)
+{
+ SECItem *result = NULL;
+
+ if (item == NULL) {
+ result = nss_ZAlloc(NULL, sizeof(SECItem));
+ if (result == NULL) {
+ goto loser;
+ }
+ } else {
+ PORT_Assert(item->data == NULL);
+ result = item;
+ }
+
+ result->len = len;
+ if (len) {
+ result->data = nss_ZAlloc(NULL, len);
+ }
+
+ return (result);
+
+ loser:
+ if (result != NULL) {
+ SECITEM_FreeItem(result, (item == NULL) ? PR_TRUE : PR_FALSE);
+ }
+ return (NULL);
+}
+
+static SECStatus FileToItem(SECItem * dst, PRFileDesc * src)
+{
+ PRFileInfo info;
+ PRInt32 numBytes;
+ PRStatus prStatus;
+
+ prStatus = PR_GetOpenFileInfo(src, &info);
+
+ if (prStatus != PR_SUCCESS) {
+ return SECFailure;
+ }
+
+ /* XXX workaround for 3.1, not all utils zero dst before sending */
+ dst->data = 0;
+ if (!AllocItem(dst, info.size+1))
+ goto loser;
+
+ numBytes = PR_Read(src, dst->data, info.size);
+ if (numBytes != info.size) {
+ goto loser;
+ }
+
+ return SECSuccess;
+ loser:
+ SECITEM_FreeItem(dst, PR_FALSE);
+ nss_ZFreeIf(dst);
+ return SECFailure;
+}
+
+int
+ReadDERFromFile(SECItem *** derlist, char *filename, PRBool ascii,
+ int *cipher, char **ivstring, PRBool certsonly)
+{
+ SECStatus rv;
+ PRFileDesc *inFile;
+ int count = 0, size = 0;
+ SECItem *der;
+ int error;
+ SECItem filedata;
+ char *c, *iv;
+
+ inFile = PR_Open(filename, PR_RDONLY, 0);
+ if (!inFile)
+ return -1;
+
+ if (ascii) {
+ /* First convert ascii to binary */
+ char *asc, *body;
+
+ /* Read in ascii data */
+ rv = FileToItem(&filedata, inFile);
+ asc = (char *) filedata.data;
+ if (!asc) {
+ PR_Close(inFile);
+ return -1;
+ }
+
+ /* check for headers and trailers and remove them */
+ if ((body = strstr(asc, "-----BEGIN")) != NULL) {
+ int key = 0;
+ while ((asc) && ((body = strstr(asc, "-----BEGIN")) != NULL)) {
+ key = 0;
+ if (strncmp(body, "-----BEGIN RSA PRIVATE KEY", 25) == 0) {
+ key = 1;
+ c = body;
+ body = strchr(body, '\n');
+ body++;
+ if (strncmp(body, "Proc-Type: 4,ENCRYPTED", 22) == 0) {
+ body = strchr(body, '\n');
+ body++;
+ if (strncmp(body, "DEK-Info: ", 10) == 0) {
+ body += 10;
+ c = body;
+ body = strchr(body, ',');
+ if (body == NULL)
+ goto loser;
+ *body = '\0';
+ if (!strcasecmp(c, "DES-EDE3-CBC"))
+ *cipher = NSS_DES_EDE3_CBC;
+ else if (!strcasecmp(c, "DES-CBC"))
+ *cipher = NSS_DES_CBC;
+ else {
+ *cipher = -1;
+ goto loser;
+ }
+ body++;
+ iv = body;
+ body = strchr(body, '\n');
+ if (body == NULL)
+ goto loser;
+ *body = '\0';
+ body++;
+ *ivstring = strdup(iv);
+ }
+ } else { /* Else the private key is not encrypted */
+ *cipher = 0;
+ body = c;
+ }
+ }
+ der = (SECItem *) malloc(sizeof(SECItem));
+
+ char *trailer = NULL;
+ asc = body;
+ body = strchr(body, '\n');
+ if (!body)
+ body = strchr(asc, '\r'); /* maybe this is a MAC file */
+ if (body) {
+ trailer = strstr(++body, "-----END");
+ }
+ if (trailer != NULL) {
+ asc = trailer + 1;
+ *trailer = '\0';
+ } else {
+ goto loser;
+ }
+
+ /* Convert to binary */
+ rv = ATOB_ConvertAsciiToItem(der, body);
+ if (rv) {
+ goto loser;
+ }
+ if ((certsonly && !key) || (!certsonly && key))
+ PUT_Object(der, error);
+ } /* while */
+ } else { /* No headers and footers, translate the blob */
+ der = nss_ZNEW(NULL, SECItem);
+ rv = ATOB_ConvertAsciiToItem(der, asc);
+ if (rv) {
+ goto loser;
+ }
+ }
+
+ nss_ZFreeIf(filedata.data);
+ filedata.data = 0;
+ filedata.len = 0;
+ } else {
+ /* Read in binary der */
+ rv = FileToItem(der, inFile);
+ if (rv) {
+ PR_Close(inFile);
+ return -1;
+ }
+ }
+ PR_Close(inFile);
+ return count;
+
+ loser:
+ if (filedata.len > 0)
+ nss_ZFreeIf(filedata.data);
+ PR_Close(inFile);
+ return -1;
+}
+
+FILE *plogfile;
+
+void open_log()
+{
+#ifdef DEBUG
+ plogfile = fopen("/tmp/pkcs11.log", "a");
+#endif
+
+ return;
+}
+
+void close_log()
+{
+#ifdef DEBUG
+ fclose(plogfile);
+#endif
+ return;
+}
+
+void plog(const char *fmt, ...)
+{
+#ifdef DEBUG
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(plogfile, fmt, ap);
+ va_end(ap);
+
+ fflush(plogfile);
+#endif
+}