/*
 * @param(IN) salt  salt in binary format
 * @param(IN) saltSize   number of bytes for the salt
 * @param(IN) clearPasswd clearPasswd
 * @param(OUT) the hashed password with salt in ascii b64 format
 *
 * #sample keyfile line
 * j2ee;{SSHA}WRWaz20fzw3zN9x5Uzyyk5Wfvrbe4m40rYTPrA==;staff,eng
 */
void sshaPasswd(const char* salt, const int saltSize,const char* clearPasswd,NSString& hashed)
{
    //PRBool workaround= PR_FALSE; //PR_TRUE;
    const int digestLen = SHA1_LENGTH;  //20
    unsigned char H[512];
    char* pwdAndSalt=NULL;
    
    hashed.clear();
    if (!clearPasswd) {
        return;
    }
    int tobeHashedLen = 0;
    pwdAndSalt = addSalt(clearPasswd, salt, saltSize,tobeHashedLen);

        //if (workaround==PR_TRUE) {
        //https_SHA1_Hash(H,pwdAndSalt); //refer lib/libadmin/password.cpp
        //} else {
        //const int keylen = PRIVATE_KEY_LEN;
        //unsigned char DigestPrivatekey[PRIVATE_KEY_LEN];
        //PK11_GenerateRandom(DigestPrivatekey, keylen);

        PK11Context * SHA1Ctx = PK11_CreateDigestContext(SEC_OID_SHA1);
        if (SHA1Ctx==NULL) {
            FREE(pwdAndSalt);
            return;            
        }
        PK11_DigestBegin(SHA1Ctx);
        //PK11_DigestOp(SHA1Ctx, (unsigned char*)pwdAndSalt, strlen(pwdAndSalt) );
        PK11_DigestOp(SHA1Ctx, (unsigned char*)pwdAndSalt, tobeHashedLen );
        PK11_DigestFinal(SHA1Ctx, (unsigned char *)H, (unsigned int*)&digestLen, sizeof(H));
        PK11_DestroyContext(SHA1Ctx, 1);
        PR_ASSERT(digestLen==20);
        //}

    char* base64Val=NULL;
    if (salt!=NULL && saltSize>0) {
        memcpy(H+20,salt,saltSize);   //append salt to hashed passwd
        base64Val = BTOA_DataToAscii(H,digestLen+saltSize);   //base64.h
    } else {
        base64Val = BTOA_DataToAscii(H,digestLen);   //base64.h
    }

    hashed.append(SSHA_TAG );
    hashed.append(base64Val);

    if (base64Val)
        PORT_Free(base64Val);
    base64Val = NULL;
    FREE(pwdAndSalt);
    return;
}
Beispiel #2
0
/* NSS wraps b64 encoded buffers with CRLF automatically after 64 chars. This
 * function strips the CRLF double-chars. The buffer can be decoded with plain
 * NSS calls */
char *sss_base64_encode(TALLOC_CTX *mem_ctx,
                        const unsigned char *inbuf,
                        size_t inbufsize)
{
    int ret;
    char *b64encoded = NULL;
    int i, j, b64size;
    char *outbuf;

    /* initialize NSS if needed */
    ret = nspr_nss_init();
    if (ret != EOK) {
        return NULL;
    }

    b64encoded = BTOA_DataToAscii(inbuf, inbufsize);
    if (!b64encoded) return NULL;

    b64size = strlen(b64encoded) + 1;
    outbuf = talloc_array(mem_ctx, char, b64size);
    if (outbuf == NULL) {
        PORT_Free(b64encoded);
        return NULL;
    }

    for (i=0, j=0; i < b64size; i++) {
        if (b64encoded[i] == '\n' || b64encoded[i] == '\r') {
            continue;
        }
        outbuf[j++] = b64encoded[i]; /* will also copy the trailing \0 char */
    }

    PORT_Free(b64encoded);
    return outbuf;
}
Beispiel #3
0
NS_IMETHODIMP
nsCryptoHash::Finish(bool ascii, nsACString & _retval)
{
  nsNSSShutDownPreventionLock locker;
  
  if (!mInitialized)
    return NS_ERROR_NOT_INITIALIZED;
  
  uint32_t hashLen = 0;
  unsigned char buffer[HASH_LENGTH_MAX];
  unsigned char* pbuffer = buffer;

  HASH_End(mHashContext, pbuffer, &hashLen, HASH_LENGTH_MAX);

  mInitialized = false;

  if (ascii)
  {
    char *asciiData = BTOA_DataToAscii(buffer, hashLen);
    NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);

    _retval.Assign(asciiData);
    PORT_Free(asciiData);
  }
  else
  {
    _retval.Assign((const char*)buffer, hashLen);
  }

  return NS_OK;
}
Beispiel #4
0
/* ACString finish (in bool aASCII); */
NS_IMETHODIMP nsCryptoHMAC::Finish(bool aASCII, nsACString & _retval)
{
  nsNSSShutDownPreventionLock locker;

  if (!mHMACContext)
    return NS_ERROR_NOT_INITIALIZED;
  
  uint32_t hashLen = 0;
  unsigned char buffer[HASH_LENGTH_MAX];
  unsigned char* pbuffer = buffer;

  PK11_DigestFinal(mHMACContext, pbuffer, &hashLen, HASH_LENGTH_MAX);
  if (aASCII)
  {
    char *asciiData = BTOA_DataToAscii(buffer, hashLen);
    NS_ENSURE_TRUE(asciiData, NS_ERROR_OUT_OF_MEMORY);

    _retval.Assign(asciiData);
    PORT_Free(asciiData);
  }
  else
  {
    _retval.Assign((const char*)buffer, hashLen);
  }

  return NS_OK;
}
Beispiel #5
0
gchar* PE_nonce_to_str(Nonce* nonce) {
   char * tmp = BTOA_DataToAscii(*nonce, sizeof(Nonce));
   gchar* out = g_strdup(tmp);

   purple_debug(PURPLE_DEBUG_INFO, "pidgin-encryption", "Built Nonce:%u:%s\n", (unsigned)sizeof(Nonce), tmp);

   PORT_Free(tmp);
   return out;
}
/* Convert 'num' bytes into an ascii string.  */
void PE_bytes_to_str(char *str, unsigned char *bytes, int num) {
   char* tmp = BTOA_DataToAscii(bytes, num);
   GString* tmp2 = g_string_new(tmp);

   PE_strip_returns(tmp2);
   strcpy(str, tmp2->str);

   PORT_Free(tmp);
   g_string_free(tmp2, TRUE);
}
Beispiel #7
0
off_t
export_signature(cms_context *cms, int fd, int ascii_armor)
{
	off_t ret = 0;
	int rc = 0;

	SECItem *sig = &cms->newsig;

	unsigned char *data = sig->data;
	int datalen = sig->len;
	if (ascii_armor) {
		char *ascii = BTOA_DataToAscii(data, datalen);
		if (!ascii) {
			cms->log(cms, LOG_ERR, "error exporting signature");
failure:
			close(fd);
			return -1;
		}

		rc = write(fd, sig_begin_marker, strlen(sig_begin_marker));
		if (rc < 0) {
			cms->log(cms, LOG_ERR, "error exporting signature: %m");
			goto failure;
		}
		ret += rc;

		rc = write(fd, ascii, strlen(ascii));
		if (rc < 0) {
			cms->log(cms, LOG_ERR, "error exporting signature: %m");
			goto failure;
		}
		ret += rc;

		rc = write(fd, sig_end_marker, strlen(sig_end_marker));
		if (rc < 0) {
			cms->log(cms, LOG_ERR, "error exporting signature: %m");
			goto failure;
		}
		ret += rc;

		PORT_Free(ascii);
	} else {
		rc = write(fd, data, datalen);
		if (rc < 0) {
			cms->log(cms, LOG_ERR, "error exporting signature: %m");
			goto failure;
		}
		ret += rc;
	}
	return ret;
}
NSAPI_PUBLIC void INTsession_fill_ssl(Session *sn)
{
    PRInt32 secon = -1;
    PRInt32 keySize, secretKeySize;
    char *cipher;
    char *issuer_dn;
    char *user_dn;
    char *idstr;
    SECItem *iditem;

    // we'll call SSL_SecurityStatus both when we know that SSL is on
    // or when we don't know anything.
    // either way, we can do this only when we have a descriptor.
    // if we don't have one, we're in a VSInit.
    if (sn->ssl && sn->csd_open) {
        if (!SSL_SecurityStatus(sn->csd, &secon, &cipher, &keySize,
                                &secretKeySize, &issuer_dn, &user_dn)) {
            if(secon > 0) {
                sn->ssl = 1;

                int cipher_len = cipher ? strlen(cipher) : 0;
                int issuer_dn_len = issuer_dn ? strlen(issuer_dn) : 0;
                int user_dn_len = user_dn ? strlen(user_dn) : 0;
                pblock_kvinsert(pb_key_cipher, cipher, cipher_len, sn->client);
                pblock_kninsert(pb_key_keysize, keySize, sn->client);
                pblock_kninsert(pb_key_secret_keysize, secretKeySize, sn->client);
                pblock_kvinsert(pb_key_issuer_dn, issuer_dn, issuer_dn_len, sn->client);
                pblock_kvinsert(pb_key_user_dn, user_dn, user_dn_len, sn->client);

                iditem = SSL_GetSessionID(sn->csd);
                if (iditem) {
                    /* Convert to base64 ASCII encoding */
                    idstr = BTOA_DataToAscii(iditem->data, iditem->len);
                    if (idstr) {
                        /* Add encoding to client pblock */
                        pblock_kvinsert(pb_key_ssl_id, idstr, strlen(idstr), sn->client);
                    }

                    /* Free the encoding buffer (pblock_nvinsert dups it) */
                    SECITEM_FreeItem(iditem, PR_TRUE);
                    PR_Free(idstr);
                }
            }
            if (cipher) PORT_Free (cipher);
            if (issuer_dn) PORT_Free (issuer_dn);
            if (user_dn) PORT_Free (user_dn);
        }
    }
}
NS_IMETHODIMP nsStreamCipher::Finish(bool aASCII, nsACString & _retval)
{
  if (!mContext)
    return NS_ERROR_NOT_INITIALIZED;

  if (aASCII) {
    char *asciiData = BTOA_DataToAscii((unsigned char*)(mValue.get()),
                                       mValue.Length());
    _retval.Assign(asciiData);
    PORT_Free(asciiData);
  } else {
    _retval.Assign(mValue);
  }

  return NS_OK;
}
Beispiel #10
0
void
export_signature(pesign_context *p_ctx, SECItem *sig)
{
	int rc = 0;

	unsigned char *data = sig->data;
	int datalen = sig->len;
	if (p_ctx->ascii) {
		char *ascii = BTOA_DataToAscii(data, datalen);
		if (!ascii) {
			fprintf(stderr, "Error exporting signature\n");
failure:
			close(p_ctx->outsigfd);
			unlink(p_ctx->outsig);
			exit(1);
		}

		rc = write(p_ctx->outsigfd, sig_begin_marker,
				strlen(sig_begin_marker));
		if (rc < 0) {
			fprintf(stderr, "Error exporting signature: %m\n");
			goto failure;
		}

		rc = write(p_ctx->outsigfd, ascii, strlen(ascii));
		if (rc < 0) {
			fprintf(stderr, "Error exporting signature: %m\n");
			goto failure;
		}

		rc = write(p_ctx->outsigfd, sig_end_marker,
			strlen(sig_end_marker));
		if (rc < 0) {
			fprintf(stderr, "Error exporting signature: %m\n");
			goto failure;
		}

		PORT_Free(ascii);
	} else {
		rc = write(p_ctx->outsigfd, data, datalen);
		if (rc < 0) {
			fprintf(stderr, "Error exporting signature: %m\n");
			goto failure;
		}
	}
}
Beispiel #11
0
/*
 *  m a n i f e s t o _ f n
 *
 *  Called by pointer from manifesto(), once for
 *  each file within the directory.
 *
 */
static int	manifesto_fn 
(char *relpath, char *basedir, char *reldir, char *filename, void *arg)
{
    int	use_js;

    JAR_Digest dig;
    char	fullname [FNSIZE];

    if (verbosity >= 0) {
	PR_fprintf(outputFD, "--> %s\n", relpath);
    }

    /* extension matching */
    if (extensionsGiven) {
	char	*ext = PL_strrchr(relpath, '.');
	if (!ext) 
	    return 0;
	if (!PL_HashTableLookup(extensions, ext)) 
	    return 0;
    }

    sprintf (fullname, "%s/%s", basedir, relpath);

    fprintf (mf, "\n");

    use_js = 0;

    if (scriptdir && !PORT_Strcmp (scriptdir, reldir))
	use_js++;

    /* sign non-.js files inside .arc directories using the javascript magic */

    if ( (PL_strcaserstr(filename, ".js") != filename + strlen(filename) - 3)
         && (PL_strcaserstr(reldir, ".arc") == reldir + strlen(filename) - 4))
	use_js++;

    if (use_js) {
	fprintf (mf, "Name: %s\n", filename);
	fprintf (mf, "Magic: javascript\n");

	if (optimize == 0)
	    fprintf (mf, "javascript.id: %s\n", filename);

	if (metafile)
	    add_meta (mf, filename);
    } else {
	fprintf (mf, "Name: %s\n", relpath);
	if (metafile)
	    add_meta (mf, relpath);
    }

    JAR_digest_file (fullname, &dig);


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

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

    if (!use_js) {
	JzipAdd(fullname, relpath, zipfile, compression_level);
    }

    return 0;
}
Beispiel #12
0
nsresult
nsKeygenFormProcessor::GetPublicKey(nsAString& aValue, nsAString& aChallenge,
                                    nsAFlatString& aKeyType,
                                    nsAString& aOutPublicKey, nsAString& aKeyParams)
{
    nsNSSShutDownPreventionLock locker;
    nsresult rv = NS_ERROR_FAILURE;
    char *keystring = nsnull;
    char *keyparamsString = nsnull, *str = nsnull;
    KeyType type;
    PRUint32 keyGenMechanism;
    PRInt32 primeBits;
    PK11SlotInfo *slot = nsnull;
    PK11RSAGenParams rsaParams;
    SECOidTag algTag;
    int keysize = 0;
    void *params;
    SECKEYPrivateKey *privateKey = nsnull;
    SECKEYPublicKey *publicKey = nsnull;
    CERTSubjectPublicKeyInfo *spkInfo = nsnull;
    PRArenaPool *arena = nsnull;
    SECStatus sec_rv = SECFailure;
    SECItem spkiItem;
    SECItem pkacItem;
    SECItem signedItem;
    CERTPublicKeyAndChallenge pkac;
    pkac.challenge.data = nsnull;
    nsIGeneratingKeypairInfoDialogs * dialogs;
    nsKeygenThread *KeygenRunnable = 0;
    nsCOMPtr<nsIKeygenThread> runnable;

    // Get the key size //
    for (size_t i = 0; i < number_of_key_size_choices; ++i) {
        if (aValue.Equals(mSECKeySizeChoiceList[i].name)) {
            keysize = mSECKeySizeChoiceList[i].size;
            break;
        }
    }
    if (!keysize) {
        goto loser;
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        goto loser;
    }

    // Set the keygen mechanism
    if (aKeyType.IsEmpty() || aKeyType.LowerCaseEqualsLiteral("rsa")) {
        type = rsaKey;
        keyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
    } else if (aKeyType.LowerCaseEqualsLiteral("dsa")) {
        char * end;
        keyparamsString = ToNewCString(aKeyParams);
        if (!keyparamsString) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        type = dsaKey;
        keyGenMechanism = CKM_DSA_KEY_PAIR_GEN;
        if (strcmp(keyparamsString, "null") == 0)
            goto loser;
        str = keyparamsString;
        PRBool found_match = PR_FALSE;
        do {
            end = strchr(str, ',');
            if (end != nsnull)
                *end = '\0';
            primeBits = pqg_prime_bits(str);
            if (keysize == primeBits) {
                found_match = PR_TRUE;
                break;
            }
            str = end + 1;
        } while (end != nsnull);
        if (!found_match) {
            goto loser;
        }
    } else if (aKeyType.LowerCaseEqualsLiteral("ec")) {
        keyparamsString = ToNewCString(aKeyParams);
        if (!keyparamsString) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        type = ecKey;
        keyGenMechanism = CKM_EC_KEY_PAIR_GEN;
        /* ecParams are initialized later */
    } else {
        goto loser;
    }

    // Get the slot
    rv = GetSlot(keyGenMechanism, &slot);
    if (NS_FAILED(rv)) {
        goto loser;
    }
    switch (keyGenMechanism) {
    case CKM_RSA_PKCS_KEY_PAIR_GEN:
        rsaParams.keySizeInBits = keysize;
        rsaParams.pe = DEFAULT_RSA_KEYGEN_PE;
        algTag = DEFAULT_RSA_KEYGEN_ALG;
        params = &rsaParams;
        break;
    case CKM_DSA_KEY_PAIR_GEN:
        // XXX Fix this! XXX //
        goto loser;
    case CKM_EC_KEY_PAIR_GEN:
        /* XXX We ought to rethink how the KEYGEN tag is
         * displayed. The pulldown selections presented
         * to the user must depend on the keytype.
         * The displayed selection could be picked
         * from the keyparams attribute (this is currently called
         * the pqg attribute).
         * For now, we pick ecparams from the keyparams field
         * if it specifies a valid supported curve, or else
         * we pick one of secp384r1, secp256r1 or secp192r1
         * respectively depending on the user's selection
         * (High, Medium, Low).
         * (RSA uses RSA-2048, RSA-1024 and RSA-512 for historical
         * reasons, while ECC choices represent a stronger mapping)
         * NOTE: The user's selection
         * is silently ignored when a valid curve is presented
         * in keyparams.
         */
        if ((params = decode_ec_params(keyparamsString)) == nsnull) {
            /* The keyparams attribute did not specify a valid
             * curve name so use a curve based on the keysize.
             * NOTE: Here keysize is used only as an indication of
             * High/Medium/Low strength; elliptic curve
             * cryptography uses smaller keys than RSA to provide
             * equivalent security.
             */
            switch (keysize) {
            case 2048:
                params = decode_ec_params("secp384r1");
                break;
            case 1024:
            case 512:
                params = decode_ec_params("secp256r1");
                break;
            }
        }
        /* XXX The signature algorithm ought to choose the hashing
         * algorithm based on key size once ECDSA variations based
         * on SHA256 SHA384 and SHA512 are standardized.
         */
        algTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
        break;
    default:
        goto loser;
    }

    /* Make sure token is initialized. */
    rv = setPassword(slot, m_ctx);
    if (NS_FAILED(rv))
        goto loser;

    sec_rv = PK11_Authenticate(slot, PR_TRUE, m_ctx);
    if (sec_rv != SECSuccess) {
        goto loser;
    }

    rv = getNSSDialogs((void**)&dialogs,
                       NS_GET_IID(nsIGeneratingKeypairInfoDialogs),
                       NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID);

    if (NS_SUCCEEDED(rv)) {
        KeygenRunnable = new nsKeygenThread();
        NS_IF_ADDREF(KeygenRunnable);
    }

    if (NS_FAILED(rv) || !KeygenRunnable) {
        rv = NS_OK;
        privateKey = PK11_GenerateKeyPair(slot, keyGenMechanism, params,
                                          &publicKey, PR_TRUE, PR_TRUE, m_ctx);
    } else {
        KeygenRunnable->SetParams( slot, keyGenMechanism, params, PR_TRUE, PR_TRUE, m_ctx );

        runnable = do_QueryInterface(KeygenRunnable);

        if (runnable) {
            {
                nsPSMUITracker tracker;
                if (tracker.isUIForbidden()) {
                    rv = NS_ERROR_NOT_AVAILABLE;
                }
                else {
                    rv = dialogs->DisplayGeneratingKeypairInfo(m_ctx, runnable);
                    // We call join on the thread,
                    // so we can be sure that no simultaneous access to the passed parameters will happen.
                    KeygenRunnable->Join();
                }
            }

            NS_RELEASE(dialogs);
            if (NS_SUCCEEDED(rv)) {
                rv = KeygenRunnable->GetParams(&privateKey, &publicKey);
            }
        }
    }

    if (NS_FAILED(rv) || !privateKey) {
        goto loser;
    }
    // just in case we'll need to authenticate to the db -jp //
    privateKey->wincx = m_ctx;

    /*
     * Create a subject public key info from the public key.
     */
    spkInfo = SECKEY_CreateSubjectPublicKeyInfo(publicKey);
    if ( !spkInfo ) {
        goto loser;
    }

    /*
     * Now DER encode the whole subjectPublicKeyInfo.
     */
    sec_rv=DER_Encode(arena, &spkiItem, CERTSubjectPublicKeyInfoTemplate, spkInfo);
    if (sec_rv != SECSuccess) {
        goto loser;
    }

    /*
     * set up the PublicKeyAndChallenge data structure, then DER encode it
     */
    pkac.spki = spkiItem;
    pkac.challenge.len = aChallenge.Length();
    pkac.challenge.data = (unsigned char *)ToNewCString(aChallenge);
    if (!pkac.challenge.data) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    sec_rv = DER_Encode(arena, &pkacItem, CERTPublicKeyAndChallengeTemplate, &pkac);
    if ( sec_rv != SECSuccess ) {
        goto loser;
    }

    /*
     * now sign the DER encoded PublicKeyAndChallenge
     */
    sec_rv = SEC_DerSignData(arena, &signedItem, pkacItem.data, pkacItem.len,
                             privateKey, algTag);
    if ( sec_rv != SECSuccess ) {
        goto loser;
    }

    /*
     * Convert the signed public key and challenge into base64/ascii.
     */
    keystring = BTOA_DataToAscii(signedItem.data, signedItem.len);
    if (!keystring) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    CopyASCIItoUTF16(keystring, aOutPublicKey);
    nsCRT::free(keystring);

    rv = NS_OK;
loser:
    if ( sec_rv != SECSuccess ) {
        if ( privateKey ) {
            PK11_DestroyTokenObject(privateKey->pkcs11Slot,privateKey->pkcs11ID);
        }
        if ( publicKey ) {
            PK11_DestroyTokenObject(publicKey->pkcs11Slot,publicKey->pkcs11ID);
        }
    }
    if ( spkInfo ) {
        SECKEY_DestroySubjectPublicKeyInfo(spkInfo);
    }
    if ( publicKey ) {
        SECKEY_DestroyPublicKey(publicKey);
    }
    if ( privateKey ) {
        SECKEY_DestroyPrivateKey(privateKey);
    }
    if ( arena ) {
        PORT_FreeArena(arena, PR_TRUE);
    }
    if (slot != nsnull) {
        PK11_FreeSlot(slot);
    }
    if (KeygenRunnable) {
        NS_RELEASE(KeygenRunnable);
    }
    if (keyparamsString) {
        nsMemory::Free(keyparamsString);
    }
    if (pkac.challenge.data) {
        nsMemory::Free(pkac.challenge.data);
    }
    return rv;
}
Beispiel #13
0
nsresult
nsKeygenFormProcessor::GetPublicKey(const nsAString& aValue,
                                    const nsAString& aChallenge,
                                    const nsAFlatString& aKeyType,
                                    nsAString& aOutPublicKey,
                                    const nsAString& aKeyParams)
{
    nsNSSShutDownPreventionLock locker;
    if (isAlreadyShutDown()) {
      return NS_ERROR_NOT_AVAILABLE;
    }

    nsresult rv = NS_ERROR_FAILURE;
    char *keystring = nullptr;
    char *keyparamsString = nullptr;
    uint32_t keyGenMechanism;
    PK11SlotInfo *slot = nullptr;
    PK11RSAGenParams rsaParams;
    SECOidTag algTag;
    int keysize = 0;
    void *params = nullptr;
    SECKEYPrivateKey *privateKey = nullptr;
    SECKEYPublicKey *publicKey = nullptr;
    CERTSubjectPublicKeyInfo *spkInfo = nullptr;
    SECStatus srv = SECFailure;
    SECItem spkiItem;
    SECItem pkacItem;
    SECItem signedItem;
    CERTPublicKeyAndChallenge pkac;
    pkac.challenge.data = nullptr;
    nsIGeneratingKeypairInfoDialogs * dialogs;
    nsKeygenThread *KeygenRunnable = 0;
    nsCOMPtr<nsIKeygenThread> runnable;

    // permanent and sensitive flags for keygen
    PK11AttrFlags attrFlags = PK11_ATTR_TOKEN | PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE;

    UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE));
    if (!arena) {
        goto loser;
    }

    // Get the key size //
    for (size_t i = 0; i < number_of_key_size_choices; ++i) {
        if (aValue.Equals(mSECKeySizeChoiceList[i].name)) {
            keysize = mSECKeySizeChoiceList[i].size;
            break;
        }
    }
    if (!keysize) {
        goto loser;
    }

    // Set the keygen mechanism
    if (aKeyType.IsEmpty() || aKeyType.LowerCaseEqualsLiteral("rsa")) {
        keyGenMechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
    } else if (aKeyType.LowerCaseEqualsLiteral("ec")) {
        keyparamsString = ToNewCString(aKeyParams);
        if (!keyparamsString) {
            rv = NS_ERROR_OUT_OF_MEMORY;
            goto loser;
        }

        keyGenMechanism = CKM_EC_KEY_PAIR_GEN;
        /* ecParams are initialized later */
    } else {
        goto loser;
    }

    // Get the slot
    rv = GetSlot(keyGenMechanism, &slot);
    if (NS_FAILED(rv)) {
        goto loser;
    }
    switch (keyGenMechanism) {
        case CKM_RSA_PKCS_KEY_PAIR_GEN:
            rsaParams.keySizeInBits = keysize;
            rsaParams.pe = DEFAULT_RSA_KEYGEN_PE;
            algTag = DEFAULT_RSA_KEYGEN_ALG;
            params = &rsaParams;
            break;
        case CKM_EC_KEY_PAIR_GEN:
            /* XXX We ought to rethink how the KEYGEN tag is 
             * displayed. The pulldown selections presented
             * to the user must depend on the keytype.
             * The displayed selection could be picked
             * from the keyparams attribute (this is currently called
             * the pqg attribute).
             * For now, we pick ecparams from the keyparams field
             * if it specifies a valid supported curve, or else 
             * we pick one of secp384r1, secp256r1 or secp192r1
             * respectively depending on the user's selection
             * (High, Medium, Low). 
             * (RSA uses RSA-2048, RSA-1024 and RSA-512 for historical
             * reasons, while ECC choices represent a stronger mapping)
             * NOTE: The user's selection
             * is silently ignored when a valid curve is presented
             * in keyparams.
             */
            if ((params = decode_ec_params(keyparamsString)) == nullptr) {
                /* The keyparams attribute did not specify a valid
                 * curve name so use a curve based on the keysize.
                 * NOTE: Here keysize is used only as an indication of
                 * High/Medium/Low strength; elliptic curve
                 * cryptography uses smaller keys than RSA to provide
                 * equivalent security.
                 */
                switch (keysize) {
                case 2048:
                    params = decode_ec_params("secp384r1");
                    break;
                case 1024:
                case 512:
                    params = decode_ec_params("secp256r1");
                    break;
                } 
            }
            /* XXX The signature algorithm ought to choose the hashing
             * algorithm based on key size once ECDSA variations based
             * on SHA256 SHA384 and SHA512 are standardized.
             */
            algTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
            break;
      default:
          goto loser;
      }

    /* Make sure token is initialized. */
    rv = setPassword(slot, m_ctx, locker);
    if (NS_FAILED(rv))
        goto loser;

    srv = PK11_Authenticate(slot, true, m_ctx);
    if (srv != SECSuccess) {
        goto loser;
    }

    rv = getNSSDialogs((void**)&dialogs,
                       NS_GET_IID(nsIGeneratingKeypairInfoDialogs),
                       NS_GENERATINGKEYPAIRINFODIALOGS_CONTRACTID);

    if (NS_SUCCEEDED(rv)) {
        KeygenRunnable = new nsKeygenThread();
        NS_IF_ADDREF(KeygenRunnable);
    }

    if (NS_FAILED(rv) || !KeygenRunnable) {
        rv = NS_OK;
        privateKey = PK11_GenerateKeyPairWithFlags(slot, keyGenMechanism, params,
                                                   &publicKey, attrFlags, m_ctx);
    } else {
        KeygenRunnable->SetParams( slot, attrFlags, nullptr, 0,
                                   keyGenMechanism, params, m_ctx );

        runnable = do_QueryInterface(KeygenRunnable);
        
        if (runnable) {
            rv = dialogs->DisplayGeneratingKeypairInfo(m_ctx, runnable);
            // We call join on the thread so we can be sure that no
            // simultaneous access to the passed parameters will happen.
            KeygenRunnable->Join();

            NS_RELEASE(dialogs);
            if (NS_SUCCEEDED(rv)) {
                PK11SlotInfo *used_slot = nullptr;
                rv = KeygenRunnable->ConsumeResult(&used_slot, &privateKey, &publicKey);
                if (NS_SUCCEEDED(rv) && used_slot) {
                  PK11_FreeSlot(used_slot);
                }
            }
        }
    }
    
    if (NS_FAILED(rv) || !privateKey) {
        goto loser;
    }
    // just in case we'll need to authenticate to the db -jp //
    privateKey->wincx = m_ctx;

    /*
     * Create a subject public key info from the public key.
     */
    spkInfo = SECKEY_CreateSubjectPublicKeyInfo(publicKey);
    if ( !spkInfo ) {
        goto loser;
    }

    /*
     * Now DER encode the whole subjectPublicKeyInfo.
     */
    srv = DER_Encode(arena.get(), &spkiItem, CERTSubjectPublicKeyInfoTemplate,
                     spkInfo);
    if (srv != SECSuccess) {
        goto loser;
    }

    /*
     * set up the PublicKeyAndChallenge data structure, then DER encode it
     */
    pkac.spki = spkiItem;
    pkac.challenge.len = aChallenge.Length();
    pkac.challenge.data = (unsigned char *)ToNewCString(aChallenge);
    if (!pkac.challenge.data) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    srv = DER_Encode(arena.get(), &pkacItem, CERTPublicKeyAndChallengeTemplate,
                     &pkac);
    if (srv != SECSuccess) {
        goto loser;
    }

    /*
     * now sign the DER encoded PublicKeyAndChallenge
     */
    srv = SEC_DerSignData(arena.get(), &signedItem, pkacItem.data, pkacItem.len,
                          privateKey, algTag);
    if (srv != SECSuccess) {
        goto loser;
    }

    /*
     * Convert the signed public key and challenge into base64/ascii.
     */
    keystring = BTOA_DataToAscii(signedItem.data, signedItem.len);
    if (!keystring) {
        rv = NS_ERROR_OUT_OF_MEMORY;
        goto loser;
    }

    CopyASCIItoUTF16(keystring, aOutPublicKey);
    free(keystring);

    rv = NS_OK;

    GatherKeygenTelemetry(keyGenMechanism, keysize, keyparamsString);
loser:
    if (srv != SECSuccess) {
        if ( privateKey ) {
            PK11_DestroyTokenObject(privateKey->pkcs11Slot,privateKey->pkcs11ID);
        }
        if ( publicKey ) {
            PK11_DestroyTokenObject(publicKey->pkcs11Slot,publicKey->pkcs11ID);
        }
    }
    if ( spkInfo ) {
        SECKEY_DestroySubjectPublicKeyInfo(spkInfo);
    }
    if ( publicKey ) {
        SECKEY_DestroyPublicKey(publicKey);
    }
    if ( privateKey ) {
        SECKEY_DestroyPrivateKey(privateKey);
    }
    if (slot) {
        PK11_FreeSlot(slot);
    }
    if (KeygenRunnable) {
        NS_RELEASE(KeygenRunnable);
    }
    if (keyparamsString) {
        free(keyparamsString);
    }
    if (pkac.challenge.data) {
        free(pkac.challenge.data);
    }
    // If params is non-null and doesn't point to rsaParams, it was allocated
    // in decode_ec_params. We have to free this memory.
    if (params && params != &rsaParams) {
        SECITEM_FreeItem(static_cast<SECItem*>(params), true);
        params = nullptr;
    }
    return rv;
}
Beispiel #14
0
/**
 * Extracts a signature from a MAR file, base64 encodes it, and writes it out
 *
 * @param  src       The path of the source MAR file
 * @param  sigIndex  The index of the signature to extract
 * @param  dest      The path of file to write the signature to
 * @return 0 on success
 *         -1 on error
*/
int
extract_signature(const char *src, uint32_t sigIndex, const char * dest)
{
  FILE *fpSrc = NULL, *fpDest = NULL;
  uint32_t i;
  uint32_t signatureCount;
  uint32_t signatureLen;
  uint8_t *extractedSignature = NULL;
  char *base64Encoded = NULL;
  int rv = -1;
  if (!src || !dest) {
    fprintf(stderr, "ERROR: Invalid parameter passed in.\n");
    goto failure;
  }

  fpSrc = fopen(src, "rb");
  if (!fpSrc) {
    fprintf(stderr, "ERROR: could not open source file: %s\n", src);
    goto failure;
  }

  fpDest = fopen(dest, "wb");
  if (!fpDest) {
    fprintf(stderr, "ERROR: could not create target file: %s\n", dest);
    goto failure;
  }

  /* Skip to the start of the signature block */
  if (fseeko(fpSrc, SIGNATURE_BLOCK_OFFSET, SEEK_SET)) {
    fprintf(stderr, "ERROR: could not seek to signature block\n");
    goto failure;
  }

  /* Get the number of signatures */
  if (fread(&signatureCount, sizeof(signatureCount), 1, fpSrc) != 1) {
    fprintf(stderr, "ERROR: could not read signature count\n");
    goto failure;
  }
  signatureCount = ntohl(signatureCount);
  if (sigIndex >= signatureCount) {
    fprintf(stderr, "ERROR: Signature index was out of range\n");
    goto failure;
  }

  /* Skip to the correct signature */
  for (i = 0; i <= sigIndex; i++) {
    /* Avoid leaking while skipping signatures */
    free(extractedSignature);

    /* skip past the signature algorithm ID */
    if (fseeko(fpSrc, sizeof(uint32_t), SEEK_CUR)) {
      fprintf(stderr, "ERROR: Could not seek past sig algorithm ID.\n");
      goto failure;
    }

    /* Get the signature length */
    if (fread(&signatureLen, sizeof(signatureLen), 1, fpSrc) != 1) {
      fprintf(stderr, "ERROR: could not read signature length\n");
      goto failure;
    }
    signatureLen = ntohl(signatureLen);

    /* Get the signature */
    extractedSignature = malloc(signatureLen);
    if (fread(extractedSignature, signatureLen, 1, fpSrc) != 1) {
      fprintf(stderr, "ERROR: could not read signature\n");
      goto failure;
    }
  }

  base64Encoded = BTOA_DataToAscii(extractedSignature, signatureLen);
  if (!base64Encoded) {
    fprintf(stderr, "ERROR: could not obtain base64 encoded data\n");
    goto failure;
  }

  if (fwrite(base64Encoded, strlen(base64Encoded), 1, fpDest) != 1) {
    fprintf(stderr, "ERROR: Could not write base64 encoded string\n");
    goto failure;
  }

  rv = 0;
failure:
  if (base64Encoded) {
    PORT_Free(base64Encoded);
  }

  if (extractedSignature) {
    free(extractedSignature);
  }

  if (fpSrc) {
    fclose(fpSrc);
  }

  if (fpDest) {
    fclose(fpDest);
  }

  if (rv) {
    remove(dest);
  }

  return rv;
}
Beispiel #15
0
/*************************************************************************
 *
 * o u t p u t _ c a _ c e r t
 */
static void	
output_ca_cert (CERTCertificate *cert, CERTCertDBHandle *db)
{
    FILE * out;

    SECItem * encodedCertChain;
    SEC_PKCS7ContentInfo * certChain;
    char	*filename;

    /* the raw */

    filename = PORT_ZAlloc(strlen(DEFAULT_X509_BASENAME) + 8);
    if (!filename) 
	out_of_memory();

    sprintf(filename, "%s.raw", DEFAULT_X509_BASENAME);
    if ((out = fopen (filename, "wb")) == NULL) {
	PR_fprintf(errorFD, "%s: Can't open %s output file\n", PROGRAM_NAME,
	     filename);
	errorCount++;
	exit(ERRX);
    }

    certChain = SEC_PKCS7CreateCertsOnly (cert, PR_TRUE, db);
    encodedCertChain 
         = SEC_PKCS7EncodeItem (NULL, NULL, certChain, NULL, NULL, NULL);
    SEC_PKCS7DestroyContentInfo (certChain);

    if (encodedCertChain) {
	fprintf(out, "Content-type: application/x-x509-ca-cert\n\n");
	fwrite (encodedCertChain->data, 1, encodedCertChain->len,
	     out);
	SECITEM_FreeItem(encodedCertChain, PR_TRUE);
    } else {
	PR_fprintf(errorFD, "%s: Can't DER encode this certificate\n",
	     PROGRAM_NAME);
	errorCount++;
	exit(ERRX);
    }

    fclose (out);

    /* and the cooked */

    sprintf(filename, "%s.cacert", DEFAULT_X509_BASENAME);
    if ((out = fopen (filename, "wb")) == NULL) {
	PR_fprintf(errorFD, "%s: Can't open %s output file\n", PROGRAM_NAME,
	     filename);
	errorCount++;
	return;
    }

    fprintf (out, "%s\n%s\n%s\n", 
        NS_CERT_HEADER,
        BTOA_DataToAscii (cert->derCert.data, cert->derCert.len), 
        NS_CERT_TRAILER);

    fclose (out);

    if (verbosity >= 0) {
	PR_fprintf(outputFD, "Exported certificate to %s.raw and %s.cacert.\n",
	     			DEFAULT_X509_BASENAME, DEFAULT_X509_BASENAME);
    }
}
Beispiel #16
0
SECStatus
outputPQGParams(PQGParams *pqgParams, PRBool output_binary, PRBool output_raw,
                FILE *outFile)
{
    PLArenaPool *arena = NULL;
    char *PQG;
    SECItem *pItem;
    int cc;
    SECStatus rv;
    SECItem encodedParams;

    if (output_raw) {
        SECItem item;

        rv = PK11_PQG_GetPrimeFromParams(pqgParams, &item);
        if (rv) {
            SECU_PrintError(progName, "PK11_PQG_GetPrimeFromParams");
            return rv;
        }
        SECU_PrintInteger(outFile, &item, "Prime", 1);
        SECITEM_FreeItem(&item, PR_FALSE);

        rv = PK11_PQG_GetSubPrimeFromParams(pqgParams, &item);
        if (rv) {
            SECU_PrintError(progName, "PK11_PQG_GetPrimeFromParams");
            return rv;
        }
        SECU_PrintInteger(outFile, &item, "Subprime", 1);
        SECITEM_FreeItem(&item, PR_FALSE);

        rv = PK11_PQG_GetBaseFromParams(pqgParams, &item);
        if (rv) {
            SECU_PrintError(progName, "PK11_PQG_GetPrimeFromParams");
            return rv;
        }
        SECU_PrintInteger(outFile, &item, "Base", 1);
        SECITEM_FreeItem(&item, PR_FALSE);

        fprintf(outFile, "\n");
        return SECSuccess;
    }

    encodedParams.data = NULL;
    encodedParams.len = 0;
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) {
        SECU_PrintError(progName, "PORT_NewArena");
        return SECFailure;
    }
    pItem = SEC_ASN1EncodeItem(arena, &encodedParams, pqgParams,
                               seckey_PQGParamsTemplate);
    if (!pItem) {
        SECU_PrintError(progName, "SEC_ASN1EncodeItem");
        PORT_FreeArena(arena, PR_FALSE);
        return SECFailure;
    }
    if (output_binary) {
        size_t len;
        len = fwrite(encodedParams.data, 1, encodedParams.len, outFile);
        PORT_FreeArena(arena, PR_FALSE);
        if (len != encodedParams.len) {
            fprintf(stderr, "%s: fwrite failed\n", progName);
            return SECFailure;
        }
        return SECSuccess;
    }

    /* must be output ASCII */
    PQG = BTOA_DataToAscii(encodedParams.data, encodedParams.len);
    PORT_FreeArena(arena, PR_FALSE);
    if (!PQG) {
        SECU_PrintError(progName, "BTOA_DataToAscii");
        return SECFailure;
    }

    cc = fprintf(outFile, "%s\n", PQG);
    PORT_Free(PQG);
    if (cc <= 0) {
        fprintf(stderr, "%s: fprintf failed\n", progName);
        return SECFailure;
    }
    return SECSuccess;
}
Beispiel #17
0
/*
 *  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;
}