示例#1
0
/* generate KEYS -- as per PKCS12 section 7.
 * only used for MAC
 */
SECItem *
sec_pkcs12_generate_key_from_password(SECOidTag algorithm,
                                      SECItem *salt,
                                      SECItem *password)
{
    unsigned char *pre_hash = NULL;
    unsigned char *hash_dest = NULL;
    SECStatus res;
    PLArenaPool *poolp;
    SECItem *key = NULL;
    int key_len = 0;

    if ((salt == NULL) || (password == NULL)) {
        return NULL;
    }

    poolp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (poolp == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return NULL;
    }

    pre_hash = (unsigned char *)PORT_ArenaZAlloc(poolp, sizeof(char) *
                                                            (salt->len + password->len));
    if (pre_hash == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    hash_dest = (unsigned char *)PORT_ArenaZAlloc(poolp,
                                                  sizeof(unsigned char) * SHA1_LENGTH);
    if (hash_dest == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    PORT_Memcpy(pre_hash, salt->data, salt->len);
    /* handle password of 0 length case */
    if (password->len > 0) {
        PORT_Memcpy(&(pre_hash[salt->len]), password->data, password->len);
    }

    res = PK11_HashBuf(SEC_OID_SHA1, hash_dest, pre_hash,
                       (salt->len + password->len));
    if (res == SECFailure) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto loser;
    }

    switch (algorithm) {
        case SEC_OID_SHA1:
            if (key_len == 0)
                key_len = 16;
            key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
            if (key == NULL) {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                goto loser;
            }
            key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) * key_len);
            if (key->data == NULL) {
                PORT_SetError(SEC_ERROR_NO_MEMORY);
                goto loser;
            }
            key->len = key_len;
            PORT_Memcpy(key->data, &hash_dest[SHA1_LENGTH - key->len], key->len);
            break;
        default:
            goto loser;
            break;
    }

    PORT_FreeArena(poolp, PR_TRUE);
    return key;

loser:
    PORT_FreeArena(poolp, PR_TRUE);
    if (key != NULL) {
        SECITEM_ZfreeItem(key, PR_TRUE);
    }
    return NULL;
}
示例#2
0
文件: sign.c 项目: emilio/gecko-dev
/*
 *  g e n e r a t e _ S F _ f i l e
 *
 *  From the supplied manifest file, calculates
 *  digests on the various sections, creating a .SF
 *  file in the process.
 *
 */
static int
generate_SF_file(char *manifile, char *who)
{
    FILE *sf;
    FILE *mf;
    long r1, r2, r3;
    char whofile[FNSIZE];
    char *buf, *name = NULL;
    JAR_Digest dig;
    int line = 0;

    strcpy(whofile, who);

    if ((mf = fopen(manifile, "rb")) == NULL) {
        perror(manifile);
        exit(ERRX);
    }

    if ((sf = fopen(whofile, "wb")) == NULL) {
        perror(who);
        exit(ERRX);
    }

    buf = (char *)PORT_ZAlloc(BUFSIZ);

    if (buf)
        name = (char *)PORT_ZAlloc(BUFSIZ);

    if (buf == NULL || name == NULL)
        out_of_memory();

    fprintf(sf, "Signature-Version: 1.0\n");
    fprintf(sf, "Created-By: %s\n", CREATOR);
    fprintf(sf, "Comments: %s\n", BREAKAGE);

    if (fgets(buf, BUFSIZ, mf) == NULL) {
        PR_fprintf(errorFD, "%s: empty manifest file!\n", PROGRAM_NAME);
        errorCount++;
        exit(ERRX);
    }

    if (strncmp(buf, "Manifest-Version:", 17)) {
        PR_fprintf(errorFD, "%s: not a manifest file!\n", PROGRAM_NAME);
        errorCount++;
        exit(ERRX);
    }

    fseek(mf, 0L, SEEK_SET);

    /* Process blocks of headers, and calculate their hashen */

    while (1) {
        /* Beginning range */
        r1 = ftell(mf);

        if (fgets(name, BUFSIZ, mf) == NULL)
            break;

        line++;

        if (r1 != 0 && strncmp(name, "Name:", 5)) {
            PR_fprintf(errorFD,
                       "warning: unexpected input in manifest file \"%s\" at line %d:\n",
                       manifile, line);
            PR_fprintf(errorFD, "%s\n", name);
            warningCount++;
        }

        r2 = r1;
        while (fgets(buf, BUFSIZ, mf)) {
            if (*buf == 0 || *buf == '\n' || *buf == '\r')
                break;

            line++;

            /* Ending range for hashing */
            r2 = ftell(mf);
        }

        r3 = ftell(mf);

        if (r1) {
            fprintf(sf, "\n");
            fprintf(sf, "%s", name);
        }

        calculate_MD5_range(mf, r1, r2, &dig);

        if (optimize == 0) {
            fprintf(sf, "Digest-Algorithms: MD5 SHA1\n");
            fprintf(sf, "MD5-Digest: %s\n",
                    BTOA_DataToAscii(dig.md5, MD5_LENGTH));
        }

        fprintf(sf, "SHA1-Digest: %s\n",
                BTOA_DataToAscii(dig.sha1, SHA1_LENGTH));

        /* restore normalcy after changing offset position */
        fseek(mf, r3, SEEK_SET);
    }

    PORT_Free(buf);
    PORT_Free(name);

    fclose(sf);
    fclose(mf);

    return 0;
}
char *
crypto_encrypt (const char *cipher,
                const GByteArray *data,
                const char *iv,
                gsize iv_len,
                const char *key,
                gsize key_len,
                gsize *out_len,
                GError **error)
{
	SECStatus ret;
	CK_MECHANISM_TYPE cipher_mech = CKM_DES3_CBC_PAD;
	PK11SlotInfo *slot = NULL;
	SECItem key_item = { .data = (unsigned char *) key, .len = key_len };
	SECItem iv_item = { .data = (unsigned char *) iv, .len = iv_len };
	PK11SymKey *sym_key = NULL;
	SECItem *sec_param = NULL;
	PK11Context *ctx = NULL;
	unsigned char *output, *padded_buf;
	gsize output_len;
	int encrypted_len = 0, i;
	gboolean success = FALSE;
	gsize padded_buf_len, pad_len;

	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
		cipher_mech = CKM_DES3_CBC_PAD;
	else {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_UNKNOWN_CIPHER,
		             _("Private key cipher '%s' was unknown."),
		             cipher);
		return NULL;
	}

	/* If data->len % ivlen == 0, then we add another complete block
	 * onto the end so that the decrypter knows there's padding.
	 */
	pad_len = iv_len - (data->len % iv_len);
	output_len = padded_buf_len = data->len + pad_len;
	padded_buf = g_malloc0 (padded_buf_len);

	memcpy (padded_buf, data->data, data->len);
	for (i = 0; i < pad_len; i++)
		padded_buf[data->len + i] = (guint8) (pad_len & 0xFF);

	output = g_malloc0 (output_len);
	if (!output) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_OUT_OF_MEMORY,
		             _("Could not allocate memory for encrypting."));
		return NULL;
	}

	slot = PK11_GetBestSlot (cipher_mech, NULL);
	if (!slot) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_INIT_FAILED,
		             _("Failed to initialize the encryption cipher slot."));
		goto out;
	}

	sym_key = PK11_ImportSymKey (slot, cipher_mech, PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL);
	if (!sym_key) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_SET_KEY_FAILED,
		             _("Failed to set symmetric key for encryption."));
		goto out;
	}

	sec_param = PK11_ParamFromIV (cipher_mech, &iv_item);
	if (!sec_param) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_SET_IV_FAILED,
		             _("Failed to set IV for encryption."));
		goto out;
	}

	ctx = PK11_CreateContextBySymKey (cipher_mech, CKA_ENCRYPT, sym_key, sec_param);
	if (!ctx) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_INIT_FAILED,
		             _("Failed to initialize the encryption context."));
		goto out;
	}

	ret = PK11_CipherOp (ctx, output, &encrypted_len, output_len, padded_buf, padded_buf_len);
	if (ret != SECSuccess) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_ENCRYPT_FAILED,
		             _("Failed to encrypt: %d."),
		             PORT_GetError ());
		goto out;
	}

	if (encrypted_len != output_len) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_ENCRYPT_FAILED,
		             _("Unexpected amount of data after encrypting."));
		goto out;
	}

	*out_len = encrypted_len;
	success = TRUE;

out:
	if (ctx)
		PK11_DestroyContext (ctx, PR_TRUE);
	if (sym_key)
		PK11_FreeSymKey (sym_key);
	if (sec_param)
		SECITEM_FreeItem (sec_param, PR_TRUE);
	if (slot)
		PK11_FreeSlot (slot);

	if (padded_buf) {
		memset (padded_buf, 0, padded_buf_len);
		g_free (padded_buf);
		padded_buf = NULL;
	}

	if (!success) {
		memset (output, 0, output_len);
		g_free (output);
		output = NULL;
	}
	return (char *) output;
}

NMCryptoFileFormat
crypto_verify_cert (const unsigned char *data,
                    gsize len,
                    GError **error)
{
	CERTCertificate *cert;

	/* Try DER/PEM first */
	cert = CERT_DecodeCertFromPackage ((char *) data, len);
	if (!cert) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CERT_FORMAT_INVALID,
		             _("Couldn't decode certificate: %d"),
		             PORT_GetError());
		return NM_CRYPTO_FILE_FORMAT_UNKNOWN;
	}

	CERT_DestroyCertificate (cert);
	return NM_CRYPTO_FILE_FORMAT_X509;
}

gboolean
crypto_verify_pkcs12 (const GByteArray *data,
                      const char *password,
                      GError **error)
{
	SEC_PKCS12DecoderContext *p12ctx = NULL;
	SECItem pw = { 0 };
	PK11SlotInfo *slot = NULL;
	SECStatus s;
	char *ucs2_password;
	glong ucs2_chars = 0;
#ifndef WORDS_BIGENDIAN
	guint16 *p;
#endif /* WORDS_BIGENDIAN */

	if (error)
		g_return_val_if_fail (*error == NULL, FALSE);

	/* PKCS#12 passwords are apparently UCS2 BIG ENDIAN, and NSS doesn't do
	 * any conversions for us.
	 */
	if (password && strlen (password)) {
		ucs2_password = (char *) g_utf8_to_utf16 (password, strlen (password), NULL, &ucs2_chars, NULL);
		if (!ucs2_password || !ucs2_chars) {
			g_set_error (error, NM_CRYPTO_ERROR,
			             NM_CRYPTO_ERR_INVALID_PASSWORD,
			             _("Couldn't convert password to UCS2: %d"),
			             PORT_GetError());
			return FALSE;
		}

		ucs2_chars *= 2;  /* convert # UCS2 characters -> bytes */
		pw.data = PORT_ZAlloc(ucs2_chars + 2);
		memcpy (pw.data, ucs2_password, ucs2_chars);
		pw.len = ucs2_chars + 2;  /* include terminating NULL */

		memset (ucs2_password, 0, ucs2_chars);
		g_free (ucs2_password);

#ifndef WORDS_BIGENDIAN
		for (p = (guint16 *) pw.data; p < (guint16 *) (pw.data + pw.len); p++)
			*p = GUINT16_SWAP_LE_BE (*p);
#endif /* WORDS_BIGENDIAN */
	} else {
		/* NULL password */
		pw.data = NULL;
		pw.len = 0;
	}

	slot = PK11_GetInternalKeySlot();
	p12ctx = SEC_PKCS12DecoderStart (&pw, slot, NULL, NULL, NULL, NULL, NULL, NULL);
	if (!p12ctx) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_DECODE_FAILED,
		             _("Couldn't initialize PKCS#12 decoder: %d"),
		             PORT_GetError());
		goto error;
	}

	s = SEC_PKCS12DecoderUpdate (p12ctx, data->data, data->len);
	if (s != SECSuccess) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_FILE_FORMAT_INVALID,
		             _("Couldn't decode PKCS#12 file: %d"),
		             PORT_GetError());
		goto error;
	}

	s = SEC_PKCS12DecoderVerify (p12ctx);
	if (s != SECSuccess) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERR_CIPHER_DECRYPT_FAILED,
		             _("Couldn't verify PKCS#12 file: %d"),
		             PORT_GetError());
		goto error;
	}

	SEC_PKCS12DecoderFinish (p12ctx);
	SECITEM_ZfreeItem (&pw, PR_FALSE);
	return TRUE;

error:
	if (p12ctx)
		SEC_PKCS12DecoderFinish (p12ctx);

	if (slot)
		PK11_FreeSlot(slot);

	SECITEM_ZfreeItem (&pw, PR_FALSE);
	return FALSE;
}
示例#4
0
char *getNSSPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
{
     secuPWData *pwdInfo = (secuPWData *)arg;
     PRFileDesc *fd;
     PRInt32 nb; /*number of bytes*/
     char* password; 
     char* strings;
     char* token=NULL;
     const long maxPwdFileSize = NSSpwdfilesize;
     int i, tlen=0;

     if (slot) {
     token = PK11_GetTokenName(slot);
         if (token) {
         tlen = PORT_Strlen(token);
	 /* libreswan_log("authentication needed for token name %s with length %d",token,tlen); */
         }
	 else {
		return 0;
	 }
     }
     else {
	return 0;
     }

     if(retry) return 0;

     strings=PORT_ZAlloc(maxPwdFileSize);
     if(!strings) {
     libreswan_log("Not able to allocate memory for reading NSS password file");
     return 0;
     }

     
     if(pwdInfo->source == PW_FROMFILE) {
     	if(pwdInfo->data !=NULL) {
            fd = PR_Open(pwdInfo->data, PR_RDONLY, 0);
	    if (!fd) {
	    PORT_Free(strings);
	    libreswan_log("No password file \"%s\" exists.", pwdInfo->data);
	    return 0;
	    }

	    nb = PR_Read(fd, strings, maxPwdFileSize);
	    PR_Close(fd);

	    if (nb == 0) {
            libreswan_log("password file contains no data");
            PORT_Free(strings);
            return 0;
            }

            i = 0;
            do
            {
               int start = i;
               int slen;

               while (strings[i] != '\r' && strings[i] != '\n' && i < nb) i++;
               strings[i++] = '\0';

               while ( (i<nb) && (strings[i] == '\r' || strings[i] == '\n')) {
               strings[i++] = '\0';
               }

               password = &strings[start];

               if (PORT_Strncmp(password, token, tlen)) continue;
               slen = PORT_Strlen(password);

               if (slen < (tlen+1)) continue;
               if (password[tlen] != ':') continue;
               password = &password[tlen+1];
               break;

            } while (i<nb);

            password = PORT_Strdup((char*)password);
            PORT_Free(strings);

            /* libreswan_log("Password passed to NSS is %s with length %d", password, PORT_Strlen(password)); */
            return password;
	}
	else {
	libreswan_log("File with Password to NSS DB is not provided");
        return 0;
	}
     }

libreswan_log("nss password source is not specified as file");
return 0;
}
示例#5
0
static int
nss_cms_recipients_traverse(NSSCMSRecipientInfo **recipientinfos, NSSCMSRecipient **recipient_list)
{
    int count = 0;
    int rlindex = 0;
    int i, j;
    NSSCMSRecipient *rle;
    NSSCMSRecipientInfo *ri;
    NSSCMSRecipientEncryptedKey *rek;

    for (i = 0; recipientinfos[i] != NULL; i++) {
        ri = recipientinfos[i];
        switch (ri->recipientInfoType) {
        case NSSCMSRecipientInfoID_KeyTrans:
            if (recipient_list) {
                NSSCMSRecipientIdentifier *recipId =
                    &ri->ri.keyTransRecipientInfo.recipientIdentifier;

                if (recipId->identifierType != NSSCMSRecipientID_IssuerSN &&
                        recipId->identifierType != NSSCMSRecipientID_SubjectKeyID) {
                    PORT_SetError(SEC_ERROR_INVALID_ARGS);
                    return -1;
                }
                /* alloc one & fill it out */
                rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
                if (!rle)
                    return -1;

                rle->riIndex = i;
                rle->subIndex = -1;
                switch (recipId->identifierType) {
                case NSSCMSRecipientID_IssuerSN:
                    rle->kind = RLIssuerSN;
                    rle->id.issuerAndSN = recipId->id.issuerAndSN;
                    break;
                case NSSCMSRecipientID_SubjectKeyID:
                    rle->kind = RLSubjKeyID;
                    rle->id.subjectKeyID = recipId->id.subjectKeyID;
                    break;
                default: /* we never get here because of identifierType check
                            we done before. Leaving it to kill compiler warning */
                    break;
                }
                recipient_list[rlindex++] = rle;
            } else {
                count++;
            }
            break;
        case NSSCMSRecipientInfoID_KeyAgree:
            if (ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys == NULL)
                break;
            for (j=0; ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j] != NULL; j++) {
                if (recipient_list) {
                    rek = ri->ri.keyAgreeRecipientInfo.recipientEncryptedKeys[j];
                    /* alloc one & fill it out */
                    rle = (NSSCMSRecipient *)PORT_ZAlloc(sizeof(NSSCMSRecipient));
                    if (!rle)
                        return -1;

                    rle->riIndex = i;
                    rle->subIndex = j;
                    switch (rek->recipientIdentifier.identifierType) {
                    case NSSCMSKeyAgreeRecipientID_IssuerSN:
                        rle->kind = RLIssuerSN;
                        rle->id.issuerAndSN = rek->recipientIdentifier.id.issuerAndSN;
                        break;
                    case NSSCMSKeyAgreeRecipientID_RKeyID:
                        rle->kind = RLSubjKeyID;
                        rle->id.subjectKeyID = rek->recipientIdentifier.id.recipientKeyIdentifier.subjectKeyIdentifier;
                        break;
                    }
                    recipient_list[rlindex++] = rle;
                } else {
                    count++;
                }
            }
            break;
        case NSSCMSRecipientInfoID_KEK:
            /* KEK is not implemented */
            break;
        }
    }
    /* if we have a recipient list, we return on success (-1, above, on failure) */
    /* otherwise, we return the count. */
    if (recipient_list) {
        recipient_list[rlindex] = NULL;
        return 0;
    } else {
        return count;
    }
}
示例#6
0
/*
 * NSS_CMSCipherContext_StartDecrypt - create a cipher context to do decryption
 * based on the given bulk encryption key and algorithm identifier (which 
 * may include an iv).
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function below (for starting up encryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
NSSCMSCipherContext *
NSS_CMSCipherContext_StartDecrypt(PK11SymKey *key, SECAlgorithmID *algid)
{
    NSSCMSCipherContext *cc;
    void *ciphercx;
    CK_MECHANISM_TYPE cryptoMechType;
    PK11SlotInfo *slot;
    SECOidTag algtag;
    SECItem *param = NULL;

    algtag = SECOID_GetAlgorithmTag(algid);

    /* set param and mechanism */
    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	SECItem *pwitem;

	pwitem = PK11_GetSymKeyUserData(key);
	if (!pwitem) 
	    return NULL;

	cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
	if (cryptoMechType == CKM_INVALID_MECHANISM) {
	    SECITEM_FreeItem(param,PR_TRUE);
	    return NULL;
	}

    } else {
	cryptoMechType = PK11_AlgtagToMechanism(algtag);
	if ((param = PK11_ParamFromAlgid(algid)) == NULL)
	    return NULL;
    }

    cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext));
    if (cc == NULL) {
	SECITEM_FreeItem(param,PR_TRUE);
	return NULL;
    }

    /* figure out pad and block sizes */
    cc->pad_size = PK11_GetBlockSize(cryptoMechType, param);
    slot = PK11_GetSlotFromKey(key);
    cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
    PK11_FreeSlot(slot);

    /* create PK11 cipher context */
    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_DECRYPT, 
					  key, param);
    SECITEM_FreeItem(param, PR_TRUE);
    if (ciphercx == NULL) {
	PORT_Free (cc);
	return NULL;
    }

    cc->cx = ciphercx;
    cc->doit =  (nss_cms_cipher_function) PK11_CipherOp;
    cc->destroy = (nss_cms_cipher_destroy) PK11_DestroyContext;
    cc->encrypt = PR_FALSE;
    cc->pending_count = 0;

    return cc;
}
示例#7
0
/*
 * NSS_CMSCipherContext_StartEncrypt - create a cipher object to do encryption,
 * based on the given bulk encryption key and algorithm tag.  Fill in the 
 * algorithm identifier (which may include an iv) appropriately.
 *
 * XXX Once both are working, it might be nice to combine this and the
 * function above (for starting up decryption) into one routine, and just
 * have two simple cover functions which call it. 
 */
NSSCMSCipherContext *
NSS_CMSCipherContext_StartEncrypt(PRArenaPool *poolp, PK11SymKey *key, SECAlgorithmID *algid)
{
    NSSCMSCipherContext *cc;
    void *ciphercx;
    SECStatus rv;
    CK_MECHANISM_TYPE cryptoMechType;
    PK11SlotInfo *slot;
    SECItem *param = NULL;
    PRBool needToEncodeAlgid = PR_FALSE;
    SECOidTag algtag = SECOID_GetAlgorithmTag(algid);

    /* set param and mechanism */
    if (SEC_PKCS5IsAlgorithmPBEAlg(algid)) {
	SECItem *pwitem;

	pwitem = PK11_GetSymKeyUserData(key);
	if (!pwitem) 
	    return NULL;

	cryptoMechType = PK11_GetPBECryptoMechanism(algid, &param, pwitem);
	if (cryptoMechType == CKM_INVALID_MECHANISM) {
	    SECITEM_FreeItem(param,PR_TRUE);
	    return NULL;
	}
    } else {
	cryptoMechType = PK11_AlgtagToMechanism(algtag);
	if ((param = PK11_GenerateNewParam(cryptoMechType, key)) == NULL)
	    return NULL;
	needToEncodeAlgid = PR_TRUE;
    }

    cc = (NSSCMSCipherContext *)PORT_ZAlloc(sizeof(NSSCMSCipherContext));
    if (cc == NULL) {
	goto loser;
    }

    /* now find pad and block sizes for our mechanism */
    cc->pad_size = PK11_GetBlockSize(cryptoMechType, param);
    slot = PK11_GetSlotFromKey(key);
    cc->block_size = PK11_IsHW(slot) ? BLOCK_SIZE : cc->pad_size;
    PK11_FreeSlot(slot);

    /* and here we go, creating a PK11 cipher context */
    ciphercx = PK11_CreateContextBySymKey(cryptoMechType, CKA_ENCRYPT, 
					  key, param);
    if (ciphercx == NULL) {
	PORT_Free(cc);
	cc = NULL;
	goto loser;
    }

    /*
     * These are placed after the CreateContextBySymKey() because some
     * mechanisms have to generate their IVs from their card (i.e. FORTEZZA).
     * Don't move it from here.
     * XXX is that right? the purpose of this is to get the correct algid
     *     containing the IVs etc. for encoding. this means we need to set this up
     *     BEFORE encoding the algid in the contentInfo, right?
     */
    if (needToEncodeAlgid) {
	rv = PK11_ParamToAlgid(algtag, param, poolp, algid);
	if(rv != SECSuccess) {
	    PORT_Free(cc);
	    cc = NULL;
	    goto loser;
	}
    }

    cc->cx = ciphercx;
    cc->doit = (nss_cms_cipher_function)PK11_CipherOp;
    cc->destroy = (nss_cms_cipher_destroy)PK11_DestroyContext;
    cc->encrypt = PR_TRUE;
    cc->pending_count = 0;

loser:
    SECITEM_FreeItem(param, PR_TRUE);

    return cc;
}
示例#8
0
/****************************************************************
 *
 * J z i p A d d
 *
 * Adds a new file into a ZIP file.  The ZIP file must have already
 * been opened with JzipOpen.
 */
int
JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int compression_level)
{
    ZIPentry * entry;
    PRFileDesc * readfp;
    PRFileDesc * zipfp;
    unsigned long crc;
    unsigned long local_size_pos;
    int	          num;
    int	          err;
    int	          deflate_percent;
    z_stream      zstream;
    Bytef         inbuf[BUFSIZ];
    Bytef         outbuf[BUFSIZ];


    if ( !fullname || !filename || !zipfile) {
	return - 1;
    }

    zipfp = zipfile->fp;
    if (!zipfp)
	return - 1;


    if ( (readfp = PR_Open(fullname, PR_RDONLY, 0777)) == NULL) {
	char	*nsprErr;
	if (PR_GetErrorTextLength()) {
	    nsprErr = PR_Malloc(PR_GetErrorTextLength());
	    PR_GetErrorText(nsprErr);
	} else {
	    nsprErr = NULL;
	}
	PR_fprintf(errorFD, "%s: %s\n", fullname, nsprErr ? nsprErr :
	    "");
	errorCount++;
	if (nsprErr) 
	    PR_Free(nsprErr);
	exit(ERRX);
    }

    /*
     * Make sure the input file is not the output file.
     * Add a few bytes to the end of the JAR file and see if the input file
     * twitches
     */
     {
	PRInt32 endOfJar;
	PRInt32 inputSize;
	PRBool isSame;

	inputSize = PR_Available(readfp);

	endOfJar = PR_Seek(zipfp, 0L, PR_SEEK_CUR);

	if (PR_Write(zipfp, "abcde", 5) < 5) {
	    char	*nsprErr;

	    if (PR_GetErrorTextLength()) {
		nsprErr = PR_Malloc(PR_GetErrorTextLength());
		PR_GetErrorText(nsprErr);
	    } else {
		nsprErr = NULL;
	    }
	    PR_fprintf(errorFD, "Writing to zip file: %s\n",
	        nsprErr ? nsprErr : "");
	    if (nsprErr) 
		PR_Free(nsprErr);
	    errorCount++;
	    exit(ERRX);
	}

	isSame = (PR_Available(readfp) != inputSize);

	PR_Seek(zipfp, endOfJar, PR_SEEK_SET);

	if (isSame) {
	    /* It's the same file! Forget it! */
	    PR_Close(readfp);
	    return 0;
	}
    }

    if (verbosity >= 0) {
	PR_fprintf(outputFD, "adding %s to %s...", fullname, zipfile->filename);
    }

    entry = PORT_ZAlloc(sizeof(ZIPentry));
    if (!entry) 
	out_of_memory();

    entry->filename = PORT_Strdup(filename);
    entry->comment = NULL;

    /* Set up local file header */
    longtox(LSIG, entry->local.signature);
    inttox(strlen(filename), entry->local.filename_len);
    inttox(zipfile->time, entry->local.time);
    inttox(zipfile->date, entry->local.date);
    inttox(Z_DEFLATED, entry->local.method);

    /* Set up central directory entry */
    longtox(CSIG, entry->central.signature);
    inttox(strlen(filename), entry->central.filename_len);
    if (entry->comment) {
	inttox(strlen(entry->comment), entry->central.commentfield_len);
    }
    longtox(PR_Seek(zipfile->fp, 0, PR_SEEK_CUR),
        entry->central.localhdr_offset);
    inttox(zipfile->time, entry->central.time);
    inttox(zipfile->date, entry->central.date);
    inttox(Z_DEFLATED, entry->central.method);

    /* Compute crc.  Too bad we have to process the whole file to do this*/
    crc = crc32(0L, NULL, 0);
    while ( (num = PR_Read(readfp, inbuf, BUFSIZ)) > 0) {
	crc = crc32(crc, inbuf, num);
    }
    PR_Seek(readfp, 0L, PR_SEEK_SET);

    /* Store CRC */
    longtox(crc, entry->local.crc32);
    longtox(crc, entry->central.crc32);

    /* Stick this entry onto the end of the list */
    entry->next = NULL;
    if ( zipfile->list == NULL ) {
	/* First entry */
	zipfile->list = entry;
    } else {
	ZIPentry * pe;

	pe = zipfile->list;
	while (pe->next != NULL) {
	    pe = pe->next;
	}
	pe->next = entry;
    }

    /*
     * Start writing stuff out
     */

    local_size_pos = PR_Seek(zipfp, 0, PR_SEEK_CUR) + 18;
    /* File header */
    if (PR_Write(zipfp, &entry->local, sizeof(struct ZipLocal ))
         < sizeof(struct ZipLocal )) {
	char	*nsprErr;
	if (PR_GetErrorTextLength()) {
	    nsprErr = PR_Malloc(PR_GetErrorTextLength());
	    PR_GetErrorText(nsprErr);
	} else {
	    nsprErr = NULL;
	}
	PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr :
	    "");
	if (nsprErr) 
	    PR_Free(nsprErr);
	errorCount++;
	exit(ERRX);
    }

    /* File Name */
    if ( PR_Write(zipfp, filename, strlen(filename)) < strlen(filename)) {
	char	*nsprErr;
	if (PR_GetErrorTextLength()) {
	    nsprErr = PR_Malloc(PR_GetErrorTextLength());
	    PR_GetErrorText(nsprErr);
	} else {
	    nsprErr = NULL;
	}
	PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr :
	    "");
	if (nsprErr) 
	    PR_Free(nsprErr);
	errorCount++;
	exit(ERRX);
    }

    /*
     * File data
     */
    /* Initialize zstream */
    zstream.zalloc = my_alloc_func;
    zstream.zfree = my_free_func;
    zstream.opaque = NULL;
    zstream.next_in = inbuf;
    zstream.avail_in = BUFSIZ;
    zstream.next_out = outbuf;
    zstream.avail_out = BUFSIZ;
    /* Setting the windowBits to -MAX_WBITS is an undocumented feature of
     * zlib (see deflate.c in zlib).  It is the same thing that Java does
     * when you specify the nowrap option for deflation in java.util.zip.
     * It causes zlib to leave out its headers and footers, which don't
     * work in PKZIP files.
     */
    err = deflateInit2(&zstream, compression_level, Z_DEFLATED,
			-MAX_WBITS, 8 /*default*/, Z_DEFAULT_STRATEGY);
    if (err != Z_OK) {
	handle_zerror(err, zstream.msg);
	exit(ERRX);
    }

    while ( (zstream.avail_in = PR_Read(readfp, inbuf, BUFSIZ)) > 0) {
	zstream.next_in = inbuf;
	/* Process this chunk of data */
	while (zstream.avail_in > 0) {
	    err = deflate(&zstream, Z_NO_FLUSH);
	    if (err != Z_OK) {
		handle_zerror(err, zstream.msg);
		exit(ERRX);
	    }
	    if (zstream.avail_out <= 0) {
		if ( PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) {
		    char	*nsprErr;
		    if (PR_GetErrorTextLength()) {
			nsprErr = PR_Malloc(PR_GetErrorTextLength());
			PR_GetErrorText(nsprErr);
		    } else {
			nsprErr = NULL;
		    }
		    PR_fprintf(errorFD, "Writing zip data: %s\n",
					nsprErr ? nsprErr : "");
		    if (nsprErr) 
			PR_Free(nsprErr);
		    errorCount++;
		    exit(ERRX);
		}
		zstream.next_out = outbuf;
		zstream.avail_out = BUFSIZ;
	    }
	}
    }

    /* Now flush everything */
    while (1) {
	err = deflate(&zstream, Z_FINISH);
	if (err == Z_STREAM_END) {
	    break;
	} else if (err == Z_OK) {
	    /* output buffer full, repeat */
	} else {
	    handle_zerror(err, zstream.msg);
	    exit(ERRX);
	}
	if ( PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) {
	    char	*nsprErr;
	    if (PR_GetErrorTextLength()) {
		nsprErr = PR_Malloc(PR_GetErrorTextLength());
		PR_GetErrorText(nsprErr);
	    } else {
		nsprErr = NULL;
	    }
	    PR_fprintf(errorFD, "Writing zip data: %s\n",
				nsprErr ? nsprErr : "");
	    if (nsprErr) 
		PR_Free(nsprErr);
	    errorCount++;
	    exit(ERRX);
	}
	zstream.avail_out = BUFSIZ;
	zstream.next_out = outbuf;
    }

    /* If there's any output left, write it out. */
    if (zstream.next_out != outbuf) {
	if ( PR_Write(zipfp, outbuf, zstream.next_out - outbuf) <
	    zstream.next_out - outbuf) {
	    char	*nsprErr;
	    if (PR_GetErrorTextLength()) {
		nsprErr = PR_Malloc(PR_GetErrorTextLength());
		PR_GetErrorText(nsprErr);
	    } else {
		nsprErr = NULL;
	    }
	    PR_fprintf(errorFD, "Writing zip data: %s\n",
				nsprErr ? nsprErr : "");
	    if (nsprErr) 
		PR_Free(nsprErr);
	    errorCount++;
	    exit(ERRX);
	}
	zstream.avail_out = BUFSIZ;
	zstream.next_out = outbuf;
    }

    /* Now that we know the compressed size, write this to the headers */
    longtox(zstream.total_in, entry->local.orglen);
    longtox(zstream.total_out, entry->local.size);
    if (PR_Seek(zipfp, local_size_pos, PR_SEEK_SET) == -1) {
	char	*nsprErr;
	if (PR_GetErrorTextLength()) {
	    nsprErr = PR_Malloc(PR_GetErrorTextLength());
	    PR_GetErrorText(nsprErr);
	} else {
	    nsprErr = NULL;
	}
	PR_fprintf(errorFD, "Accessing zip file: %s\n", nsprErr ? nsprErr : "");
	if (nsprErr) 
	    PR_Free(nsprErr);
	errorCount++;
	exit(ERRX);
    }
    if ( PR_Write(zipfp, entry->local.size, 8) != 8) {
	char	*nsprErr;
	if (PR_GetErrorTextLength()) {
	    nsprErr = PR_Malloc(PR_GetErrorTextLength());
	    PR_GetErrorText(nsprErr);
	} else {
	    nsprErr = NULL;
	}
	PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
	if (nsprErr) 
	    PR_Free(nsprErr);
	errorCount++;
	exit(ERRX);
    }
    if (PR_Seek(zipfp, 0L, PR_SEEK_END) == -1) {
	char	*nsprErr;
	if (PR_GetErrorTextLength()) {
	    nsprErr = PR_Malloc(PR_GetErrorTextLength());
	    PR_GetErrorText(nsprErr);
	} else {
	    nsprErr = NULL;
	}
	PR_fprintf(errorFD, "Accessing zip file: %s\n", 
			    nsprErr ? nsprErr : "");
	if (nsprErr) 
	    PR_Free(nsprErr);
	errorCount++;
	exit(ERRX);
    }
    longtox(zstream.total_in, entry->central.orglen);
    longtox(zstream.total_out, entry->central.size);

    /* Close out the deflation operation */
    err = deflateEnd(&zstream);
    if (err != Z_OK) {
	handle_zerror(err, zstream.msg);
	exit(ERRX);
    }

    PR_Close(readfp);

    if ((zstream.total_in > zstream.total_out) && (zstream.total_in > 0)) {
	deflate_percent = (int) 
	    ((zstream.total_in - zstream.total_out) *100 / zstream.total_in);
    } else {
	deflate_percent = 0;
    }
    if (verbosity >= 0) {
	PR_fprintf(outputFD, "(deflated %d%%)\n", deflate_percent);
    }

    return 0;
}
示例#9
0
static SEC_PKCS7EncoderContext *
sec_pkcs7_encoder_start_contexts (SEC_PKCS7ContentInfo *cinfo,
				  PK11SymKey *bulkkey)
{
    SEC_PKCS7EncoderContext *p7ecx;
    SECOidTag kind;
    PRBool encrypt;
    SECItem **digests;
    SECAlgorithmID *digestalg, **digestalgs;

    p7ecx = 
      (SEC_PKCS7EncoderContext*)PORT_ZAlloc (sizeof(SEC_PKCS7EncoderContext));
    if (p7ecx == NULL)
	return NULL;

    digests = NULL;
    digestalg = NULL;
    digestalgs = NULL;
    encrypt = PR_FALSE;

    kind = SEC_PKCS7ContentType (cinfo);
    switch (kind) {
      default:
      case SEC_OID_PKCS7_DATA:
	break;
      case SEC_OID_PKCS7_DIGESTED_DATA:
	digestalg = &(cinfo->content.digestedData->digestAlg);
	break;
      case SEC_OID_PKCS7_SIGNED_DATA:
	digests = cinfo->content.signedData->digests;
	digestalgs = cinfo->content.signedData->digestAlgorithms;
	break;
      case SEC_OID_PKCS7_ENCRYPTED_DATA:
      case SEC_OID_PKCS7_ENVELOPED_DATA:
	encrypt = PR_TRUE;
	break;
      case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA:
	digests = cinfo->content.signedAndEnvelopedData->digests;
	digestalgs = cinfo->content.signedAndEnvelopedData->digestAlgorithms;
	encrypt = PR_TRUE;
	break;
    }

    if (encrypt) {
	p7ecx->encryptobj = sec_pkcs7_encoder_start_encrypt (cinfo, bulkkey);
	if (p7ecx->encryptobj == NULL) {
	    PORT_Free (p7ecx);
	    return NULL;
	}
    }

    if (digestalgs != NULL) {
	if (digests != NULL) {
	    /* digests already created (probably for detached data) */
	    digestalg = NULL;
	} else {
	    /*
	     * XXX Some day we should handle multiple digests; for now,
	     * assume only one will be done.
	     */
	    PORT_Assert (digestalgs[0] != NULL && digestalgs[1] == NULL);
	    digestalg = digestalgs[0];
	}
    }

    if (digestalg != NULL) {
	SECOidTag  oidTag = SECOID_FindOIDTag(&(digestalg->algorithm));

	p7ecx->digestobj = HASH_GetHashObjectByOidTag(oidTag);
	if (p7ecx->digestobj != NULL) {
	    p7ecx->digestcx = (* p7ecx->digestobj->create) ();
	    if (p7ecx->digestcx == NULL)
		p7ecx->digestobj = NULL;
	    else
		(* p7ecx->digestobj->begin) (p7ecx->digestcx);
	}
	if (p7ecx->digestobj == NULL) {
	    if (p7ecx->encryptobj != NULL)
		sec_PKCS7DestroyEncryptObject (p7ecx->encryptobj);
	    PORT_Free (p7ecx);
	    return NULL;
	}
    }

    p7ecx->cinfo = cinfo;
    return p7ecx;
}
示例#10
0
/*  Returns the password passed in in the text file.
 *  Uses the password once and nulls it out the prevent
 *  PKCS11 from calling us forever.
 */
char *GetFilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
{
    char* phrases, *phrase;
    PRFileDesc *fd;
    PRInt32 nb;
    const char *pwFile = (const char *)arg;
    int i;
    const long maxPwdFileSize = 4096;
    char* tokenName = NULL;
    int tokenLen = 0;

    if (!pwFile) {
        return 0;
    }

    if (retry) {
        return 0;  /* no good retrying - the files contents will be the same */
    }

    phrases = PORT_ZAlloc(maxPwdFileSize);

    if (!phrases) {
        return 0; /* out of memory */
    }

    fd = PR_Open(pwFile, PR_RDONLY, 0);
    if (!fd) {
        fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
        PORT_Free(phrases);
        return NULL;
    }
    nb = PR_Read(fd, phrases, maxPwdFileSize);

    PR_Close(fd);

    if (nb == 0) {
        fprintf(stderr,"password file contains no data\n");
        PORT_Free(phrases);
        return NULL;
    }

    if (slot) {
        tokenName = PK11_GetTokenName(slot);
        if (tokenName) {
            tokenLen = PORT_Strlen(tokenName);
        }
    }
    i = 0;
    do {
        int startphrase = i;
        int phraseLen;
        /* handle the Windows EOL case */
        while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++;
        /* terminate passphrase */
        phrases[i++] = '\0';
        /* clean up any EOL before the start of the next passphrase */
        while ( (i<nb) && (phrases[i] == '\r' || phrases[i] == '\n')) {
            phrases[i++] = '\0';
        }
        /* now analyze the current passphrase */
        phrase = &phrases[startphrase];
        if (!tokenName)
            break;
        if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue;
        phraseLen = PORT_Strlen(phrase);
        if (phraseLen < (tokenLen+1)) continue;
        if (phrase[tokenLen] != ':') continue;
        phrase = &phrase[tokenLen+1];
        break;
    } while (i<nb);

    phrase = PORT_Strdup((char*)phrase);
    PORT_Free(phrases);
    return phrase;
}