diff --git a/SOURCES/cve-2014-1568-nss-extra.patch b/SOURCES/cve-2014-1568-nss-extra.patch
new file mode 100644
index 0000000..507198e
--- /dev/null
+++ b/SOURCES/cve-2014-1568-nss-extra.patch
@@ -0,0 +1,32 @@
+
+# HG changeset patch
+# User Kai Engert <kaie@kuix.de>
+# Date 1411493980 -7200
+# Node ID 8dd6c6ac977d063dbd093f092ba46e50e9bcb80b
+# Parent  fb7208e91ae8e819b38a80480f816efb32fbfab3
+Bug 1064636, follow up commit to fix Windows build bustage
+
+diff --git a/lib/cryptohi/secvfy.c b/lib/cryptohi/secvfy.c
+--- a/lib/cryptohi/secvfy.c
++++ b/lib/cryptohi/secvfy.c
+@@ -595,18 +595,18 @@ VFY_EndWithSignature(VFYContext *cx, SEC
+ 	}
+ 	break;
+       case rsaKey:
+       {
+         SECItem digest;
+         digest.data = final;
+         digest.len = part;
+ 	if (sig) {
++	    SECOidTag hashid;
+ 	    PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN);
+-	    SECOidTag hashid;
+ 	    rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid,
+ 					&cx->pkcs1RSADigestInfo,
+ 					&cx->pkcs1RSADigestInfoLen,
+ 					cx->key,
+ 					sig, cx->wincx);
+ 	    PORT_Assert(cx->hashAlg == hashid);
+ 	    if (rv != SECSuccess) {
+ 		return SECFailure;
+
diff --git a/SOURCES/cve-2014-1568-nss.patch b/SOURCES/cve-2014-1568-nss.patch
new file mode 100644
index 0000000..a97e863
--- /dev/null
+++ b/SOURCES/cve-2014-1568-nss.patch
@@ -0,0 +1,355 @@
+
+# HG changeset patch
+# User Kai Engert <kaie@kuix.de>
+# Date 1411493314 -7200
+# Node ID ad411fb64046d987272043f311ca477022c6fef4
+# Parent  70ae6afde27f9c977badc5271efa835c8a4ec4f0
+Fix bug 1064636, patch part 2, r=rrelyea
+
+diff --git a/lib/cryptohi/secvfy.c b/lib/cryptohi/secvfy.c
+--- a/lib/cryptohi/secvfy.c
++++ b/lib/cryptohi/secvfy.c
+@@ -7,121 +7,165 @@
+ 
+ #include <stdio.h>
+ #include "cryptohi.h"
+ #include "sechash.h"
+ #include "keyhi.h"
+ #include "secasn1.h"
+ #include "secoid.h"
+ #include "pk11func.h"
++#include "pkcs1sig.h"
+ #include "secdig.h"
+ #include "secerr.h"
+ #include "keyi.h"
+ 
+ /*
+-** Decrypt signature block using public key
+-** Store the hash algorithm oid tag in *tagp
+-** Store the digest in the digest buffer
+-** Store the digest length in *digestlen
++** Recover the DigestInfo from an RSA PKCS#1 signature.
++**
++** If givenDigestAlg != SEC_OID_UNKNOWN, copy givenDigestAlg to digestAlgOut.
++** Otherwise, parse the DigestInfo structure and store the decoded digest
++** algorithm into digestAlgOut.
++**
++** Store the encoded DigestInfo into digestInfo.
++** Store the DigestInfo length into digestInfoLen.
++**
++** This function does *not* verify that the AlgorithmIdentifier in the
++** DigestInfo identifies givenDigestAlg or that the DigestInfo is encoded
++** correctly; verifyPKCS1DigestInfo does that.
++**
+ ** XXX this is assuming that the signature algorithm has WITH_RSA_ENCRYPTION
+ */
+ static SECStatus
+-DecryptSigBlock(SECOidTag *tagp, unsigned char *digest,
+-		unsigned int *digestlen, unsigned int maxdigestlen,
+-		SECKEYPublicKey *key, const SECItem *sig, char *wincx)
++recoverPKCS1DigestInfo(SECOidTag givenDigestAlg,
++                       /*out*/ SECOidTag* digestAlgOut,
++                       /*out*/ unsigned char** digestInfo,
++                       /*out*/ unsigned int* digestInfoLen,
++                       SECKEYPublicKey* key,
++                       const SECItem* sig, void* wincx)
+ {
+-    SGNDigestInfo *di   = NULL;
+-    unsigned char *buf  = NULL;
+-    SECStatus      rv;
+-    SECOidTag      tag;
+-    SECItem        it;
++    SGNDigestInfo* di = NULL;
++    SECItem it;
++    PRBool rv = SECSuccess;
+ 
+-    if (key == NULL) goto loser;
++    PORT_Assert(digestAlgOut);
++    PORT_Assert(digestInfo);
++    PORT_Assert(digestInfoLen);
++    PORT_Assert(key);
++    PORT_Assert(key->keyType == rsaKey);
++    PORT_Assert(sig);
+ 
++    it.data = NULL;
+     it.len  = SECKEY_PublicKeyStrength(key);
+-    if (!it.len) goto loser;
+-    it.data = buf = (unsigned char *)PORT_Alloc(it.len);
+-    if (!buf) goto loser;
++    if (it.len != 0) {
++        it.data = (unsigned char *)PORT_Alloc(it.len);
++    }
++    if (it.len == 0 || it.data == NULL ) {
++        rv = SECFailure;
++    }
+ 
+-    /* decrypt the block */
+-    rv = PK11_VerifyRecover(key, (SECItem *)sig, &it, wincx);
+-    if (rv != SECSuccess) goto loser;
++    if (rv == SECSuccess) {
++        /* decrypt the block */
++        rv = PK11_VerifyRecover(key, sig, &it, wincx);
++    }
++    
++    if (rv == SECSuccess) {
++        if (givenDigestAlg != SEC_OID_UNKNOWN) {
++            /* We don't need to parse the DigestInfo if the caller gave us the
++             * digest algorithm to use. Later verifyPKCS1DigestInfo will verify
++             * that the DigestInfo identifies the given digest algorithm and
++             * that the DigestInfo is encoded absolutely correctly.
++             */
++            *digestInfoLen = it.len;
++            *digestInfo = (unsigned char*)it.data;
++            *digestAlgOut = givenDigestAlg;
++            return SECSuccess;
++        }
++    }
+ 
+-    di = SGN_DecodeDigestInfo(&it);
+-    if (di == NULL) goto sigloser;
++    if (rv == SECSuccess) {
++        /* The caller didn't specify a digest algorithm to use, so choose the
++         * digest algorithm by parsing the AlgorithmIdentifier within the
++         * DigestInfo.
++         */
++        di = SGN_DecodeDigestInfo(&it);
++        if (!di) {
++            rv = SECFailure;
++        }
++    }
+ 
+-    /*
+-    ** Finally we have the digest info; now we can extract the algorithm
+-    ** ID and the signature block
+-    */
+-    tag = SECOID_GetAlgorithmTag(&di->digestAlgorithm);
+-    /* Check that tag is an appropriate algorithm */
+-    if (tag == SEC_OID_UNKNOWN) {
+-	goto sigloser;
++    if (rv == SECSuccess) {
++        *digestAlgOut = SECOID_GetAlgorithmTag(&di->digestAlgorithm);
++        if (*digestAlgOut == SEC_OID_UNKNOWN) {
++            rv = SECFailure;
++        }
+     }
+-    /* make sure the "parameters" are not too bogus. */
+-    if (di->digestAlgorithm.parameters.len > 2) {
+-	goto sigloser;
++
++    if (di) {
++        SGN_DestroyDigestInfo(di);
+     }
+-    if (di->digest.len > maxdigestlen) {
+-	PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+-	goto loser;
++
++    if (rv == SECSuccess) {
++        *digestInfoLen = it.len;
++        *digestInfo = (unsigned char*)it.data;
++    } else {
++        if (it.data) {
++            PORT_Free(it.data);
++        }
++        *digestInfo = NULL;
++        *digestInfoLen = 0;
++        PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+     }
+-    PORT_Memcpy(digest, di->digest.data, di->digest.len);
+-    *tagp = tag;
+-    *digestlen = di->digest.len;
+-    goto done;
+ 
+-  sigloser:
+-    PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+-
+-  loser:
+-    rv = SECFailure;
+-
+-  done:
+-    if (di   != NULL) SGN_DestroyDigestInfo(di);
+-    if (buf  != NULL) PORT_Free(buf);
+-    
+     return rv;
+ }
+ 
+-
+ struct VFYContextStr {
+     SECOidTag hashAlg;  /* the hash algorithm */
+     SECKEYPublicKey *key;
+     /*
+      * This buffer holds either the digest or the full signature
+      * depending on the type of the signature (key->keyType).  It is
+      * defined as a union to make sure it always has enough space.
+      *
+      * Use the "buffer" union member to reference the buffer.
+      * Note: do not take the size of the "buffer" union member.  Take
+      * the size of the union or some other union member instead.
+      */
+     union {
+ 	unsigned char buffer[1];
+ 
+-	/* the digest in the decrypted RSA signature */
+-	unsigned char rsadigest[HASH_LENGTH_MAX];
+ 	/* the full DSA signature... 40 bytes */
+ 	unsigned char dsasig[DSA_MAX_SIGNATURE_LEN];
+ 	/* the full ECDSA signature */
+ 	unsigned char ecdsasig[2 * MAX_ECKEY_LEN];
+     } u;
+-    unsigned int rsadigestlen;
++    unsigned int pkcs1RSADigestInfoLen;
++    /* the encoded DigestInfo from a RSA PKCS#1 signature */
++    unsigned char *pkcs1RSADigestInfo;
+     void * wincx;
+     void *hashcx;
+     const SECHashObject *hashobj;
+     SECOidTag encAlg;  /* enc alg */
+     PRBool hasSignature;  /* true if the signature was provided in the
+                            * VFY_CreateContext call.  If false, the
+                            * signature must be provided with a
+                            * VFY_EndWithSignature call. */
+ };
+ 
++static SECStatus
++verifyPKCS1DigestInfo(const VFYContext* cx, const SECItem* digest)
++{
++  SECItem pkcs1DigestInfo;
++  pkcs1DigestInfo.data = cx->pkcs1RSADigestInfo;
++  pkcs1DigestInfo.len = cx->pkcs1RSADigestInfoLen;
++  return _SGN_VerifyPKCS1DigestInfo(
++           cx->hashAlg, digest, &pkcs1DigestInfo,
++           PR_TRUE /*XXX: unsafeAllowMissingParameters*/);
++}
++
+ /*
+  * decode the ECDSA or DSA signature from it's DER wrapping.
+  * The unwrapped/raw signature is placed in the buffer pointed
+  * to by dsig and has enough room for len bytes.
+  */
+ static SECStatus
+ decodeECorDSASignature(SECOidTag algid, const SECItem *sig, unsigned char *dsig,
+ 		       unsigned int len) {
+@@ -371,26 +415,26 @@ vfy_CreateContext(const SECKEYPublicKey 
+ 	goto loser;
+     }
+ 
+     cx->wincx = wincx;
+     cx->hasSignature = (sig != NULL);
+     cx->encAlg = encAlg;
+     cx->hashAlg = hashAlg;
+     cx->key = SECKEY_CopyPublicKey(key);
++    cx->pkcs1RSADigestInfo = NULL;
+     rv = SECSuccess;
+     if (sig) {
+ 	switch (type) {
+ 	case rsaKey:
+-	    rv = DecryptSigBlock(&cx->hashAlg, cx->u.buffer, &cx->rsadigestlen,
+-			HASH_LENGTH_MAX, cx->key, sig, (char*)wincx);
+-	    if (cx->hashAlg != hashAlg && hashAlg != SEC_OID_UNKNOWN) {
+-		PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+-		rv = SECFailure;	
+-	    }
++	    rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg,
++					&cx->pkcs1RSADigestInfo,
++					&cx->pkcs1RSADigestInfoLen,
++					cx->key,
++					sig, wincx);
+ 	    break;
+ 	case dsaKey:
+ 	case ecKey:
+ 	    sigLen = SECKEY_SignatureLen(key);
+ 	    if (sigLen == 0) {
+ 		/* error set by SECKEY_SignatureLen */
+ 		rv = SECFailure;	
+ 		break;
+@@ -464,16 +508,19 @@ VFY_DestroyContext(VFYContext *cx, PRBoo
+     if (cx) {
+ 	if (cx->hashcx != NULL) {
+ 	    (*cx->hashobj->destroy)(cx->hashcx, PR_TRUE);
+ 	    cx->hashcx = NULL;
+ 	}
+ 	if (cx->key) {
+ 	    SECKEY_DestroyPublicKey(cx->key);
+ 	}
++    if (cx->pkcs1RSADigestInfo) {
++        PORT_Free(cx->pkcs1RSADigestInfo);
++    }
+ 	if (freeit) {
+ 	    PORT_ZFree(cx, sizeof(VFYContext));
+ 	}
+     }
+ }
+ 
+ SECStatus
+ VFY_Begin(VFYContext *cx)
+@@ -543,31 +590,35 @@ VFY_EndWithSignature(VFYContext *cx, SEC
+ 	hash.data = final;
+ 	hash.len = part;
+ 	if (PK11_Verify(cx->key,&dsasig,&hash,cx->wincx) != SECSuccess) {
+ 		PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ 		return SECFailure;
+ 	}
+ 	break;
+       case rsaKey:
++      {
++        SECItem digest;
++        digest.data = final;
++        digest.len = part;
+ 	if (sig) {
+-	    SECOidTag hashid = SEC_OID_UNKNOWN;
+-	    rv = DecryptSigBlock(&hashid, cx->u.buffer, &cx->rsadigestlen,
+-		    HASH_LENGTH_MAX, cx->key, sig, (char*)cx->wincx);
+-	    if ((rv != SECSuccess) || (hashid != cx->hashAlg)) {
+-		PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
++	    PORT_Assert(cx->hashAlg != SEC_OID_UNKNOWN);
++	    SECOidTag hashid;
++	    rv = recoverPKCS1DigestInfo(cx->hashAlg, &hashid,
++					&cx->pkcs1RSADigestInfo,
++					&cx->pkcs1RSADigestInfoLen,
++					cx->key,
++					sig, cx->wincx);
++	    PORT_Assert(cx->hashAlg == hashid);
++	    if (rv != SECSuccess) {
+ 		return SECFailure;
+ 	    }
+ 	}
+-	if ((part != cx->rsadigestlen) ||
+-	    PORT_Memcmp(final, cx->u.buffer, part)) {
+-	    PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+-	    return SECFailure;
+-	}
+-	break;
++	return verifyPKCS1DigestInfo(cx, &digest);
++      }
+       default:
+ 	PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+ 	return SECFailure; /* shouldn't happen */
+     }
+     return SECSuccess;
+ }
+ 
+ SECStatus
+@@ -590,22 +641,17 @@ vfy_VerifyDigest(const SECItem *digest, 
+     SECItem dsasig; /* also used for ECDSA */
+ 
+     rv = SECFailure;
+ 
+     cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx);
+     if (cx != NULL) {
+ 	switch (key->keyType) {
+ 	case rsaKey:
+-	    if ((digest->len != cx->rsadigestlen) ||
+-		PORT_Memcmp(digest->data, cx->u.buffer, digest->len)) {
+-		PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
+-	    } else {
+-		rv = SECSuccess;
+-	    }
++	    rv = verifyPKCS1DigestInfo(cx, digest);
+ 	    break;
+ 	case dsaKey:
+ 	case ecKey:
+ 	    dsasig.data = cx->u.buffer;
+ 	    dsasig.len = SECKEY_SignatureLen(cx->key);
+ 	    if (dsasig.len == 0) {
+ 		break;
+ 	    }
+
diff --git a/SPECS/nss.spec b/SPECS/nss.spec
index 8a03293..b462558 100644
--- a/SPECS/nss.spec
+++ b/SPECS/nss.spec
@@ -21,7 +21,7 @@
 Summary:          Network Security Services
 Name:             nss
 Version:          3.16.2
-Release:          2%{?dist}
+Release:          7%{?dist}
 License:          MPLv2.0
 URL:              http://www.mozilla.org/projects/security/pki/nss/
 Group:            System Environment/Libraries
@@ -102,6 +102,9 @@ Patch56:          p-ignore-setpolicy.patch
 Patch62:          dont-hold-issuer-cert-handles-in-crl-cache.patch
 # Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1007126
 Patch63:          manfixes.patch
+# Upstream: https://bugzilla.mozilla.org/show_bug.cgi?id=1064636
+Patch77: cve-2014-1568-nss.patch
+Patch78: cve-2014-1568-nss-extra.patch
 
 %description
 Network Security Services (NSS) is a set of libraries designed to
@@ -198,6 +201,8 @@ popd
 %patch62 -p0 -b .1034409
 pushd nss
 %patch63 -p0 -b .missing_options
+%patch77 -p1 -b cve-2014-1568-nss
+%patch78 -p1 -b cve-2014-1568-nss-extra
 popd
 
 #########################################################
@@ -779,6 +784,13 @@ fi
 
 
 %changelog
+* Wed Sep 24 2014 Elio Maldonado <emaldona@redhat.com> - 3.16.2-7
+- Resolves: Bug 1145433 - CVE-2014-1568
+
+* Wed Sep 24 2014 Elio Maldonado <emaldona@redhat.com> - 3.16.2-6
+- Rolling back to commit e5fb6e476c179665976e906604496cbbb24f22a7
+- Related: Bug 1145433
+
 * Wed Aug 06 2014 Elio Maldonado <emaldona@redhat.com> - 3.16.2-2
 - Restore missing options descriptions fix for certutil manpage
 - Document certutil options --dump-ext-val, --extGeneric, and --extSAN