Beispiel #1
0
void
SECU_PrintError(const char *progName, const char *msg, ...)
{
    va_list args;
    PRErrorCode err = PORT_GetError();
    const char *errName = PR_ErrorToName(err);
    const char *errString = PR_ErrorToString(err, 0);

    va_start(args, msg);

    fprintf(stderr, "%s: ", progName);
    vfprintf(stderr, msg, args);

    if (errName != NULL) {
        fprintf(stderr, ": %s", errName);
    } else {
        fprintf(stderr, ": error %d", (int)err);
    }

    if (errString != NULL && PORT_Strlen(errString) > 0)
        fprintf(stderr, ": %s\n", errString);

    va_end(args);
}
// inputToDecoder
//
// Given a decoder, read bytes from file and input them to the decoder.
nsresult
nsPKCS12Blob::inputToDecoder(SEC_PKCS12DecoderContext *dcx, nsIFile *file)
{
  nsNSSShutDownPreventionLock locker;
  nsresult rv;
  SECStatus srv;
  PRUint32 amount;
  char buf[PIP_PKCS12_BUFFER_SIZE];

  nsCOMPtr<nsIInputStream> fileStream;
  rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
  
  if (NS_FAILED(rv)) {
    return rv;
  }

  while (true) {
    rv = fileStream->Read(buf, PIP_PKCS12_BUFFER_SIZE, &amount);
    if (NS_FAILED(rv)) {
      return rv;
    }
    // feed the file data into the decoder
    srv = SEC_PKCS12DecoderUpdate(dcx, 
				  (unsigned char*) buf, 
				  amount);
    if (srv) {
      // don't allow the close call to overwrite our precious error code
      int pr_err = PORT_GetError();
      PORT_SetError(pr_err);
      return NS_ERROR_ABORT;
    }
    if (amount < PIP_PKCS12_BUFFER_SIZE)
      break;
  }
  return NS_OK;
}
Beispiel #3
0
/**
 * Check a canonical sig+rrset and signature against a dnskey
 * @param buf: buffer with data to verify, the first rrsig part and the
 *	canonicalized rrset.
 * @param algo: DNSKEY algorithm.
 * @param sigblock: signature rdata field from RRSIG
 * @param sigblock_len: length of sigblock data.
 * @param key: public key data from DNSKEY RR.
 * @param keylen: length of keydata.
 * @param reason: bogus reason in more detail.
 * @return secure if verification succeeded, bogus on crypto failure,
 *	unchecked on format errors and alloc failures.
 */
enum sec_status
verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock, 
	unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
	char** reason)
{
	/* uses libNSS */
	/* large enough for the different hashes */
	unsigned char hash[HASH_LENGTH_MAX];
	unsigned char hash2[HASH_LENGTH_MAX*2];
	HASH_HashType htype = 0;
	SECKEYPublicKey* pubkey = NULL;
	SECItem secsig = {siBuffer, sigblock, sigblock_len};
	SECItem sechash = {siBuffer, hash, 0};
	SECStatus res;
	unsigned char* prefix = NULL; /* prefix for hash, RFC3110, RFC5702 */
	size_t prefixlen = 0;
	int err;

	if(!nss_setup_key_digest(algo, &pubkey, &htype, key, keylen,
		&prefix, &prefixlen)) {
		verbose(VERB_QUERY, "verify: failed to setup key");
		*reason = "use of key for crypto failed";
		SECKEY_DestroyPublicKey(pubkey);
		return sec_status_bogus;
	}

#if defined(USE_DSA) && defined(USE_SHA1)
	/* need to convert DSA, ECDSA signatures? */
	if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3)) {
		if(sigblock_len == 1+2*SHA1_LENGTH) {
			secsig.data ++;
			secsig.len --;
		} else {
			SECItem* p = DSAU_DecodeDerSig(&secsig);
			if(!p) {
				verbose(VERB_QUERY, "verify: failed DER decode");
				*reason = "signature DER decode failed";
				SECKEY_DestroyPublicKey(pubkey);
				return sec_status_bogus;
			}
			if(SECITEM_CopyItem(pubkey->arena, &secsig, p)) {
				log_err("alloc failure in DER decode");
				SECKEY_DestroyPublicKey(pubkey);
				SECITEM_FreeItem(p, PR_TRUE);
				return sec_status_unchecked;
			}
			SECITEM_FreeItem(p, PR_TRUE);
		}
	}
#endif /* USE_DSA */

	/* do the signature cryptography work */
	/* hash the data */
	sechash.len = HASH_ResultLen(htype);
	if(sechash.len > sizeof(hash)) {
		verbose(VERB_QUERY, "verify: hash too large for buffer");
		SECKEY_DestroyPublicKey(pubkey);
		return sec_status_unchecked;
	}
	if(HASH_HashBuf(htype, hash, (unsigned char*)sldns_buffer_begin(buf),
		(unsigned int)sldns_buffer_limit(buf)) != SECSuccess) {
		verbose(VERB_QUERY, "verify: HASH_HashBuf failed");
		SECKEY_DestroyPublicKey(pubkey);
		return sec_status_unchecked;
	}
	if(prefix) {
		int hashlen = sechash.len;
		if(prefixlen+hashlen > sizeof(hash2)) {
			verbose(VERB_QUERY, "verify: hashprefix too large");
			SECKEY_DestroyPublicKey(pubkey);
			return sec_status_unchecked;
		}
		sechash.data = hash2;
		sechash.len = prefixlen+hashlen;
		memcpy(sechash.data, prefix, prefixlen);
		memmove(sechash.data+prefixlen, hash, hashlen);
	}

	/* verify the signature */
	res = PK11_Verify(pubkey, &secsig, &sechash, NULL /*wincx*/);
	SECKEY_DestroyPublicKey(pubkey);

	if(res == SECSuccess) {
		return sec_status_secure;
	}
	err = PORT_GetError();
	if(err != SEC_ERROR_BAD_SIGNATURE) {
		/* failed to verify */
		verbose(VERB_QUERY, "verify: PK11_Verify failed: %s",
			PORT_ErrorToString(err));
		/* if it is not supported, like ECC is removed, we get,
		 * SEC_ERROR_NO_MODULE */
		if(err == SEC_ERROR_NO_MODULE)
			return sec_status_unchecked;
		/* but other errors are commonly returned
		 * for a bad signature from NSS.  Thus we return bogus,
		 * not unchecked */
		*reason = "signature crypto failed";
		return sec_status_bogus;
	}
	verbose(VERB_QUERY, "verify: signature mismatch: %s",
		PORT_ErrorToString(err));
	*reason = "signature crypto failed";
	return sec_status_bogus;
}
int main(int argc, char **argv)
{
    int rv, ascii;
    char *progName;
    FILE *outFile;
    PRFileDesc *inFile;
    SECItem der, data;
    char *typeTag;
    PLOptState *optstate;

    progName = strrchr(argv[0], '/');
    progName = progName ? progName+1 : argv[0];

    ascii = 0;
    inFile = 0;
    outFile = 0;
    typeTag = 0;
    optstate = PL_CreateOptState(argc, argv, "at:i:o:");
    while ( PL_GetNextOpt(optstate) == PL_OPT_OK ) {
	switch (optstate->option) {
	  case '?':
	    Usage(progName);
	    break;

	  case 'a':
	    ascii = 1;
	    break;

	  case 'i':
	    inFile = PR_Open(optstate->value, PR_RDONLY, 0);
	    if (!inFile) {
		fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
			progName, optstate->value);
		return -1;
	    }
	    break;

	  case 'o':
	    outFile = fopen(optstate->value, "w");
	    if (!outFile) {
		fprintf(stderr, "%s: unable to open \"%s\" for writing\n",
			progName, optstate->value);
		return -1;
	    }
	    break;

	  case 't':
	    typeTag = strdup(optstate->value);
	    break;
	}
    }
    PL_DestroyOptState(optstate);
    if (!typeTag) Usage(progName);

    if (!inFile) inFile = PR_STDIN;
    if (!outFile) outFile = stdout;

    PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
    rv = NSS_NoDB_Init(NULL);
    if (rv != SECSuccess) {
	fprintf(stderr, "%s: NSS_NoDB_Init failed (%s)\n",
		progName, SECU_Strerror(PORT_GetError()));
	exit(1);
    }
    SECU_RegisterDynamicOids();

    rv = SECU_ReadDERFromFile(&der, inFile, ascii, PR_FALSE);
    if (rv != SECSuccess) {
	fprintf(stderr, "%s: SECU_ReadDERFromFile failed\n", progName);
	exit(1);
    }

    /* Data is untyped, using the specified type */
    data.data = der.data;
    data.len = der.len;

    /* Pretty print it */
    if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0) {
	rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0,
			     SECU_PrintCertificate);
    } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0) {
        PRBool saveWrapeState = SECU_GetWrapEnabled();
        SECU_EnableWrap(PR_FALSE);
        rv = SECU_PrintSignedContent(outFile, &data, 0, 0,
                                     SECU_PrintDumpDerIssuerAndSerial);
        SECU_EnableWrap(saveWrapeState);
    } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0) {
	rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0,
			     SECU_PrintCertificateRequest);
    } else if (PORT_Strcmp (typeTag, SEC_CT_CRL) == 0) {
	rv = SECU_PrintSignedData (outFile, &data, "CRL", 0, SECU_PrintCrl);
#ifdef HAVE_EPV_TEMPLATE
    } else if (PORT_Strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0) {
	rv = SECU_PrintPrivateKey(outFile, &data, "Private Key", 0);
#endif
    } else if (PORT_Strcmp(typeTag, SEC_CT_PUBLIC_KEY) == 0) {
	rv = SECU_PrintSubjectPublicKeyInfo(outFile, &data, "Public Key", 0);
    } else if (PORT_Strcmp(typeTag, SEC_CT_PKCS7) == 0) {
	rv = SECU_PrintPKCS7ContentInfo(outFile, &data,
					"PKCS #7 Content Info", 0);
    } else if (PORT_Strcmp(typeTag, SEC_CT_NAME) == 0) {
	rv = SECU_PrintDERName(outFile, &data, "Name", 0);
    } else {
	fprintf(stderr, "%s: don't know how to print out '%s' files\n",
		progName, typeTag);
	SECU_PrintAny(outFile, &data, "File contains", 0);
	return -1;
    }

    if (inFile != PR_STDIN)
	PR_Close(inFile);
    PORT_Free(der.data);
    if (rv) {
	fprintf(stderr, "%s: problem converting data (%s)\n",
		progName, SECU_Strerror(PORT_GetError()));
    }
    if (NSS_Shutdown() != SECSuccess) {
	fprintf(stderr, "%s: NSS_Shutdown failed (%s)\n",
		progName, SECU_Strerror(PORT_GetError()));
	rv = SECFailure;
    }
    PR_Cleanup();
    return rv;
}
Beispiel #5
0
SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type, 
                     PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions,
                     secuPWData *pwdata)
{
    CERTSignedCrl *crl = NULL;
    SECItem crlDER;
    PK11SlotInfo* slot = NULL;
    int rv;
#if defined(DEBUG_jp96085)
    PRIntervalTime starttime, endtime, elapsed;
    PRUint32 mins, secs, msecs;
#endif

    crlDER.data = NULL;


    /* Read in the entire file specified with the -f argument */
    rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE, PR_FALSE);
    if (rv != SECSuccess) {
	SECU_PrintError(progName, "unable to read input file");
	return (SECFailure);
    }

    decodeOptions |= CRL_DECODE_DONT_COPY_DER;

    slot = PK11_GetInternalKeySlot();

    if (PK11_NeedLogin(slot)) {
	rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
    if (rv != SECSuccess)
	goto loser;
    }
 
#if defined(DEBUG_jp96085)
    starttime = PR_IntervalNow();
#endif
    crl = PK11_ImportCRL(slot, &crlDER, url, type,
          NULL, importOptions, NULL, decodeOptions);
#if defined(DEBUG_jp96085)
    endtime = PR_IntervalNow();
    elapsed = endtime - starttime;
    mins = PR_IntervalToSeconds(elapsed) / 60;
    secs = PR_IntervalToSeconds(elapsed) % 60;
    msecs = PR_IntervalToMilliseconds(elapsed) % 1000;
    printf("Elapsed : %2d:%2d.%3d\n", mins, secs, msecs);
#endif
    if (!crl) {
	const char *errString;

	rv = SECFailure;
	errString = SECU_Strerror(PORT_GetError());
	if ( errString && PORT_Strlen (errString) == 0)
	    SECU_PrintError (progName, 
	        "CRL is not imported (error: input CRL is not up to date.)");
	else    
	    SECU_PrintError (progName, "unable to import CRL");
    } else {
	SEC_DestroyCrl (crl);
    }
  loser:
    if (slot) {
        PK11_FreeSlot(slot);
    }
    return (rv);
}
Beispiel #6
0
/************************************************************************
 *
 * J a r W h o
 */
int
JarWho(char *filename)
{
    FILE *fp;

    JAR *jar;
    JAR_Context *ctx;

    int status;
    int retval = 0;

    JAR_Item *it;
    JAR_Cert *fing;

    CERTCertificate *cert, *prev = NULL;

    jar = JAR_new();

    if ((fp = fopen(filename, "r")) == NULL) {
        perror(filename);
        exit(ERRX);
    }
    fclose(fp);

    status = JAR_pass_archive(jar, jarArchGuess, filename, "some-url");

    if (status < 0 || jar->valid < 0) {
        PR_fprintf(outputFD,
                   "NOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
                   filename);
        retval = -1;
        if (jar->valid < 0 || status != -1) {
            const char *errtext;

            if (status >= JAR_BASE && status <= JAR_BASE_END) {
                errtext = JAR_get_error(status);
            } else {
                errtext = SECU_Strerror(PORT_GetError());
            }

            PR_fprintf(outputFD, "  (reported reason: %s)\n\n", errtext);
        }
    }

    PR_fprintf(outputFD, "\nSigner information:\n\n");

    ctx = JAR_find(jar, NULL, jarTypeSign);

    while (JAR_find_next(ctx, &it) >= 0) {
        fing = (JAR_Cert *)it->data;
        cert = fing->cert;

        if (cert) {
            if (prev == cert)
                break;

            if (cert->nickname)
                PR_fprintf(outputFD, "nickname: %s\n", cert->nickname);
            if (cert->subjectName)
                PR_fprintf(outputFD, "subject name: %s\n",
                           cert->subjectName);
            if (cert->issuerName)
                PR_fprintf(outputFD, "issuer name: %s\n", cert->issuerName);
        } else {
            PR_fprintf(outputFD, "no certificate could be found\n");
            retval = -1;
        }

        prev = cert;
    }

    JAR_find_end(ctx);

    JAR_destroy(jar);
    return retval;
}
Beispiel #7
0
/* Caller holds the SSL Socket's write lock. SSL_LOCK_WRITER(ss) */
int
ssl_SecureSend(sslSocket *ss, const unsigned char *buf, int len, int flags)
{
    int rv = 0;
    PRBool falseStart = PR_FALSE;

    SSL_TRC(2, ("%d: SSL[%d]: SecureSend: sending %d bytes",
		SSL_GETPID(), ss->fd, len));

    if (ss->shutdownHow & ssl_SHUTDOWN_SEND) {
	PORT_SetError(PR_SOCKET_SHUTDOWN_ERROR);
    	rv = PR_FAILURE;
	goto done;
    }
    if (flags) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
    	rv = PR_FAILURE;
	goto done;
    }

    ssl_GetXmitBufLock(ss);
    if (ss->pendingBuf.len != 0) {
	PORT_Assert(ss->pendingBuf.len > 0);
	rv = ssl_SendSavedWriteData(ss);
	if (rv >= 0 && ss->pendingBuf.len != 0) {
	    PORT_Assert(ss->pendingBuf.len > 0);
	    PORT_SetError(PR_WOULD_BLOCK_ERROR);
	    rv = SECFailure;
	}
    }
    ssl_ReleaseXmitBufLock(ss);
    if (rv < 0) {
	goto done;
    }

    if (len > 0) 
    	ss->writerThread = PR_GetCurrentThread();
    /* If any of these is non-zero, the initial handshake is not done. */
    if (!ss->firstHsDone) {
	ssl_Get1stHandshakeLock(ss);
	if (ss->opt.enableFalseStart &&
	    ss->version >= SSL_LIBRARY_VERSION_3_0) {
	    ssl_GetSSL3HandshakeLock(ss);
	    falseStart = ss->ssl3.hs.canFalseStart;
	    ssl_ReleaseSSL3HandshakeLock(ss);
	}
	if (!falseStart &&
	    (ss->handshake || ss->nextHandshake || ss->securityHandshake)) {
	    rv = ssl_Do1stHandshake(ss);
	}
	ssl_Release1stHandshakeLock(ss);
    }
    if (rv < 0) {
    	ss->writerThread = NULL;
	goto done;
    }

    /* Check for zero length writes after we do housekeeping so we make forward
     * progress.
     */
    if (len == 0) {
    	rv = 0;
	goto done;
    }
    PORT_Assert(buf != NULL);
    if (!buf) {
	PORT_SetError(PR_INVALID_ARGUMENT_ERROR);
    	rv = PR_FAILURE;
	goto done;
    }

    if (!ss->firstHsDone) {
	PORT_Assert(ss->version >= SSL_LIBRARY_VERSION_3_0);
#ifdef DEBUG
	ssl_GetSSL3HandshakeLock(ss);
	PORT_Assert(ss->ssl3.hs.canFalseStart);
	ssl_ReleaseSSL3HandshakeLock(ss);
#endif
	SSL_TRC(3, ("%d: SSL[%d]: SecureSend: sending data due to false start",
		    SSL_GETPID(), ss->fd));
    }

    /* Send out the data using one of these functions:
     *	ssl2_SendClear, ssl2_SendStream, ssl2_SendBlock, 
     *  ssl3_SendApplicationData
     */
    ssl_GetXmitBufLock(ss);
    rv = (*ss->sec.send)(ss, buf, len, flags);
    ssl_ReleaseXmitBufLock(ss);
    ss->writerThread = NULL;
done:
    if (rv < 0) {
	SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count, error %d",
		    SSL_GETPID(), ss->fd, rv, PORT_GetError()));
    } else {
	SSL_TRC(2, ("%d: SSL[%d]: SecureSend: returning %d count",
		    SSL_GETPID(), ss->fd, rv));
    }
    return rv;
}
static CamelCipherValidity *
sm_decrypt(CamelCipherContext *context, CamelMimePart *ipart, CamelMimePart *opart, CamelException *ex)
{
	NSSCMSDecoderContext *dec;
	NSSCMSMessage *cmsg;
	CamelStreamMem *istream;
	CamelStream *ostream;
	CamelCipherValidity *valid = NULL;

	/* FIXME: This assumes the content is only encrypted.  Perhaps its ok for
	   this api to do this ... */

	ostream = camel_stream_mem_new();
	camel_stream_mem_set_secure((CamelStreamMem *)ostream);

	/* FIXME: stream this to the decoder incrementally */
	istream = (CamelStreamMem *)camel_stream_mem_new();
	camel_data_wrapper_decode_to_stream(camel_medium_get_content_object((CamelMedium *)ipart), (CamelStream *)istream);
	camel_stream_reset((CamelStream *)istream);

	dec = NSS_CMSDecoder_Start(NULL,
				   sm_write_stream, ostream, /* content callback     */
				   NULL, NULL,
				   NULL, NULL); /* decrypt key callback */

	if (NSS_CMSDecoder_Update(dec, (char *) istream->buffer->data, istream->buffer->len) != SECSuccess) {
		printf("decoder update failed\n");
	}
	camel_object_unref(istream);

	cmsg = NSS_CMSDecoder_Finish(dec);
	if (cmsg == NULL) {
		camel_exception_setv(ex, CAMEL_EXCEPTION_SYSTEM, _("Decoder failed, error %d"), PORT_GetError());
		goto fail;
	}

#if 0
	/* not sure if we really care about this? */
	if (!NSS_CMSMessage_IsEncrypted(cmsg)) {
		camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, _("S/MIME Decrypt: No encrypted content found"));
		NSS_CMSMessage_Destroy(cmsg);
		goto fail;
	}
#endif

	camel_stream_reset(ostream);
	camel_data_wrapper_construct_from_stream((CamelDataWrapper *)opart, ostream);

	if (NSS_CMSMessage_IsSigned(cmsg)) {
		valid = sm_verify_cmsg(context, cmsg, NULL, ex);
	} else {
		valid = camel_cipher_validity_new();
		valid->encrypt.description = g_strdup(_("Encrypted content"));
		valid->encrypt.status = CAMEL_CIPHER_VALIDITY_ENCRYPT_ENCRYPTED;
	}

	NSS_CMSMessage_Destroy(cmsg);
fail:
	camel_object_unref(ostream);

	return valid;
}
Beispiel #9
0
SECStatus
PRNGTEST_RunHealthTests()
{
   static const PRUint8 entropy[] = {
			0x8e,0x9c,0x0d,0x25,0x75,0x22,0x04,0xf9,
			0xc5,0x79,0x10,0x8b,0x23,0x79,0x37,0x14,
			0x9f,0x2c,0xc7,0x0b,0x39,0xf8,0xee,0xef,
			0x95,0x0c,0x97,0x59,0xfc,0x0a,0x85,0x41,
			0x76,0x9d,0x6d,0x67,0x00,0x4e,0x19,0x12,
			0x02,0x16,0x53,0xea,0xf2,0x73,0xd7,0xd6,
			0x7f,0x7e,0xc8,0xae,0x9c,0x09,0x99,0x7d,
			0xbb,0x9e,0x48,0x7f,0xbb,0x96,0x46,0xb3,
			0x03,0x75,0xf8,0xc8,0x69,0x45,0x3f,0x97,
			0x5e,0x2e,0x48,0xe1,0x5d,0x58,0x97,0x4c };
   static const PRUint8 rng_known_result[] = {
			0x16,0xe1,0x8c,0x57,0x21,0xd8,0xf1,0x7e,
			0x5a,0xa0,0x16,0x0b,0x7e,0xa6,0x25,0xb4,
			0x24,0x19,0xdb,0x54,0xfa,0x35,0x13,0x66,
			0xbb,0xaa,0x2a,0x1b,0x22,0x33,0x2e,0x4a,
			0x14,0x07,0x9d,0x52,0xfc,0x73,0x61,0x48,
			0xac,0xc1,0x22,0xfc,0xa4,0xfc,0xac,0xa4,
			0xdb,0xda,0x5b,0x27,0x33,0xc4,0xb3 };
   static const PRUint8 reseed_entropy[] = {
			0xc6,0x0b,0x0a,0x30,0x67,0x07,0xf4,0xe2,
			0x24,0xa7,0x51,0x6f,0x5f,0x85,0x3e,0x5d,
			0x67,0x97,0xb8,0x3b,0x30,0x9c,0x7a,0xb1,
			0x52,0xc6,0x1b,0xc9,0x46,0xa8,0x62,0x79 };
   static const PRUint8 additional_input[] = {
			0x86,0x82,0x28,0x98,0xe7,0xcb,0x01,0x14,
			0xae,0x87,0x4b,0x1d,0x99,0x1b,0xc7,0x41,
			0x33,0xff,0x33,0x66,0x40,0x95,0x54,0xc6,
			0x67,0x4d,0x40,0x2a,0x1f,0xf9,0xeb,0x65 };
   static const PRUint8 rng_reseed_result[] = {
			0x02,0x0c,0xc6,0x17,0x86,0x49,0xba,0xc4,
			0x7b,0x71,0x35,0x05,0xf0,0xdb,0x4a,0xc2,
			0x2c,0x38,0xc1,0xa4,0x42,0xe5,0x46,0x4a,
			0x7d,0xf0,0xbe,0x47,0x88,0xb8,0x0e,0xc6,
			0x25,0x2b,0x1d,0x13,0xef,0xa6,0x87,0x96,
			0xa3,0x7d,0x5b,0x80,0xc2,0x38,0x76,0x61,
			0xc7,0x80,0x5d,0x0f,0x05,0x76,0x85 };
   static const PRUint8 rng_no_reseed_result[] = {
			0xc4,0x40,0x41,0x8c,0xbf,0x2f,0x70,0x23,
			0x88,0xf2,0x7b,0x30,0xc3,0xca,0x1e,0xf3,
			0xef,0x53,0x81,0x5d,0x30,0xed,0x4c,0xf1,
			0xff,0x89,0xa5,0xee,0x92,0xf8,0xc0,0x0f,
			0x88,0x53,0xdf,0xb6,0x76,0xf0,0xaa,0xd3,
			0x2e,0x1d,0x64,0x37,0x3e,0xe8,0x4a,0x02,
			0xff,0x0a,0x7f,0xe5,0xe9,0x2b,0x6d };

   SECStatus rng_status = SECSuccess;
   PR_STATIC_ASSERT(sizeof(rng_known_result) >= sizeof(rng_reseed_result));
   PRUint8 result[sizeof(rng_known_result)];

   /********************************************/
   /*   First test instantiate error path.     */
   /*   In this case we supply enough entropy, */
   /*   but not enough seed. This will trigger */
   /*   the code that checks for a entropy     */
   /*   source failure.                        */
   /********************************************/
   rng_status = PRNGTEST_Instantiate(entropy, 256/PR_BITS_PER_BYTE, 
				     NULL, 0, NULL, 0);
   if (rng_status == SECSuccess) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   /* we failed with the proper error code, we can continue */

   /********************************************/
   /* Generate random bytes with a known seed. */
   /********************************************/
   rng_status = PRNGTEST_Instantiate(entropy, sizeof entropy, 
				     NULL, 0, NULL, 0);
   if (rng_status != SECSuccess) {
	/* Error set by PRNGTEST_Instantiate */
	return SECFailure;
   }
   rng_status = PRNGTEST_Generate(result, sizeof rng_known_result, NULL, 0);
   if ( ( rng_status != SECSuccess)  ||
        ( PORT_Memcmp( result, rng_known_result,
                       sizeof rng_known_result ) != 0 ) ) {
	PRNGTEST_Uninstantiate();
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   rng_status = PRNGTEST_Reseed(reseed_entropy, sizeof reseed_entropy,
				additional_input, sizeof additional_input);
   if (rng_status != SECSuccess) {
	/* Error set by PRNG_Reseed */
	PRNGTEST_Uninstantiate();
	return SECFailure;
   }
   rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
   if ( ( rng_status != SECSuccess)  ||
        ( PORT_Memcmp( result, rng_reseed_result,
                       sizeof rng_reseed_result ) != 0 ) ) {
	PRNGTEST_Uninstantiate();
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   /* This magic forces the reseed count to it's max count, so we can see if
    * PRNGTEST_Generate will actually when it reaches it's count */
   rng_status = PRNGTEST_Reseed(NULL, 0, NULL, 0);
   if (rng_status != SECSuccess) {
	PRNGTEST_Uninstantiate();
	/* Error set by PRNG_Reseed */
	return SECFailure;
   }
   /* This generate should now reseed */
   rng_status = PRNGTEST_Generate(result, sizeof rng_reseed_result, NULL, 0);
   if ( ( rng_status != SECSuccess)  ||
	/* NOTE we fail if the result is equal to the no_reseed_result. 
         * no_reseed_result is the value we would have gotten if we didn't
	 * do an automatic reseed in PRNGTEST_Generate */
        ( PORT_Memcmp( result, rng_no_reseed_result,
                       sizeof rng_no_reseed_result ) == 0 ) ) {
	PRNGTEST_Uninstantiate();
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   /* make sure reseed fails when we don't supply enough entropy */
   rng_status = PRNGTEST_Reseed(reseed_entropy, 4, NULL, 0);
   if (rng_status == SECSuccess) {
	PRNGTEST_Uninstantiate();
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   if (PORT_GetError() != SEC_ERROR_NEED_RANDOM) {
	PRNGTEST_Uninstantiate();
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   rng_status = PRNGTEST_Uninstantiate();
   if (rng_status != SECSuccess) {
	/* Error set by PRNG_Uninstantiate */
	return rng_status;
   }
   /* make sure uninstantiate fails if the contest is not initiated (also tests
    * if the context was cleared in the previous Uninstantiate) */
   rng_status = PRNGTEST_Uninstantiate();
   if (rng_status == SECSuccess) {
	PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
	return SECFailure;
   }
   if (PORT_GetError() != SEC_ERROR_LIBRARY_FAILURE) {
	return rng_status;
   }
  
   return SECSuccess;
}
Beispiel #10
0
/* Gather in a record and when complete, Handle that record.
 * Repeat this until the handshake is complete,
 * or until application data is available.
 *
 * Returns  1 when the handshake is completed without error, or
 *                 application data is available.
 * Returns  0 if ssl3_GatherData hits EOF.
 * Returns -1 on read error, or PR_WOULD_BLOCK_ERROR, or handleRecord error.
 * Returns -2 on SECWouldBlock return from ssl3_HandleRecord.
 *
 * Called from ssl_GatherRecord1stHandshake       in sslcon.c,
 *    and from SSL_ForceHandshake in sslsecur.c
 *    and from ssl3_GatherAppDataRecord below (<- DoRecv in sslsecur.c).
 *
 * Caller must hold the recv buf lock.
 */
int
ssl3_GatherCompleteHandshake(sslSocket *ss, int flags)
{
    SSL3Ciphertext cText;
    int rv;
    PRBool keepGoing = PR_TRUE;

    SSL_TRC(30, ("ssl3_GatherCompleteHandshake"));

    /* ssl3_HandleRecord may end up eventually calling ssl_FinishHandshake,
     * which requires the 1stHandshakeLock, which must be acquired before the
     * RecvBufLock.
     */
    PORT_Assert(ss->opt.noLocks || ssl_Have1stHandshakeLock(ss));
    PORT_Assert(ss->opt.noLocks || ssl_HaveRecvBufLock(ss));

    do {
        PRBool handleRecordNow = PR_FALSE;

        ssl_GetSSL3HandshakeLock(ss);

        /* Without this, we may end up wrongly reporting
         * SSL_ERROR_RX_UNEXPECTED_* errors if we receive any records from the
         * peer while we are waiting to be restarted.
         */
        if (ss->ssl3.hs.restartTarget) {
            ssl_ReleaseSSL3HandshakeLock(ss);
            PORT_SetError(PR_WOULD_BLOCK_ERROR);
            return (int)SECFailure;
        }

        /* Treat an empty msgState like a NULL msgState. (Most of the time
         * when ssl3_HandleHandshake returns SECWouldBlock, it leaves
         * behind a non-NULL but zero-length msgState).
         * Test: async_cert_restart_server_sends_hello_request_first_in_separate_record
         */
        if (ss->ssl3.hs.msgState.buf) {
            if (ss->ssl3.hs.msgState.len == 0) {
                ss->ssl3.hs.msgState.buf = NULL;
            } else {
                handleRecordNow = PR_TRUE;
            }
        }

        ssl_ReleaseSSL3HandshakeLock(ss);

        if (handleRecordNow) {
            /* ssl3_HandleHandshake previously returned SECWouldBlock and the
             * as-yet-unprocessed plaintext of that previous handshake record.
             * We need to process it now before we overwrite it with the next
             * handshake record.
             */
            rv = ssl3_HandleRecord(ss, NULL, &ss->gs.buf);
        } else {
            /* bring in the next sslv3 record. */
            if (ss->recvdCloseNotify) {
                /* RFC 5246 Section 7.2.1:
                 *   Any data received after a closure alert is ignored.
                 */
                return 0;
            }
            if (!IS_DTLS(ss)) {
                rv = ssl3_GatherData(ss, &ss->gs, flags);
            } else {
                rv = dtls_GatherData(ss, &ss->gs, flags);

                /* If we got a would block error, that means that no data was
                 * available, so we check the timer to see if it's time to
                 * retransmit */
                if (rv == SECFailure &&
                    (PORT_GetError() == PR_WOULD_BLOCK_ERROR)) {
                    ssl_GetSSL3HandshakeLock(ss);
                    dtls_CheckTimer(ss);
                    ssl_ReleaseSSL3HandshakeLock(ss);
                    /* Restore the error in case something succeeded */
                    PORT_SetError(PR_WOULD_BLOCK_ERROR);
                }
            }

            if (rv <= 0) {
                return rv;
            }

            /* decipher it, and handle it if it's a handshake.
             * If it's application data, ss->gs.buf will not be empty upon return.
             * If it's a change cipher spec, alert, or handshake message,
             * ss->gs.buf.len will be 0 when ssl3_HandleRecord returns SECSuccess.
             */
            cText.type = (SSL3ContentType)ss->gs.hdr[0];
            cText.version = (ss->gs.hdr[1] << 8) | ss->gs.hdr[2];

            if (IS_DTLS(ss)) {
                int i;

                cText.version = dtls_DTLSVersionToTLSVersion(cText.version);
                /* DTLS sequence number */
                cText.seq_num.high = 0;
                cText.seq_num.low = 0;
                for (i = 0; i < 4; i++) {
                    cText.seq_num.high <<= 8;
                    cText.seq_num.low <<= 8;
                    cText.seq_num.high |= ss->gs.hdr[3 + i];
                    cText.seq_num.low |= ss->gs.hdr[7 + i];
                }
            }

            cText.buf = &ss->gs.inbuf;
            rv = ssl3_HandleRecord(ss, &cText, &ss->gs.buf);
        }
        if (rv < 0) {
            return ss->recvdCloseNotify ? 0 : rv;
        }
        if (ss->gs.buf.len > 0) {
            /* We have application data to return to the application. This
             * prioritizes returning application data to the application over
             * completing any renegotiation handshake we may be doing.
             */
            PORT_Assert(ss->firstHsDone);
            PORT_Assert(cText.type == content_application_data);
            break;
        }

        PORT_Assert(keepGoing);
        ssl_GetSSL3HandshakeLock(ss);
        if (ss->ssl3.hs.ws == idle_handshake) {
            /* We are done with the current handshake so stop trying to
             * handshake. Note that it would be safe to test ss->firstHsDone
             * instead of ss->ssl3.hs.ws. By testing ss->ssl3.hs.ws instead,
             * we prioritize completing a renegotiation handshake over sending
             * application data.
             */
            PORT_Assert(ss->firstHsDone);
            PORT_Assert(!ss->ssl3.hs.canFalseStart);
            keepGoing = PR_FALSE;
        } else if (ss->ssl3.hs.canFalseStart) {
            /* Prioritize sending application data over trying to complete
             * the handshake if we're false starting.
             *
             * If we were to do this check at the beginning of the loop instead
             * of here, then this function would become be a no-op after
             * receiving the ServerHelloDone in the false start case, and we
             * would never complete the handshake.
             */
            PORT_Assert(!ss->firstHsDone);

            if (ssl3_WaitingForServerSecondRound(ss)) {
                keepGoing = PR_FALSE;
            } else {
                ss->ssl3.hs.canFalseStart = PR_FALSE;
            }
        }
        ssl_ReleaseSSL3HandshakeLock(ss);
    } while (keepGoing);

    ss->gs.readOffset = 0;
    ss->gs.writeOffset = ss->gs.buf.len;
    return 1;
}
Beispiel #11
0
/*
 * This thread looks for card and reader insertions and puts events on the
 * event queue
 */
static void
vcard_emul_event_thread(void *arg)
{
    PK11SlotInfo *slot;
    VReader *vreader;
    VReaderEmul *vreader_emul;
    VCard *vcard;
    SECMODModule *module = (SECMODModule *)arg;

    do {
        /*
         * XXX - the latency value doesn't matter one bit. you only get no
         * blocking (flags |= CKF_DONT_BLOCK) or PKCS11_WAIT_LATENCY (==500),
         * hard coded in coolkey.  And it isn't coolkey's fault - the timeout
         * value we pass get's dropped on the floor before C_WaitForSlotEvent
         * is called.
         */
        slot = SECMOD_WaitForAnyTokenEvent(module, 0, 500);
        if (slot == NULL) {
            /* this could be just a no event indication */
            if (PORT_GetError() == SEC_ERROR_NO_EVENT) {
                continue;
            }
            break;
        }
        vreader = vcard_emul_find_vreader_from_slot(slot);
        if (vreader == NULL) {
            /* new vreader */
            vreader_emul = vreader_emul_new(slot, default_card_type,
                                            default_type_params);
            vreader = vreader_new(PK11_GetSlotName(slot), vreader_emul,
                                  vreader_emul_delete);
            PK11_FreeSlot(slot);
            slot = NULL;
            vreader_add_reader(vreader);
            vreader_free(vreader);
            continue;
        }
        /* card remove/insert */
        vreader_emul = vreader_get_private(vreader);
        if (PK11_IsPresent(slot)) {
            int series = PK11_GetSlotSeries(slot);
            if (series != vreader_emul->series) {
                if (vreader_emul->present) {
                    vreader_insert_card(vreader, NULL);
                }
                vcard = vcard_emul_mirror_card(vreader);
                vreader_insert_card(vreader, vcard);
                vcard_free(vcard);
            }
            vreader_emul->series = series;
            vreader_emul->present = 1;
            vreader_free(vreader);
            PK11_FreeSlot(slot);
            continue;
        }
        if (vreader_emul->present) {
            vreader_insert_card(vreader, NULL);
        }
        vreader_emul->series = 0;
        vreader_emul->present = 0;
        PK11_FreeSlot(slot);
        vreader_free(vreader);
    } while (1);
}
Beispiel #12
0
/* RSA sign/decrypt with the key, signature happens 'in place' */
vcard_7816_status_t
vcard_emul_rsa_op(VCard *card, VCardKey *key,
                  unsigned char *buffer, int buffer_size)
{
    SECKEYPrivateKey *priv_key;
    unsigned signature_len;
    PK11SlotInfo *slot;
    SECStatus rv;
    unsigned char buf[2048];
    unsigned char *bp = NULL;
    int pad_len;
    vcard_7816_status_t ret = VCARD7816_STATUS_SUCCESS;

    if ((!nss_emul_init) || (key == NULL)) {
        /* couldn't get the key, indicate that we aren't logged in */
        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
    }
    priv_key = vcard_emul_get_nss_key(key);
    if (priv_key == NULL) {
        /* couldn't get the key, indicate that we aren't logged in */
        return VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED;
    }
    slot = vcard_emul_card_get_slot(card);

    /*
     * this is only true of the rsa signature
     */
    signature_len = PK11_SignatureLen(priv_key);
    if (buffer_size != signature_len) {
        return  VCARD7816_STATUS_ERROR_DATA_INVALID;
    }
    /* be able to handle larger keys if necessariy */
    bp = &buf[0];
    if (sizeof(buf) < signature_len) {
        bp = g_malloc(signature_len);
    }

    /*
     * do the raw operations. Some tokens claim to do CKM_RSA_X_509, but then
     * choke when they try to do the actual operations. Try to detect
     * those cases and treat them as if the token didn't claim support for
     * X_509.
     */
    if (key->failedX509 != VCardEmulTrue
                              && PK11_DoesMechanism(slot, CKM_RSA_X_509)) {
        rv = PK11_PrivDecryptRaw(priv_key, bp, &signature_len, signature_len,
                                 buffer, buffer_size);
        if (rv == SECSuccess) {
            assert(buffer_size == signature_len);
            memcpy(buffer, bp, signature_len);
            key->failedX509 = VCardEmulFalse;
            goto cleanup;
        }
        /*
         * we've had a successful X509 operation, this failure must be
         * somethine else
         */
        if (key->failedX509 == VCardEmulFalse) {
            ret = vcard_emul_map_error(PORT_GetError());
            goto cleanup;
        }
        /*
         * key->failedX509 must be Unknown at this point, try the
         * non-x_509 case
         */
    }
    /* token does not support CKM_RSA_X509, emulate that with CKM_RSA_PKCS */
    /* is this a PKCS #1 formatted signature? */
    if ((buffer[0] == 0) && (buffer[1] == 1)) {
        int i;

        for (i = 2; i < buffer_size; i++) {
            /* rsa signature pad */
            if (buffer[i] != 0xff) {
                break;
            }
        }
        if ((i < buffer_size) && (buffer[i] == 0)) {
            /* yes, we have a properly formated PKCS #1 signature */
            /*
             * NOTE: even if we accidentally got an encrypt buffer, which
             * through shear luck started with 00, 01, ff, 00, it won't matter
             * because the resulting Sign operation will effectively decrypt
             * the real buffer.
             */
            SECItem signature;
            SECItem hash;

            i++;
            hash.data = &buffer[i];
            hash.len = buffer_size - i;
            signature.data = bp;
            signature.len = signature_len;
            rv = PK11_Sign(priv_key,  &signature, &hash);
            if (rv != SECSuccess) {
                ret = vcard_emul_map_error(PORT_GetError());
                goto cleanup;
            }
            assert(buffer_size == signature.len);
            memcpy(buffer, bp, signature.len);
            /*
             * we got here because either the X509 attempt failed, or the
             * token couldn't do the X509 operation, in either case stay
             * with the PKCS version for future operations on this key
             */
            key->failedX509 = VCardEmulTrue;
            goto cleanup;
        }
    }
    pad_len = buffer_size - signature_len;
    assert(pad_len < 4);
    /*
     * OK now we've decrypted the payload, package it up in PKCS #1 for the
     * upper layer.
     */
    buffer[0] = 0;
    buffer[1] = 2; /* RSA_encrypt  */
    pad_len -= 3; /* format is 0 || 2 || pad || 0 || data */
    /*
     * padding for PKCS #1 encrypted data is a string of random bytes. The
     * random butes protect against potential decryption attacks against RSA.
     * Since PrivDecrypt has already stripped those bytes, we can't reconstruct
     * them. This shouldn't matter to the upper level code which should just
     * strip this code out anyway, so We'll pad with a constant 3.
     */
    memset(&buffer[2], 0x03, pad_len);
    pad_len += 2; /* index to the end of the pad */
    buffer[pad_len] = 0;
    pad_len++; /* index to the start of the data */
    memcpy(&buffer[pad_len], bp, signature_len);
    /*
     * we got here because either the X509 attempt failed, or the
     * token couldn't do the X509 operation, in either case stay
     * with the PKCS version for future operations on this key
     */
    key->failedX509 = VCardEmulTrue;
cleanup:
    if (bp != buf) {
        g_free(bp);
    }
    return ret;
}
static gboolean
watch_one_event_from_driver (GsdSmartcardManager       *self,
                             WatchSmartcardsOperation  *operation,
                             GCancellable              *cancellable,
                             GError                   **error)
{
        GsdSmartcardManagerPrivate *priv = self->priv;
        PK11SlotInfo *card, *old_card;
        CK_SLOT_ID slot_id;
        gulong handler_id;
        int old_slot_series = -1, slot_series;

        handler_id = g_cancellable_connect (cancellable,
                                            G_CALLBACK (on_watch_cancelled),
                                            operation,
                                            NULL);

        card = SECMOD_WaitForAnyTokenEvent (operation->driver, 0, PR_SecondsToInterval (1));

        g_cancellable_disconnect (cancellable, handler_id);

        if (g_cancellable_set_error_if_cancelled (cancellable, error)) {
                g_warning ("smartcard event function cancelled");
                return FALSE;
        }

        if (card == NULL) {
                int error_code;

                error_code = PORT_GetError ();

                operation->number_of_consecutive_errors++;
                if (operation->number_of_consecutive_errors > 10) {
                     g_warning ("Got %d consecutive smartcard errors, so giving up.",
                                operation->number_of_consecutive_errors);

                     g_set_error (error,
                                  GSD_SMARTCARD_MANAGER_ERROR,
                                  GSD_SMARTCARD_MANAGER_ERROR_WITH_NSS,
                                  "encountered unexpected error while "
                                  "waiting for smartcard events (error %x)",
                                  error_code);
                     return FALSE;
                }

                g_warning ("Got potentially spurious smartcard event error: %x.", error_code);

                g_usleep (0.5 * G_USEC_PER_SEC);
                return TRUE;
        }
        operation->number_of_consecutive_errors = 0;

        slot_id = PK11_GetSlotID (card);
        slot_series = PK11_GetSlotSeries (card);

        old_card = g_hash_table_lookup (operation->smartcards, GINT_TO_POINTER ((int) slot_id));

        /* If there is a different card in the slot now than
         * there was before, then we need to emit a removed signal
         * for the old card
         */
        if (old_card != NULL) {
                old_slot_series = PK11_GetSlotSeries (old_card);

                if (old_slot_series != slot_series) {
                        /* Card registered with slot previously is
                         * different than this card, so update its
                         * exported state to track the implicit missed
                         * removal
                         */
                        gsd_smartcard_service_sync_token (priv->service, old_card, cancellable);
                }

                g_hash_table_remove (operation->smartcards, GINT_TO_POINTER ((int) slot_id));
        }

        if (PK11_IsPresent (card)) {
                g_debug ("Detected smartcard insertion event in slot %d", (int) slot_id);

                g_hash_table_replace (operation->smartcards,
                                      GINT_TO_POINTER ((int) slot_id),
                                      PK11_ReferenceSlot (card));

                gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        } else if (old_card == NULL) {
                /* If the just removed smartcard is not known to us then
                 * ignore the removal event. NSS sends a synthentic removal
                 * event for slots that are empty at startup
                 */
                g_debug ("Detected slot %d is empty in reader", (int) slot_id);
        } else {
                g_debug ("Detected smartcard removal event in slot %d", (int) slot_id);

                /* If the just removed smartcard is known to us then
                 * we need to update its exported state to reflect the
                 * removal
                 */
                if (old_slot_series == slot_series)
                        gsd_smartcard_service_sync_token (priv->service, card, cancellable);
        }

        PK11_FreeSlot (card);

        return TRUE;
}
Beispiel #14
0
int 
jar_create_pk7(CERTCertDBHandle *certdb, void *keydb, CERTCertificate *cert, 
               char *password, JAR_FILE infp, JAR_FILE outfp)
{
    SEC_PKCS7ContentInfo *cinfo;
    const SECHashObject *hashObj;
    char *errstring;
    void *mw = NULL;
    void *hashcx;
    unsigned int len;
    int status = 0;
    SECStatus rv;
    SECItem digest;
    unsigned char digestdata[32];
    unsigned char buffer[4096];

    if (outfp == NULL || infp == NULL || cert == NULL)
	return JAR_ERR_GENERAL;

    /* we sign with SHA */
    hashObj = HASH_GetHashObject(HASH_AlgSHA1);

    hashcx = (* hashObj->create)();
    if (hashcx == NULL)
	return JAR_ERR_GENERAL;

    (* hashObj->begin)(hashcx);
    while (1) {
	int nb = JAR_FREAD(infp, buffer, sizeof buffer);
	if (nb == 0) { /* eof */
	    break;
	}
	(* hashObj->update) (hashcx, buffer, nb);
    }
    (* hashObj->end)(hashcx, digestdata, &len, 32);
    (* hashObj->destroy)(hashcx, PR_TRUE);

    digest.data = digestdata;
    digest.len = len;

    /* signtool must use any old context it can find since it's
	 calling from inside javaland. */
    PORT_SetError (0);
    cinfo = SEC_PKCS7CreateSignedData(cert, certUsageObjectSigner, NULL,
                                      SEC_OID_SHA1, &digest, NULL, mw);
    if (cinfo == NULL)
	return JAR_ERR_PK7;

    rv = SEC_PKCS7IncludeCertChain(cinfo, NULL);
    if (rv != SECSuccess) {
	status = PORT_GetError();
	SEC_PKCS7DestroyContentInfo(cinfo);
	return status;
    }

    /* Having this here forces signtool to always include signing time. */
    rv = SEC_PKCS7AddSigningTime(cinfo);
    /* don't check error */
    PORT_SetError(0);

    /* if calling from mozilla thread*/
    rv = SEC_PKCS7Encode(cinfo, jar_pk7_out, outfp, NULL, NULL, mw);
    if (rv != SECSuccess)
	status = PORT_GetError();
    SEC_PKCS7DestroyContentInfo (cinfo);
    if (rv != SECSuccess) {
	errstring = JAR_get_error (status);
	return ((status < 0) ? status : JAR_ERR_GENERAL);
    }
    return 0;
}
Beispiel #15
0
char *
crypto_decrypt (const char *cipher,
                int key_type,
                const guint8 *data,
                gsize data_len,
                const char *iv,
                const gsize iv_len,
                const char *key,
                const gsize key_len,
                gsize *out_len,
                GError **error)
{
	char *output = NULL;
	int decrypted_len = 0;
	CK_MECHANISM_TYPE cipher_mech;
	PK11SlotInfo *slot = NULL;
	SECItem key_item;
	PK11SymKey *sym_key = NULL;
	SECItem *sec_param = NULL;
	PK11Context *ctx = NULL;
	SECStatus s;
	gboolean success = FALSE;
	unsigned int pad_len = 0, extra = 0;
	guint32 i, real_iv_len = 0;

	if (!crypto_init (error))
		return NULL;

	if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
		cipher_mech = CKM_DES3_CBC_PAD;
		real_iv_len = 8;
	} else if (!strcmp (cipher, CIPHER_DES_CBC)) {
		cipher_mech = CKM_DES_CBC_PAD;
		real_iv_len = 8;
	} else if (!strcmp (cipher, CIPHER_AES_CBC)) {
		cipher_mech = CKM_AES_CBC_PAD;
		real_iv_len = 16;
	} else {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
		             _("Private key cipher '%s' was unknown."),
		             cipher);
		return NULL;
	}

	if (iv_len < real_iv_len) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_INVALID_DATA,
		             _("Invalid IV length (must be at least %d)."),
		             real_iv_len);
		return NULL;
	}

	output = g_malloc0 (data_len);

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

	key_item.data = (unsigned char *) key;
	key_item.len = key_len;
	sym_key = PK11_ImportSymKey (slot, cipher_mech, PK11_OriginUnwrap, CKA_DECRYPT, &key_item, NULL);
	if (!sym_key) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to set symmetric key for decryption."));
		goto out;
	}

	key_item.data = (unsigned char *) iv;
	key_item.len = real_iv_len;
	sec_param = PK11_ParamFromIV (cipher_mech, &key_item);
	if (!sec_param) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to set IV for decryption."));
		goto out;
	}

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

	s = PK11_CipherOp (ctx,
	                   (unsigned char *) output,
	                   &decrypted_len,
	                   data_len,
	                   data,
	                   data_len);
	if (s != SECSuccess) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to decrypt the private key: %d."),
		             PORT_GetError ());
		goto out;
	}

	if (decrypted_len > data_len) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to decrypt the private key: decrypted data too large."));
		goto out;
	}

	s = PK11_DigestFinal (ctx,
	                      (unsigned char *) (output + decrypted_len),
	                      &extra,
	                      data_len - decrypted_len);
	if (s != SECSuccess) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to finalize decryption of the private key: %d."),
		             PORT_GetError ());
		goto out;
	}
	decrypted_len += extra;
	pad_len = data_len - decrypted_len;

	/* Check if the padding at the end of the decrypted data is valid */
	if (pad_len == 0 || pad_len > real_iv_len) {
		g_set_error (error, NM_CRYPTO_ERROR,
		             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
		             _("Failed to decrypt the private key: unexpected padding length."));
		goto out;
	}

	/* Validate tail padding; last byte is the padding size, and all pad bytes
	 * should contain the padding size.
	 */
	for (i = pad_len; i > 0; i--) {
		if (output[data_len - i] != pad_len) {
			g_set_error (error, NM_CRYPTO_ERROR,
			             NM_CRYPTO_ERROR_DECRYPTION_FAILED,
			             _("Failed to decrypt the private key."));
			goto out;
		}
	}

	*out_len = decrypted_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 (!success) {
		if (output) {
			/* Don't expose key material */
			memset (output, 0, data_len);
			g_free (output);
			output = NULL;
		}
	}
	return output;
}
Beispiel #16
0
/*
 * return the crl associated with a derSubjectName 
 */
SECItem *
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
					 SECItem *name, int type, char **pUrl)
{
    NSSCRL **crls, **crlp, *crl = NULL;
    NSSDER subject;
    SECItem *rvItem;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    char * url = NULL;

    PORT_SetError(0);
    NSSITEM_FROM_SECITEM(&subject, name);
    if (*slot) {
	nssCryptokiObject **instances;
	nssPKIObjectCollection *collection;
	nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
	NSSToken *token = PK11Slot_GetNSSToken(*slot);
	collection = nssCRLCollection_Create(td, NULL);
	if (!collection) {
	    goto loser;
	}
	instances = nssToken_FindCRLsBySubject(token, NULL, &subject, 
	                                       tokenOnly, 0, NULL);
	nssPKIObjectCollection_AddInstances(collection, instances, 0);
	nss_ZFreeIf(instances);
	crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
	nssPKIObjectCollection_Destroy(collection);
    } else {
	crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
    }
    if ((!crls) || (*crls == NULL)) {
	if (crls) {
	    nssCRLArray_Destroy(crls);
	}
	if (NSS_GetError() == NSS_ERROR_NOT_FOUND) {
	    PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
	}
	goto loser;
    }
    for (crlp = crls; *crlp; crlp++) {
	if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
	    ((*crlp)->isKRL && type != SEC_CRL_TYPE)) 
	{
	    crl = nssCRL_AddRef(*crlp);
	    break;
	}
    }
    nssCRLArray_Destroy(crls);
    if (!crl) { 
	/* CRL collection was found, but no interesting CRL's were on it.
	 * Not an error */
	PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
	goto loser;
    }
    if (crl->url) {
	url = PORT_Strdup(crl->url);
	if (!url) {
	    goto loser;
	}
    }
    rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
    if (!rvItem) {
	goto loser;
    }
    memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
    *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
    *crlHandle = crl->object.instances[0]->handle;
    *pUrl = url;
    nssCRL_Destroy(crl);
    return rvItem;

loser:
    if (url)
    	PORT_Free(url);
    if (crl)
	nssCRL_Destroy(crl);
    if (PORT_GetError() == 0) {
	PORT_SetError(SEC_ERROR_CRL_NOT_FOUND);
    }
    return NULL;
}
Beispiel #17
0
CERTSignedCrl* PK11_ImportCRL(PK11SlotInfo * slot, SECItem *derCRL, char *url,
    int type, void *wincx, PRInt32 importOptions, PRArenaPool* arena,
    PRInt32 decodeoptions)
{
    CERTSignedCrl *newCrl, *crl;
    SECStatus rv;
    CERTCertificate *caCert = NULL;

    newCrl = crl = NULL;

    do {
        newCrl = CERT_DecodeDERCrlWithFlags(arena, derCRL, type,
                                            decodeoptions);
        if (newCrl == NULL) {
            if (type == SEC_CRL_TYPE) {
                /* only promote error when the error code is too generic */
                if (PORT_GetError () == SEC_ERROR_BAD_DER)
                    PORT_SetError(SEC_ERROR_CRL_INVALID);
	        } else {
                PORT_SetError(SEC_ERROR_KRL_INVALID);
            }
            break;		
        }

        if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){
            CERTCertDBHandle* handle = CERT_GetDefaultCertDB();
            PR_ASSERT(handle != NULL);
            caCert = CERT_FindCertByName (handle,
                                          &newCrl->crl.derName);
            if (caCert == NULL) {
                PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);	    
                break;
            }

            /* If caCert is a v3 certificate, make sure that it can be used for
               crl signing purpose */
            rv = CERT_CheckCertUsage (caCert, KU_CRL_SIGN);
            if (rv != SECSuccess) {
                break;
            }

            rv = CERT_VerifySignedData(&newCrl->signatureWrap, caCert,
                                       PR_Now(), wincx);
            if (rv != SECSuccess) {
                if (type == SEC_CRL_TYPE) {
                    PORT_SetError(SEC_ERROR_CRL_BAD_SIGNATURE);
                } else {
                    PORT_SetError(SEC_ERROR_KRL_BAD_SIGNATURE);
                }
                break;
            }
        }

	crl = crl_storeCRL(slot, url, newCrl, derCRL, type);

    } while (0);

    if (crl == NULL) {
	SEC_DestroyCrl (newCrl);
    }
    if (caCert) {
        CERT_DestroyCertificate(caCert);
    }
    return (crl);
}
static char *
getpassword(char *login, char *realm)
{
    LDAPMessage *res = NULL;
    LDAPMessage *entry;
    char **values = NULL;
    char **value = NULL;
    char *password = NULL;
    int retry = 0;
    char filter[8192];
    char searchbase[8192];
    char *universal_password = NULL;
    size_t universal_password_len = UNIVERSAL_PASS_LEN;
    int nmas_res = 0;
    int rc = -1;
    if (ld) {
	if (usersearchfilter) {
	    char escaped_login[1024];
	    snprintf(searchbase, sizeof(searchbase), "%s", userbasedn);
	    ldap_escape_value(escaped_login, sizeof(escaped_login), login);
	    snprintf(filter, sizeof(filter), usersearchfilter, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login, escaped_login);

	  retrysrch:
	    if (debug)
		fprintf(stderr, "user filter '%s', searchbase '%s'\n", filter, searchbase);

	    rc = ldap_search_s(ld, searchbase, searchscope, filter, NULL, 0, &res);
	    if (rc != LDAP_SUCCESS) {
		if (noreferrals && rc == LDAP_PARTIAL_RESULTS) {
		    /* Everything is fine. This is expected when referrals
		     * are disabled.
		     */
		    rc = LDAP_SUCCESS;
		} else {
		    fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error '%s'\n", ldap_err2string(rc));
#if defined(NETSCAPE_SSL)
		    if (sslpath && ((rc == LDAP_SERVER_DOWN) || (rc == LDAP_CONNECT_ERROR))) {
			int sslerr = PORT_GetError();
			fprintf(stderr, PROGRAM_NAME ": WARNING, SSL error %d (%s)\n", sslerr, ldapssl_err2string(sslerr));
		    }
#endif
		    fprintf(stderr, PROGRAM_NAME " WARNING, LDAP search error, trying to recover'%s'\n", ldap_err2string(rc));
		    ldap_msgfree(res);
		    /* try to connect to the LDAP server agin, maybe my persisten conexion failed. */
		    if (!retry) {
			retry++;
			ldap_unbind(ld);
			ld = NULL;
			ldapconnect();
			goto retrysrch;
		    }
		    return NULL;

		}
	    }
	} else if (userdnattr) {
	    sprintf(searchbase, "%s=%s, %s", userdnattr, login, userbasedn);

	  retrydnattr:
	    if (debug)
		fprintf(stderr, "searchbase '%s'\n", searchbase);
	    rc = ldap_search_s(ld, searchbase, searchscope, NULL, NULL, 0, &res);
	}
	if (rc == LDAP_SUCCESS) {
	    entry = ldap_first_entry(ld, res);
	    if (entry) {
		if (debug)
		    printf("ldap dn: %s\n", ldap_get_dn(ld, entry));
		if (edir_universal_passwd) {

		    /* allocate some memory for the universal password returned by NMAS */
		    universal_password = malloc(universal_password_len);
		    memset(universal_password, 0, universal_password_len);
		    values = malloc(sizeof(char *));

		    /* actually talk to NMAS to get a password */
		    nmas_res = nmasldap_get_password(ld, ldap_get_dn(ld, entry), &universal_password_len, universal_password);
		    if (nmas_res == NMAS_SUCCESS && universal_password) {
			if (debug)
			    printf("NMAS returned value %s\n", universal_password);
			values[0] = universal_password;
		    } else {
			if (debug)
			    printf("Error reading Universal Password: %d = %s\n", nmas_res, ldap_err2string(nmas_res));
		    }
		} else {
		    values = ldap_get_values(ld, entry, passattr);
		}
	    } else {
		ldap_msgfree(res);
		return NULL;
	    }
	    if (!values) {
		if (debug)
		    printf("No attribute value found\n");
		if (edir_universal_passwd)
		    free(universal_password);
		ldap_msgfree(res);
		return NULL;
	    }
	    value = values;
	    while (*value) {
		if (encrpass) {
		    if (strcmp(strtok(*value, delimiter), realm) == 0) {
			password = strtok(NULL, delimiter);
			break;
		    }
		} else {
		    password = *value;
		    break;
		}
		value++;
	    }
	    if (debug)
		printf("password: %s\n", password);
	    if (password)
		password = strdup(password);
	    if (edir_universal_passwd) {
		free(values);
		free(universal_password);
	    } else {
		ldap_value_free(values);
	    }
	    ldap_msgfree(res);
	    return password;
	} else {
	    fprintf(stderr, PROGRAM_NAME " WARNING, LDAP error '%s'\n", ldap_err2string(rc));
	    /* try to connect to the LDAP server agin, maybe my persisten conexion failed. */
	    if (!retry) {
		retry++;
		ldap_unbind(ld);
		ld = NULL;
		ldapconnect();
		goto retrydnattr;
	    }
	    return NULL;
	}
    }
    return NULL;
}
Beispiel #19
0
int
main(int argc, char *argv[], char *envp[])
{
    char *               certDir      = NULL;
    char *               progName     = NULL;
    char *               oidStr       = NULL;
    CERTCertificate *    cert;
    CERTCertificate *    firstCert    = NULL;
    CERTCertificate *    issuerCert   = NULL;
    CERTCertDBHandle *   defaultDB    = NULL;
    PRBool               isAscii      = PR_FALSE;
    PRBool               trusted      = PR_FALSE;
    SECStatus            secStatus;
    SECCertificateUsage  certUsage    = certificateUsageSSLServer;
    PLOptState *         optstate;
    PRTime               time         = 0;
    PLOptStatus          status;
    int                  usePkix      = 0;
    int                  rv           = 1;
    int                  usage;
    CERTVerifyLog        log;
    CERTCertList        *builtChain = NULL;
    PRBool               certFetching = PR_FALSE;
    int                  revDataIndex = 0;
    PRBool               ocsp_fetchingFailureIsAFailure = PR_TRUE;
    PRBool               useDefaultRevFlags = PR_TRUE;
    int                  vfyCounts = 1;

    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);

    progName = PL_strdup(argv[0]);

    optstate = PL_CreateOptState(argc, argv, "ab:c:d:efg:h:i:m:o:prs:tu:vw:W:");
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
	switch(optstate->option) {
	case  0  : /* positional parameter */  goto breakout;
	case 'a' : isAscii  = PR_TRUE;                        break;
	case 'b' : secStatus = DER_AsciiToTime(&time, optstate->value);
	           if (secStatus != SECSuccess) Usage(progName); break;
	case 'd' : certDir  = PL_strdup(optstate->value);     break;
	case 'e' : ocsp_fetchingFailureIsAFailure = PR_FALSE;  break;
	case 'f' : certFetching = PR_TRUE;                    break;
	case 'g' : 
                   if (revMethodsData[revDataIndex].testTypeStr ||
                       revMethodsData[revDataIndex].methodTypeStr) {
                       revDataIndex += 1;
                       if (revDataIndex == REV_METHOD_INDEX_MAX) {
                           fprintf(stderr, "Invalid revocation configuration"
                                   "specified.\n");
                           secStatus = SECFailure;
                           break;
                       }
                   }
                   useDefaultRevFlags = PR_FALSE;
                   revMethodsData[revDataIndex].
                       testTypeStr = PL_strdup(optstate->value); break;
	case 'h' : 
                   revMethodsData[revDataIndex].
                       testFlagsStr = PL_strdup(optstate->value);break;
        case 'i' : vfyCounts = PORT_Atoi(optstate->value);       break;
                   break;
	case 'm' : 
                   if (revMethodsData[revDataIndex].methodTypeStr) {
                       revDataIndex += 1;
                       if (revDataIndex == REV_METHOD_INDEX_MAX) {
                           fprintf(stderr, "Invalid revocation configuration"
                                   "specified.\n");
                           secStatus = SECFailure;
                           break;
                       }
                   }
                   useDefaultRevFlags = PR_FALSE;
                   revMethodsData[revDataIndex].
                       methodTypeStr = PL_strdup(optstate->value); break;
	case 'o' : oidStr = PL_strdup(optstate->value);       break;
	case 'p' : usePkix += 1;                              break;
	case 'r' : isAscii  = PR_FALSE;                       break;
	case 's' : 
                   revMethodsData[revDataIndex].
                       methodFlagsStr = PL_strdup(optstate->value); break;
	case 't' : trusted  = PR_TRUE;                        break;
	case 'u' : usage    = PORT_Atoi(optstate->value);
	           if (usage < 0 || usage > 62) Usage(progName);
		   certUsage = ((SECCertificateUsage)1) << usage; 
		   if (certUsage > certificateUsageHighest) Usage(progName);
		   break;
        case 'w':
                  pwdata.source = PW_PLAINTEXT;
                  pwdata.data = PORT_Strdup(optstate->value);
                  break;

        case 'W':
                  pwdata.source = PW_FROMFILE;
                  pwdata.data = PORT_Strdup(optstate->value);
                  break;
	case 'v' : verbose++;                                 break;
	default  : Usage(progName);                           break;
	}
    }
breakout:
    if (status != PL_OPT_OK)
	Usage(progName);

    if (usePkix < 2) {
        if (oidStr) {
            fprintf(stderr, "Policy oid(-o) can be used only with"
                    " CERT_PKIXVerifyChain(-pp) function.\n");
            Usage(progName);
        }
        if (trusted) {
            fprintf(stderr, "Cert trust flag can be used only with"
                    " CERT_PKIXVerifyChain(-pp) function.\n");
            Usage(progName);
        }
    }

    if (!useDefaultRevFlags && parseRevMethodsAndFlags()) {
        fprintf(stderr, "Invalid revocation configuration specified.\n");
        goto punt;
    }

    /* Set our password function callback. */
    PK11_SetPasswordFunc(SECU_GetModulePassword);

    /* Initialize the NSS libraries. */
    if (certDir) {
	secStatus = NSS_Init(certDir);
    } else {
	secStatus = NSS_NoDB_Init(NULL);

	/* load the builtins */
	SECMOD_AddNewModule("Builtins", DLL_PREFIX"nssckbi."DLL_SUFFIX, 0, 0);
    }
    if (secStatus != SECSuccess) {
	exitErr("NSS_Init");
    }
    SECU_RegisterDynamicOids();
    if (isOCSPEnabled()) {
        CERT_EnableOCSPChecking(CERT_GetDefaultCertDB());
        CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB());
        if (!ocsp_fetchingFailureIsAFailure) {
            CERT_SetOCSPFailureMode(ocspMode_FailureIsNotAVerificationFailure);
        }
    }

    while (status == PL_OPT_OK) {
	switch(optstate->option) {
	default  : Usage(progName);                           break;
	case 'a' : isAscii  = PR_TRUE;                        break;
	case 'r' : isAscii  = PR_FALSE;                       break;
	case 't' : trusted  = PR_TRUE;                       break;
	case  0  : /* positional parameter */
            if (usePkix < 2 && trusted) {
                fprintf(stderr, "Cert trust flag can be used only with"
                        " CERT_PKIXVerifyChain(-pp) function.\n");
                Usage(progName);
            }
	    cert = getCert(optstate->value, isAscii, progName);
	    if (!cert) 
	        goto punt;
	    rememberCert(cert, trusted);
	    if (!firstCert)
	        firstCert = cert;
            trusted = PR_FALSE;
	}
        status = PL_GetNextOpt(optstate);
    }
    PL_DestroyOptState(optstate);
    if (status == PL_OPT_BAD || !firstCert)
	Usage(progName);

    /* Initialize log structure */
    log.arena = PORT_NewArena(512);
    log.head = log.tail = NULL;
    log.count = 0;

    do {
        if (usePkix < 2) {
            /* NOW, verify the cert chain. */
            if (usePkix) {
                /* Use old API with libpkix validation lib */
                CERT_SetUsePKIXForValidation(PR_TRUE);
            }
            if (!time)
                time = PR_Now();

            defaultDB = CERT_GetDefaultCertDB();
            secStatus = CERT_VerifyCertificate(defaultDB, firstCert, 
                                               PR_TRUE /* check sig */,
                                               certUsage, 
                                               time,
                                               &pwdata, /* wincx  */
                                               &log, /* error log */
                                           NULL);/* returned usages */
        } else do {
                static CERTValOutParam cvout[4];
                static CERTValInParam cvin[6];
                SECOidTag oidTag;
                int inParamIndex = 0;
                static PRUint64 revFlagsLeaf[2];
                static PRUint64 revFlagsChain[2];
                static CERTRevocationFlags rev;
                
                if (oidStr) {
                    PRArenaPool *arena;
                    SECOidData od;
                    memset(&od, 0, sizeof od);
                    od.offset = SEC_OID_UNKNOWN;
                    od.desc = "User Defined Policy OID";
                    od.mechanism = CKM_INVALID_MECHANISM;
                    od.supportedExtension = INVALID_CERT_EXTENSION;

                    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
                    if ( !arena ) {
                        fprintf(stderr, "out of memory");
                        goto punt;
                    }
                    
                    secStatus = SEC_StringToOID(arena, &od.oid, oidStr, 0);
                    if (secStatus != SECSuccess) {
                        PORT_FreeArena(arena, PR_FALSE);
                        fprintf(stderr, "Can not encode oid: %s(%s)\n", oidStr,
                                SECU_Strerror(PORT_GetError()));
                        break;
                    }
                    
                    oidTag = SECOID_AddEntry(&od);
                    PORT_FreeArena(arena, PR_FALSE);
                    if (oidTag == SEC_OID_UNKNOWN) {
                        fprintf(stderr, "Can not add new oid to the dynamic "
                                "table: %s\n", oidStr);
                        secStatus = SECFailure;
                        break;
                    }
                    
                    cvin[inParamIndex].type = cert_pi_policyOID;
                    cvin[inParamIndex].value.arraySize = 1;
                    cvin[inParamIndex].value.array.oids = &oidTag;
                    
                    inParamIndex++;
                }
                
                if (trustedCertList) {
                    cvin[inParamIndex].type = cert_pi_trustAnchors;
                    cvin[inParamIndex].value.pointer.chain = trustedCertList;
                    
                    inParamIndex++;
                }
                
                cvin[inParamIndex].type = cert_pi_useAIACertFetch;
                cvin[inParamIndex].value.scalar.b = certFetching;
                inParamIndex++;
                
                rev.leafTests.cert_rev_flags_per_method = revFlagsLeaf;
                rev.chainTests.cert_rev_flags_per_method = revFlagsChain;
                secStatus = configureRevocationParams(&rev);
                if (secStatus) {
                    fprintf(stderr, "Can not config revocation parameters ");
                    break;
                }
                
                cvin[inParamIndex].type = cert_pi_revocationFlags;
                cvin[inParamIndex].value.pointer.revocation = &rev;
                inParamIndex++;
                
                if (time) {
                    cvin[inParamIndex].type = cert_pi_date;
                    cvin[inParamIndex].value.scalar.time = time;
                    inParamIndex++;
                }
                
                cvin[inParamIndex].type = cert_pi_end;
                
                cvout[0].type = cert_po_trustAnchor;
                cvout[0].value.pointer.cert = NULL;
                cvout[1].type = cert_po_certList;
                cvout[1].value.pointer.chain = NULL;
                
                /* setting pointer to CERTVerifyLog. Initialized structure
                 * will be used CERT_PKIXVerifyCert */
                cvout[2].type = cert_po_errorLog;
                cvout[2].value.pointer.log = &log;
                
                cvout[3].type = cert_po_end;
                
                secStatus = CERT_PKIXVerifyCert(firstCert, certUsage,
                                                cvin, cvout, &pwdata);
                if (secStatus != SECSuccess) {
                    break;
                }
                issuerCert = cvout[0].value.pointer.cert;
                builtChain = cvout[1].value.pointer.chain;
            } while (0);
        
        /* Display validation results */
        if (secStatus != SECSuccess || log.count > 0) {
            CERTVerifyLogNode *node = NULL;
            PRIntn err = PR_GetError();
            fprintf(stderr, "Chain is bad, %d = %s\n", err, SECU_Strerror(err));
            
            SECU_displayVerifyLog(stderr, &log, verbose); 
            /* Have cert refs in the log only in case of failure.
             * Destroy them. */
            for (node = log.head; node; node = node->next) {
                if (node->cert)
                    CERT_DestroyCertificate(node->cert);
            }
            rv = 1;
        } else {
            fprintf(stderr, "Chain is good!\n");
            if (issuerCert) {
                if (verbose > 1) {
                    rv = SEC_PrintCertificateAndTrust(issuerCert, "Root Certificate",
                                                      NULL);
                    if (rv != SECSuccess) {
                        SECU_PrintError(progName, "problem printing certificate");
                    }
                } else if (verbose > 0) {
                    SECU_PrintName(stdout, &issuerCert->subject, "Root "
                                   "Certificate Subject:", 0);
                }
                CERT_DestroyCertificate(issuerCert);
            }
            if (builtChain) {
                CERTCertListNode *node;
                int count = 0;
                char buff[256];
                
                if (verbose) { 
                    for(node = CERT_LIST_HEAD(builtChain); !CERT_LIST_END(node, builtChain);
                        node = CERT_LIST_NEXT(node), count++ ) {
                        sprintf(buff, "Certificate %d Subject", count + 1);
                        SECU_PrintName(stdout, &node->cert->subject, buff, 0);
                    }
                }
                CERT_DestroyCertList(builtChain);
            }
            rv = 0;
        }
    } while (--vfyCounts > 0);

    /* Need to destroy CERTVerifyLog arena at the end */
    PORT_FreeArena(log.arena, PR_FALSE);

punt:
    forgetCerts();
    if (NSS_Shutdown() != SECSuccess) {
	SECU_PrintError(progName, "NSS_Shutdown");
	rv = 1;
    }
    PORT_Free(progName);
    PORT_Free(certDir);
    PORT_Free(oidStr);
    freeRevocationMethodData();
    if (pwdata.data) {
        PORT_Free(pwdata.data);
    }
    PR_Cleanup();
    return rv;
}
Beispiel #20
0
/*
 * Perform the AES Known Answer Test (KAT) in Galois Counter Mode (GCM).
 *
 * respfn is the pathname of the RESPONSE file.
 */
static void
aes_gcm_kat(const char *respfn)
{
    char buf[512];      /* holds one line from the input REQUEST file.
                         * needs to be large enough to hold the longest
                         * line "CIPHERTEXT = <320 hex digits>\n".
                         */
    FILE *aesresp;      /* input stream from the RESPONSE file */
    int i, j;
    unsigned int test_group = 0;
    unsigned int num_tests = 0;
    PRBool is_encrypt;
    unsigned char key[32];              /* 128, 192, or 256 bits */
    unsigned int keysize = 16;
    unsigned char iv[10*16];            /* 1 to 10 blocks */
    unsigned int ivsize = 12;
    unsigned char plaintext[10*16];     /* 1 to 10 blocks */
    unsigned int plaintextlen = 0;
    unsigned char aad[10*16];           /* 1 to 10 blocks */
    unsigned int aadlen = 0;
    unsigned char ciphertext[10*16];    /* 1 to 10 blocks */
    unsigned int ciphertextlen = 0;
    unsigned char tag[16];
    unsigned int tagsize = 16;
    unsigned char output[10*16];         /* 1 to 10 blocks */
    unsigned int outputlen = 0;

    unsigned int expected_keylen = 0;
    unsigned int expected_ivlen = 0;
    unsigned int expected_ptlen = 0;
    unsigned int expected_aadlen = 0;
    unsigned int expected_taglen = 0;
    SECStatus rv;

    if (strstr(respfn, "Encrypt") != NULL) {
	is_encrypt = PR_TRUE;
    } else if (strstr(respfn, "Decrypt") != NULL) {
	is_encrypt = PR_FALSE;
    } else {
	fprintf(stderr, "Input file name must contain Encrypt or Decrypt\n");
	exit(1);
    }
    aesresp = fopen(respfn, "r");
    if (aesresp == NULL) {
	fprintf(stderr, "Cannot open input file %s\n", respfn);
	exit(1);
    }
    while (fgets(buf, sizeof buf, aesresp) != NULL) {
	/* a comment or blank line */
	if (buf[0] == '#' || buf[0] == '\n') {
	    continue;
	}
	/* [Keylen = ...], [IVlen = ...], etc. */
	if (buf[0] == '[') {
	    if (strncmp(&buf[1], "Keylen = ", 9) == 0) {
		expected_keylen = atoi(&buf[10]);
	    } else if (strncmp(&buf[1], "IVlen = ", 8) == 0) {
		expected_ivlen = atoi(&buf[9]);
	    } else if (strncmp(&buf[1], "PTlen = ", 8) == 0) {
		expected_ptlen = atoi(&buf[9]);
	    } else if (strncmp(&buf[1], "AADlen = ", 9) == 0) {
		expected_aadlen = atoi(&buf[10]);
	    } else if (strncmp(&buf[1], "Taglen = ", 9) == 0) {
		expected_taglen = atoi(&buf[10]);

		test_group++;
		if (test_group > 1) {
		    /* Report num_tests for the previous test group. */
		    printf("%u tests\n", num_tests);
		}
		num_tests = 0;
		printf("Keylen = %u, IVlen = %u, PTlen = %u, AADlen = %u, "
		       "Taglen = %u: ", expected_keylen, expected_ivlen,
		        expected_ptlen, expected_aadlen, expected_taglen);
		/* Convert lengths in bits to lengths in bytes. */
		PORT_Assert(expected_keylen % 8 == 0);
		expected_keylen /= 8;
		PORT_Assert(expected_ivlen % 8 == 0);
		expected_ivlen /= 8;
		PORT_Assert(expected_ptlen % 8 == 0);
		expected_ptlen /= 8;
		PORT_Assert(expected_aadlen % 8 == 0);
		expected_aadlen /= 8;
		PORT_Assert(expected_taglen % 8 == 0);
		expected_taglen /= 8;
	    } else {
		fprintf(stderr, "Unexpected input line: %s\n", buf);
		exit(1);
	    }
	    continue;
	}
	/* "Count = x" begins a new data set */
	if (strncmp(buf, "Count", 5) == 0) {
	    /* zeroize the variables for the test with this data set */
	    memset(key, 0, sizeof key);
	    keysize = 0;
	    memset(iv, 0, sizeof iv);
	    ivsize = 0;
	    memset(plaintext, 0, sizeof plaintext);
	    plaintextlen = 0;
	    memset(aad, 0, sizeof aad);
	    aadlen = 0;
	    memset(ciphertext, 0, sizeof ciphertext);
	    ciphertextlen = 0;
	    memset(output, 0, sizeof output);
	    outputlen = 0;
	    num_tests++;
	    continue;
	}
	/* Key = ... */
	if (strncmp(buf, "Key", 3) == 0) {
	    i = 3;
	    while (isspace(buf[i]) || buf[i] == '=') {
		i++;
	    }
	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
		hex_to_byteval(&buf[i], &key[j]);
	    }
	    keysize = j;
	    if (keysize != expected_keylen) {
		fprintf(stderr, "Unexpected key length: %u vs. %u\n",
			keysize, expected_keylen);
		exit(1);
	    }
	    continue;
	}
	/* IV = ... */
	if (strncmp(buf, "IV", 2) == 0) {
	    i = 2;
	    while (isspace(buf[i]) || buf[i] == '=') {
		i++;
	    }
	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
		hex_to_byteval(&buf[i], &iv[j]);
	    }
	    ivsize = j;
	    if (ivsize != expected_ivlen) {
		fprintf(stderr, "Unexpected IV length: %u vs. %u\n",
			ivsize, expected_ivlen);
		exit(1);
	    }
	    continue;
	}
	/* PT = ... */
	if (strncmp(buf, "PT", 2) == 0) {
	    i = 2;
	    while (isspace(buf[i]) || buf[i] == '=') {
		i++;
	    }
	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
		hex_to_byteval(&buf[i], &plaintext[j]);
	    }
	    plaintextlen = j;
	    if (plaintextlen != expected_ptlen) {
		fprintf(stderr, "Unexpected PT length: %u vs. %u\n",
			plaintextlen, expected_ptlen);
		exit(1);
	    }

	    if (!is_encrypt) {
		rv = aes_decrypt_buf(key, keysize, iv, ivsize,
		    output, &outputlen, sizeof output,
		    ciphertext, ciphertextlen, aad, aadlen, tag, tagsize);
		if (rv != SECSuccess) {
		    fprintf(stderr, "aes_decrypt_buf failed\n");
		    goto loser;
		}
		if (outputlen != plaintextlen) {
		    fprintf(stderr, "aes_decrypt_buf: wrong output size\n");
		    goto loser;
		}
		if (memcmp(output, plaintext, plaintextlen) != 0) {
		    fprintf(stderr, "aes_decrypt_buf: wrong plaintext\n");
		    goto loser;
		}
	    }
	    continue;
	}
	/* FAIL */
	if (strncmp(buf, "FAIL", 4) == 0) {
	    plaintextlen = 0;

	    PORT_Assert(!is_encrypt);
	    rv = aes_decrypt_buf(key, keysize, iv, ivsize,
		output, &outputlen, sizeof output,
		ciphertext, ciphertextlen, aad, aadlen, tag, tagsize);
	    if (rv != SECFailure) {
		fprintf(stderr, "aes_decrypt_buf succeeded unexpectedly\n");
		goto loser;
	    }
	    if (PORT_GetError() != SEC_ERROR_BAD_DATA) {
		fprintf(stderr, "aes_decrypt_buf failed with incorrect "
			"error code\n");
		goto loser;
	    }
	    continue;
	}
	/* AAD = ... */
	if (strncmp(buf, "AAD", 3) == 0) {
	    i = 3;
	    while (isspace(buf[i]) || buf[i] == '=') {
		i++;
	    }
	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
		hex_to_byteval(&buf[i], &aad[j]);
	    }
	    aadlen = j;
	    if (aadlen != expected_aadlen) {
		fprintf(stderr, "Unexpected AAD length: %u vs. %u\n",
			aadlen, expected_aadlen);
		exit(1);
	    }
	    continue;
	}
	/* CT = ... */
	if (strncmp(buf, "CT", 2) == 0) {
	    i = 2;
	    while (isspace(buf[i]) || buf[i] == '=') {
		i++;
	    }
	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
		hex_to_byteval(&buf[i], &ciphertext[j]);
	    }
	    ciphertextlen = j;
	    if (ciphertextlen != expected_ptlen) {
		fprintf(stderr, "Unexpected CT length: %u vs. %u\n",
			ciphertextlen, expected_ptlen);
		exit(1);
	    }
	    continue;
	}
	/* Tag = ... */
	if (strncmp(buf, "Tag", 3) == 0) {
	    i = 3;
	    while (isspace(buf[i]) || buf[i] == '=') {
		i++;
	    }
	    for (j=0; isxdigit(buf[i]); i+=2,j++) {
		hex_to_byteval(&buf[i], &tag[j]);
	    }
	    tagsize = j;
	    if (tagsize != expected_taglen) {
		fprintf(stderr, "Unexpected tag length: %u vs. %u\n",
			tagsize, expected_taglen);
		exit(1);
	    }

	    if (is_encrypt) {
		rv = aes_encrypt_buf(key, keysize, iv, ivsize,
		    output, &outputlen, sizeof output,
		    plaintext, plaintextlen, aad, aadlen, tagsize);
		if (rv != SECSuccess) {
		    fprintf(stderr, "aes_encrypt_buf failed\n");
		    goto loser;
		}
		if (outputlen != plaintextlen + tagsize) {
		    fprintf(stderr, "aes_encrypt_buf: wrong output size\n");
		    goto loser;
		}
		if (memcmp(output, ciphertext, plaintextlen) != 0) {
		    fprintf(stderr, "aes_encrypt_buf: wrong ciphertext\n");
		    goto loser;
		}
		if (memcmp(output + plaintextlen, tag, tagsize) != 0) {
		    fprintf(stderr, "aes_encrypt_buf: wrong tag\n");
		    goto loser;
		}
	    }
	    continue;
	}
    }
    /* Report num_tests for the last test group. */
    printf("%u tests\n", num_tests);
    printf("%u test groups\n", test_group);
    printf("PASS\n");
loser:
    fclose(aesresp);
}
Beispiel #21
0
/*************************************************************************
 *
 * V e r i f y J a r
 */
int
VerifyJar(char *filename)
{
    FILE *fp;

    int ret;
    int status;
    int failed = 0;
    char *err;

    JAR *jar;
    JAR_Context *ctx;

    JAR_Item *it;

    jar = JAR_new();

    if ((fp = fopen(filename, "r")) == NULL) {
        perror(filename);
        exit(ERRX);
    } else
        fclose(fp);

    JAR_set_callback(JAR_CB_SIGNAL, jar, jar_cb);

    status = JAR_pass_archive(jar, jarArchGuess, filename, "some-url");

    if (status < 0 || jar->valid < 0) {
        failed = 1;
        PR_fprintf(outputFD,
                   "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
                   filename);
        if (status < 0) {
            const char *errtext;

            if (status >= JAR_BASE && status <= JAR_BASE_END) {
                errtext = JAR_get_error(status);
            } else {
                errtext = SECU_Strerror(PORT_GetError());
            }

            PR_fprintf(outputFD, "  (reported reason: %s)\n\n",
                       errtext);

            /* corrupt files should not have their contents listed */

            if (status == JAR_ERR_CORRUPT)
                return -1;
        }
        PR_fprintf(outputFD,
                   "entries shown below will have their digests checked only.\n");
        jar->valid = 0;
    } else
        PR_fprintf(outputFD,
                   "archive \"%s\" has passed crypto verification.\n", filename);

    if (verify_global(jar))
        failed = 1;

    PR_fprintf(outputFD, "\n");
    PR_fprintf(outputFD, "%16s   %s\n", "status", "path");
    PR_fprintf(outputFD, "%16s   %s\n", "------------", "-------------------");

    ctx = JAR_find(jar, NULL, jarTypeMF);

    while (JAR_find_next(ctx, &it) >= 0) {
        if (it && it->pathname) {
            rm_dash_r(TMP_OUTPUT);
            ret = JAR_verified_extract(jar, it->pathname, TMP_OUTPUT);
            /* if (ret < 0) printf ("error %d on %s\n", ret, it->pathname); */
            if (ret < 0)
                failed = 1;

            if (ret == JAR_ERR_PNF)
                err = "NOT PRESENT";
            else if (ret == JAR_ERR_HASH)
                err = "HASH FAILED";
            else
                err = "NOT VERIFIED";

            PR_fprintf(outputFD, "%16s   %s\n",
                       ret >= 0 ? "verified" : err, it->pathname);

            if (ret != 0 && ret != JAR_ERR_PNF && ret != JAR_ERR_HASH)
                PR_fprintf(outputFD, "      (reason: %s)\n",
                           JAR_get_error(ret));
        }
    }

    JAR_find_end(ctx);

    if (status < 0 || jar->valid < 0) {
        failed = 1;
        PR_fprintf(outputFD,
                   "\nNOTE -- \"%s\" archive DID NOT PASS crypto verification.\n",
                   filename);
        give_help(status);
    }

    JAR_destroy(jar);

    if (failed)
        return -1;
    return 0;
}
Beispiel #22
0
/*************************************************************************
 *
 * P k 1 1 I n s t a l l _ D o I n s t a l l
 *
 * jarFile is the path of a JAR in the PKCS #11 module JAR format.
 * installDir is the directory relative to which files will be
 *   installed.
 */
Pk11Install_Error
Pk11Install_DoInstall(char *jarFile, const char *installDir,
                      const char *tempDir, PRFileDesc *feedback, short force, PRBool noverify)
{
    JAR *jar;
    char *installer;
    unsigned long installer_len;
    int status;
    Pk11Install_Error ret;
    PRBool made_temp_file;
    Pk11Install_Info installInfo;
    Pk11Install_Platform *platform;
    char *errMsg;
    char sysname[SYS_INFO_BUFFER_LENGTH], release[SYS_INFO_BUFFER_LENGTH],
        arch[SYS_INFO_BUFFER_LENGTH];
    char *myPlatform;

    jar = NULL;
    ret = PK11_INSTALL_UNSPECIFIED;
    made_temp_file = PR_FALSE;
    errMsg = NULL;
    Pk11Install_Info_init(&installInfo);

    /*
    printf("Inside DoInstall, jarFile=%s, installDir=%s, tempDir=%s\n",
        jarFile, installDir, tempDir);
    */

    /*
     * Check out jarFile and installDir for validity
     */
    if (PR_Access(installDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
        error(PK11_INSTALL_DIR_DOESNT_EXIST, installDir);
        return PK11_INSTALL_DIR_DOESNT_EXIST;
    }
    if (!tempDir) {
        tempDir = ".";
    }
    if (PR_Access(tempDir, PR_ACCESS_EXISTS) != PR_SUCCESS) {
        error(PK11_INSTALL_DIR_DOESNT_EXIST, tempDir);
        return PK11_INSTALL_DIR_DOESNT_EXIST;
    }
    if (PR_Access(tempDir, PR_ACCESS_WRITE_OK) != PR_SUCCESS) {
        error(PK11_INSTALL_DIR_NOT_WRITEABLE, tempDir);
        return PK11_INSTALL_DIR_NOT_WRITEABLE;
    }
    if ((PR_Access(jarFile, PR_ACCESS_EXISTS) != PR_SUCCESS)) {
        error(PK11_INSTALL_FILE_DOESNT_EXIST, jarFile);
        return PK11_INSTALL_FILE_DOESNT_EXIST;
    }
    if (PR_Access(jarFile, PR_ACCESS_READ_OK) != PR_SUCCESS) {
        error(PK11_INSTALL_FILE_NOT_READABLE, jarFile);
        return PK11_INSTALL_FILE_NOT_READABLE;
    }

    /*
     * Extract the JAR file
     */
    jar = JAR_new();
    JAR_set_callback(JAR_CB_SIGNAL, jar, jar_callback);

    if (noverify) {
        status = JAR_pass_archive_unverified(jar, jarArchGuess, jarFile, "url");
    } else {
        status = JAR_pass_archive(jar, jarArchGuess, jarFile, "url");
    }
    if ((status < 0) || (jar->valid < 0)) {
        if (status >= JAR_BASE && status <= JAR_BASE_END) {
            error(PK11_INSTALL_JAR_ERROR, jarFile, JAR_get_error(status));
        } else {
            error(PK11_INSTALL_JAR_ERROR, jarFile,
                  mySECU_ErrorString(PORT_GetError()));
        }
        ret = PK11_INSTALL_JAR_ERROR;
        goto loser;
    }
    /*printf("passed the archive\n");*/

    /*
     * Show the user security information, allow them to abort or continue
     */
    if (Pk11Install_UserVerifyJar(jar, PR_STDOUT,
                                  force ?
                                        PR_FALSE
                                        :
                                        PR_TRUE) &&
        !force) {
        if (feedback) {
            PR_fprintf(feedback, msgStrings[USER_ABORT]);
        }
        ret = PK11_INSTALL_USER_ABORT;
        goto loser;
    }

    /*
     * Get the name of the installation file
     */
    if (JAR_get_metainfo(jar, NULL, INSTALL_METAINFO_TAG, (void **)&installer,
                         (unsigned long *)&installer_len)) {
        error(PK11_INSTALL_NO_INSTALLER_SCRIPT);
        ret = PK11_INSTALL_NO_INSTALLER_SCRIPT;
        goto loser;
    }
    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLER_SCRIPT_NAME], installer);
    }

    /*
     * Extract the installation file
     */
    if (PR_Access(SCRIPT_TEMP_FILE, PR_ACCESS_EXISTS) == PR_SUCCESS) {
        if (PR_Delete(SCRIPT_TEMP_FILE) != PR_SUCCESS) {
            error(PK11_INSTALL_DELETE_TEMP_FILE, SCRIPT_TEMP_FILE);
            ret = PK11_INSTALL_DELETE_TEMP_FILE;
            goto loser;
        }
    }
    if (noverify) {
        status = JAR_extract(jar, installer, SCRIPT_TEMP_FILE);
    } else {
        status = JAR_verified_extract(jar, installer, SCRIPT_TEMP_FILE);
    }
    if (status) {
        if (status >= JAR_BASE && status <= JAR_BASE_END) {
            error(PK11_INSTALL_JAR_EXTRACT, installer, JAR_get_error(status));
        } else {
            error(PK11_INSTALL_JAR_EXTRACT, installer,
                  mySECU_ErrorString(PORT_GetError()));
        }
        ret = PK11_INSTALL_JAR_EXTRACT;
        goto loser;
    } else {
        made_temp_file = PR_TRUE;
    }

    /*
     * Parse the installation file into a syntax tree
     */
    Pk11Install_FD = PR_Open(SCRIPT_TEMP_FILE, PR_RDONLY, 0);
    if (!Pk11Install_FD) {
        error(PK11_INSTALL_OPEN_SCRIPT_FILE, SCRIPT_TEMP_FILE);
        ret = PK11_INSTALL_OPEN_SCRIPT_FILE;
        goto loser;
    }
    if (Pk11Install_yyparse()) {
        error(PK11_INSTALL_SCRIPT_PARSE, installer,
              Pk11Install_yyerrstr ? Pk11Install_yyerrstr : "");
        ret = PK11_INSTALL_SCRIPT_PARSE;
        goto loser;
    }

#if 0
    /* for debugging */
    Pk11Install_valueList->Print(0);
#endif

    /*
     * From the syntax tree, build a semantic structure
     */
    errMsg = Pk11Install_Info_Generate(&installInfo, Pk11Install_valueList);
    if (errMsg) {
        error(PK11_INSTALL_SEMANTIC, errMsg);
        ret = PK11_INSTALL_SEMANTIC;
        goto loser;
    }
#if 0
    installInfo.Print(0);
#endif

    if (feedback) {
        PR_fprintf(feedback, msgStrings[PARSED_INSTALL_SCRIPT]);
    }

    /*
     * Figure out which platform to use
     */
    {
        sysname[0] = release[0] = arch[0] = '\0';

        if ((PR_GetSystemInfo(PR_SI_SYSNAME, sysname, SYS_INFO_BUFFER_LENGTH) !=
             PR_SUCCESS) ||
            (PR_GetSystemInfo(PR_SI_RELEASE, release, SYS_INFO_BUFFER_LENGTH) !=
             PR_SUCCESS) ||
            (PR_GetSystemInfo(PR_SI_ARCHITECTURE, arch, SYS_INFO_BUFFER_LENGTH) !=
             PR_SUCCESS)) {
            error(PK11_INSTALL_SYSINFO);
            ret = PK11_INSTALL_SYSINFO;
            goto loser;
        }
        myPlatform = PR_smprintf("%s:%s:%s", sysname, release, arch);
        platform = Pk11Install_Info_GetBestPlatform(&installInfo, myPlatform);
        if (!platform) {
            error(PK11_INSTALL_NO_PLATFORM, myPlatform);
            PR_smprintf_free(myPlatform);
            ret = PK11_INSTALL_NO_PLATFORM;
            goto loser;
        }
        if (feedback) {
            PR_fprintf(feedback, msgStrings[MY_PLATFORM_IS], myPlatform);
            PR_fprintf(feedback, msgStrings[USING_PLATFORM],
                       Pk11Install_PlatformName_GetString(&platform->name));
        }
        PR_smprintf_free(myPlatform);
    }

    /* Run the install for that platform */
    ret = DoInstall(jar, installDir, tempDir, platform, feedback, noverify);
    if (ret) {
        goto loser;
    }

    ret = PK11_INSTALL_SUCCESS;
loser:
    if (Pk11Install_valueList) {
        Pk11Install_ValueList_delete(Pk11Install_valueList);
        PR_Free(Pk11Install_valueList);
        Pk11Install_valueList = NULL;
    }
    if (jar) {
        JAR_destroy(jar);
    }
    if (made_temp_file) {
        PR_Delete(SCRIPT_TEMP_FILE);
    }
    if (errMsg) {
        PR_smprintf_free(errMsg);
    }
    return ret;
}
Beispiel #23
0
/*
 * Decode the DER/BER-encoded item "data" as an OCSP response
 * and pretty-print the subfields.
 */
static SECStatus
print_response (FILE *out_file, SECItem *data, CERTCertDBHandle *handle)
{
    CERTOCSPResponse *response;
    int level = 0;

    PORT_Assert (out_file != NULL);
    PORT_Assert (data != NULL);
    if (out_file == NULL || data == NULL) {
	PORT_SetError (SEC_ERROR_INVALID_ARGS);
	return SECFailure;
    }

    response = CERT_DecodeOCSPResponse (data);
    if (response == NULL)
	return SECFailure;

    if (response->statusValue >= ocspResponse_min &&
	response->statusValue <= ocspResponse_max) {
	fprintf (out_file, "Response Status: %s\n",
		 responseStatusNames[response->statusValue]);
    } else {
	fprintf (out_file,
		 "Response Status: other (Status value %d out of defined range)\n",
		 (int)response->statusValue);
    }

    if (response->statusValue == ocspResponse_successful) {
	ocspResponseBytes *responseBytes = response->responseBytes;
	SECStatus sigStatus;
	CERTCertificate *signerCert = NULL;

	PORT_Assert (responseBytes != NULL);

	level++;
	fprintf (out_file, "Response Bytes:\n");
	SECU_PrintObjectID (out_file, &(responseBytes->responseType),
			    "Response Type", level);
	switch (response->responseBytes->responseTypeTag) {
	  case SEC_OID_PKIX_OCSP_BASIC_RESPONSE:
	    print_basic_response (out_file,
				  responseBytes->decodedResponse.basic,
				  level);
	    break;
	  default:
	    SECU_Indent (out_file, level);
	    fprintf (out_file, "Unknown response syntax\n");
	    break;
	}

	sigStatus = CERT_VerifyOCSPResponseSignature (response, handle,
						      NULL, &signerCert, NULL);
	SECU_Indent (out_file, level);
	fprintf (out_file, "Signature verification ");
	if (sigStatus != SECSuccess) {
	    fprintf (out_file, "failed: %s\n", SECU_Strerror (PORT_GetError()));
	} else {
	    fprintf (out_file, "succeeded.\n");
	    if (signerCert != NULL) {
		SECU_PrintName (out_file, &signerCert->subject, "Signer",
				level);
		CERT_DestroyCertificate (signerCert);
	    } else {
		SECU_Indent (out_file, level);
		fprintf (out_file, "No signer cert returned?\n");
	    }
	}
    } else {
	SECU_Indent (out_file, level);
	fprintf (out_file, "Unsuccessful response, no more information.\n");
    }

    CERT_DestroyOCSPResponse (response);
    return SECSuccess;
}
Beispiel #24
0
/*
/////////////////////////////////////////////////////////////////////////
// actually run the installation, copying files to and fro
*/
static Pk11Install_Error
DoInstall(JAR *jar, const char *installDir, const char *tempDir,
          Pk11Install_Platform *platform, PRFileDesc *feedback, PRBool noverify)
{
    Pk11Install_File *file;
    Pk11Install_Error ret;
    char *reldir;
    char *dest;
    char *modDest;
    char *cp;
    int i;
    int status;
    char *tempname, *temp;
    StringList executables;
    StringNode *execNode;
    PRProcessAttr *attr;
    PRProcess *proc;
    char *argv[2];
    char *envp[1];
    int errcode;

    ret = PK11_INSTALL_UNSPECIFIED;
    reldir = NULL;
    dest = NULL;
    modDest = NULL;
    tempname = NULL;

    StringList_new(&executables);
    /*
    // Create Temporary directory
    */
    tempname = PR_smprintf("%s/%s", tempDir, TEMPORARY_DIRECTORY_NAME);
    if (PR_Access(tempname, PR_ACCESS_EXISTS) == PR_SUCCESS) {
        /* Left over from previous run?  Delete it. */
        rm_dash_r(tempname);
    }
    if (PR_MkDir(tempname, 0700) != PR_SUCCESS) {
        error(PK11_INSTALL_CREATE_DIR, tempname);
        ret = PK11_INSTALL_CREATE_DIR;
        goto loser;
    }

    /*
    // Install all the files
    */
    for (i = 0; i < platform->numFiles; i++) {
        file = &platform->files[i];

        if (file->relativePath) {
            PRBool foundMarker = PR_FALSE;
            reldir = PR_Strdup(file->relativePath);

            /* Replace all the markers with the directories for which they stand */
            while (1) {
                if ((cp = PL_strcasestr(reldir, ROOT_MARKER))) {
                    /* Has a %root% marker  */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, installDir,
                                       cp + strlen(ROOT_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else if ((cp = PL_strcasestr(reldir, TEMP_MARKER))) {
                    /* Has a %temp% marker */
                    *cp = '\0';
                    temp = PR_smprintf("%s%s%s", reldir, tempname,
                                       cp + strlen(TEMP_MARKER));
                    PR_Free(reldir);
                    reldir = temp;
                    foundMarker = PR_TRUE;
                } else {
                    break;
                }
            }
            if (!foundMarker) {
                /* Has no markers...this isn't really a relative directory */
                error(PK11_INSTALL_BOGUS_REL_DIR, file->relativePath);
                ret = PK11_INSTALL_BOGUS_REL_DIR;
                goto loser;
            }
            dest = reldir;
            reldir = NULL;
        } else if (file->absolutePath) {
            dest = PR_Strdup(file->absolutePath);
        }

        /* Remember if this is the module file, we'll need to add it later */
        if (i == platform->modFile) {
            modDest = PR_Strdup(dest);
        }

        /* Remember is this is an executable, we'll need to run it later */
        if (file->executable) {
            StringList_Append(&executables, dest);
            /*executables.Append(dest);*/
        }

        /* Make sure the directory we are targetting exists */
        if (make_dirs(dest, file->permissions)) {
            ret = PK11_INSTALL_CREATE_DIR;
            goto loser;
        }

        /* Actually extract the file onto the filesystem */
        if (noverify) {
            status = JAR_extract(jar, (char *)file->jarPath, dest);
        } else {
            status = JAR_verified_extract(jar, (char *)file->jarPath, dest);
        }
        if (status) {
            if (status >= JAR_BASE && status <= JAR_BASE_END) {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      JAR_get_error(status));
            } else {
                error(PK11_INSTALL_JAR_EXTRACT, file->jarPath,
                      mySECU_ErrorString(PORT_GetError()));
            }
            ret = PK11_INSTALL_JAR_EXTRACT;
            goto loser;
        }
        if (feedback) {
            PR_fprintf(feedback, msgStrings[INSTALLED_FILE_MSG],
                       file->jarPath, dest);
        }

/* no NSPR command to change permissions? */
#ifdef XP_UNIX
        chmod(dest, file->permissions);
#endif

        /* Memory clean-up tasks */
        if (reldir) {
            PR_Free(reldir);
            reldir = NULL;
        }
        if (dest) {
            PR_Free(dest);
            dest = NULL;
        }
    }
    /* Make sure we found the module file */
    if (!modDest) {
        /* Internal problem here, since every platform is supposed to have
           a module file */
        error(PK11_INSTALL_NO_MOD_FILE, platform->moduleName);
        ret = PK11_INSTALL_NO_MOD_FILE;
        goto loser;
    }

    /*
    // Execute any executable files
    */
    {
        argv[1] = NULL;
        envp[0] = NULL;
        for (execNode = executables.head; execNode; execNode = execNode->next) {
            attr = PR_NewProcessAttr();
            argv[0] = PR_Strdup(execNode->str);

            /* Announce our intentions */
            if (feedback) {
                PR_fprintf(feedback, msgStrings[EXEC_FILE_MSG], execNode->str);
            }

            /* start the process */
            if (!(proc = PR_CreateProcess(execNode->str, argv, envp, attr))) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_EXEC_FILE, execNode->str);
                ret = PK11_INSTALL_EXEC_FILE;
                goto loser;
            }

            /* wait for it to finish */
            if (PR_WaitProcess(proc, &errcode) != PR_SUCCESS) {
                PR_Free(argv[0]);
                PR_DestroyProcessAttr(attr);
                error(PK11_INSTALL_WAIT_PROCESS, execNode->str);
                ret = PK11_INSTALL_WAIT_PROCESS;
                goto loser;
            }

            /* What happened? */
            if (errcode) {
                /* process returned an error */
                error(PK11_INSTALL_PROC_ERROR, execNode->str, errcode);
            } else if (feedback) {
                /* process ran successfully */
                PR_fprintf(feedback, msgStrings[EXEC_SUCCESS], execNode->str);
            }

            PR_Free(argv[0]);
            PR_DestroyProcessAttr(attr);
        }
    }

    /*
    // Add the module
    */
    status = Pk11Install_AddNewModule((char *)platform->moduleName,
                                      (char *)modDest, platform->mechFlags, platform->cipherFlags);

    if (status != SECSuccess) {
        error(PK11_INSTALL_ADD_MODULE, platform->moduleName);
        ret = PK11_INSTALL_ADD_MODULE;
        goto loser;
    }
    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLED_MODULE_MSG],
                   platform->moduleName);
    }

    if (feedback) {
        PR_fprintf(feedback, msgStrings[INSTALLATION_COMPLETE_MSG]);
    }

    ret = PK11_INSTALL_SUCCESS;

loser:
    if (reldir) {
        PR_Free(reldir);
    }
    if (dest) {
        PR_Free(dest);
    }
    if (modDest) {
        PR_Free(modDest);
    }
    if (tempname) {
        PRFileInfo info;
        if (PR_GetFileInfo(tempname, &info) == PR_SUCCESS) {
            if (info.type == PR_FILE_DIRECTORY) {
                /* Recursively remove temporary directory */
                if (rm_dash_r(tempname)) {
                    error(PK11_INSTALL_REMOVE_DIR,
                          tempname);
                    ret = PK11_INSTALL_REMOVE_DIR;
                }
            }
        }
        PR_Free(tempname);
    }
    StringList_delete(&executables);
    return ret;
}
Beispiel #25
0
static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType, PRBool deletecrls)
{
    CERTCrlHeadNode *crlList = NULL;
    CERTCrlNode *crlNode = NULL;
    CERTName *name = NULL;
    PLArenaPool *arena = NULL;
    SECStatus rv;

    do {
	arena = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
	if (arena == NULL) {
	    fprintf(stderr, "%s: fail to allocate memory\n", progName);
	    break;
	}
	
	name = PORT_ArenaZAlloc (arena, sizeof(*name));
	if (name == NULL) {
	    fprintf(stderr, "%s: fail to allocate memory\n", progName);
	    break;
	}
	name->arena = arena;
	    
	rv = SEC_LookupCrls (certHandle, &crlList, crlType);
	if (rv != SECSuccess) {
	    fprintf(stderr, "%s: fail to look up CRLs (%s)\n", progName,
	    SECU_Strerror(PORT_GetError()));
	    break;
	}
	
	/* just in case */
	if (!crlList)
	    break;

	crlNode  = crlList->first;

        fprintf (stdout, "\n");
	fprintf (stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type");
	while (crlNode) {
	    char* asciiname = NULL;
	    CERTCertificate *cert = NULL;
	    if (crlNode->crl && &crlNode->crl->crl.derName) {
	        cert = CERT_FindCertByName(certHandle,
	                                   &crlNode->crl->crl.derName);
	        if (!cert) {
	            SECU_PrintError(progName, "could not find signing "
	                         "certificate in database");
	        }
	    }
	    if (cert) {
	        char* certName = NULL;
                 if (cert->nickname && PORT_Strlen(cert->nickname) > 0) {
	            certName = cert->nickname;
	        } else if (cert->emailAddr && PORT_Strlen(cert->emailAddr) > 0) {
	            certName = cert->emailAddr;
	        }
	        if (certName) {
	            asciiname = PORT_Strdup(certName);
	        }
	        CERT_DestroyCertificate(cert);
	    }
                
	    if (!asciiname) {
	        name = &crlNode->crl->crl.name;
	        if (!name){
	            SECU_PrintError(progName, "fail to get the CRL "
	                           "issuer name");
	            continue;
	        }
	        asciiname = CERT_NameToAscii(name);
	    }
	    fprintf (stdout, "%-40s %-5s\n", asciiname, "CRL");
	    if (asciiname) {
		PORT_Free(asciiname);
	    }
            if ( PR_TRUE == deletecrls) {
                CERTSignedCrl* acrl = NULL;
                SECItem* issuer = &crlNode->crl->crl.derName;
                acrl = SEC_FindCrlByName(certHandle, issuer, crlType);
                if (acrl)
                {
                    SEC_DeletePermCRL(acrl);
                    SEC_DestroyCrl(acrl);
                }
            }
            crlNode = crlNode->next;
	} 
	
    } while (0);
    if (crlList)
	PORT_FreeArena (crlList->arena, PR_FALSE);
    PORT_FreeArena (arena, PR_FALSE);
}
Beispiel #26
0
/*
** Generate and return a new RSA public and private key.
**	Both keys are encoded in a single RSAPrivateKey structure.
**	"cx" is the random number generator context
**	"keySizeInBits" is the size of the key to be generated, in bits.
**	   512, 1024, etc.
**	"publicExponent" when not NULL is a pointer to some data that
**	   represents the public exponent to use. The data is a byte
**	   encoded integer, in "big endian" order.
*/
RSAPrivateKey *
RSA_NewKey(int keySizeInBits, SECItem *publicExponent)
{
    unsigned int primeLen;
    mp_int p, q, e, d;
    int kiter;
    mp_err   err = MP_OKAY;
    SECStatus rv = SECSuccess;
    int prerr = 0;
    RSAPrivateKey *key = NULL;
    PLArenaPool *arena = NULL;
    /* Require key size to be a multiple of 16 bits. */
    if (!publicExponent || keySizeInBits % 16 != 0 ||
	    BAD_RSA_KEY_SIZE(keySizeInBits/8, publicExponent->len)) {
	PORT_SetError(SEC_ERROR_INVALID_ARGS);
	return NULL;
    }
    /* 1. Allocate arena & key */
    arena = PORT_NewArena(NSS_FREEBL_DEFAULT_CHUNKSIZE);
    if (!arena) {
	PORT_SetError(SEC_ERROR_NO_MEMORY);
	return NULL;
    }
    key = PORT_ArenaZNew(arena, RSAPrivateKey);
    if (!key) {
	PORT_SetError(SEC_ERROR_NO_MEMORY);
	PORT_FreeArena(arena, PR_TRUE);
	return NULL;
    }
    key->arena = arena;
    /* length of primes p and q (in bytes) */
    primeLen = keySizeInBits / (2 * PR_BITS_PER_BYTE);
    MP_DIGITS(&p) = 0;
    MP_DIGITS(&q) = 0;
    MP_DIGITS(&e) = 0;
    MP_DIGITS(&d) = 0;
    CHECK_MPI_OK( mp_init(&p) );
    CHECK_MPI_OK( mp_init(&q) );
    CHECK_MPI_OK( mp_init(&e) );
    CHECK_MPI_OK( mp_init(&d) );
    /* 2.  Set the version number (PKCS1 v1.5 says it should be zero) */
    SECITEM_AllocItem(arena, &key->version, 1);
    key->version.data[0] = 0;
    /* 3.  Set the public exponent */
    SECITEM_TO_MPINT(*publicExponent, &e);
    kiter = 0;
    do {
	prerr = 0;
	PORT_SetError(0);
	CHECK_SEC_OK( generate_prime(&p, primeLen) );
	CHECK_SEC_OK( generate_prime(&q, primeLen) );
	/* Assure q < p */
	if (mp_cmp(&p, &q) < 0)
	    mp_exch(&p, &q);
	/* Attempt to use these primes to generate a key */
	rv = rsa_build_from_primes(&p, &q, 
			&e, PR_FALSE,  /* needPublicExponent=false */
			&d, PR_TRUE,   /* needPrivateExponent=true */
			key, keySizeInBits);
	if (rv == SECSuccess)
	    break; /* generated two good primes */
	prerr = PORT_GetError();
	kiter++;
	/* loop until have primes */
    } while (prerr == SEC_ERROR_NEED_RANDOM && kiter < MAX_KEY_GEN_ATTEMPTS);
    if (prerr)
	goto cleanup;
cleanup:
    mp_clear(&p);
    mp_clear(&q);
    mp_clear(&e);
    mp_clear(&d);
    if (err) {
	MP_TO_SEC_ERROR(err);
	rv = SECFailure;
    }
    if (rv && arena) {
	PORT_FreeArena(arena, PR_TRUE);
	key = NULL;
    }
    return key;
}
Beispiel #27
0
/*
 * generate an RSA signature key
 *
 * e is fixed at 3, without discussion.  That would not be wise if these
 * keys were to be used for encryption, but for signatures there are some
 * real speed advantages.
 * See also: https://www.imperialviolet.org/2012/03/16/rsae.html
 */
void rsasigkey(int nbits, int seedbits, const struct lsw_conf_options *oco)
{
	PK11RSAGenParams rsaparams = { nbits, (long) F4 };
	PK11SlotInfo *slot = NULL;
	SECKEYPrivateKey *privkey = NULL;
	SECKEYPublicKey *pubkey = NULL;
	realtime_t now = realnow();

	lsw_nss_buf_t err;
	if (!lsw_nss_setup(oco->nssdir, 0, lsw_nss_get_password, err)) {
		fprintf(stderr, "%s: %s\n", progname, err);
		exit(1);
	}

#ifdef FIPS_CHECK
	if (PK11_IsFIPS() && !FIPSCHECK_verify(NULL, NULL)) {
		fprintf(stderr,
			"FIPS HMAC integrity verification test failed.\n");
		exit(1);
	}
#endif

	/* Good for now but someone may want to use a hardware token */
	slot = lsw_nss_get_authenticated_slot(err);
	if (slot == NULL) {
		fprintf(stderr, "%s: %s\n", progname, err);
		lsw_nss_shutdown();
		exit(1);
	}

	/* Do some random-number initialization. */
	UpdateNSS_RNG(seedbits);
	privkey = PK11_GenerateKeyPair(slot,
				       CKM_RSA_PKCS_KEY_PAIR_GEN,
				       &rsaparams, &pubkey,
				       PR_TRUE,
				       PK11_IsFIPS() ? PR_TRUE : PR_FALSE,
				       lsw_return_nss_password_file_info());
	/* inTheToken, isSensitive, passwordCallbackFunction */
	if (privkey == NULL) {
		fprintf(stderr,
			"%s: key pair generation failed: \"%d\"\n", progname,
			PORT_GetError());
		return;
	}

	chunk_t public_modulus = {
		.ptr = pubkey->u.rsa.modulus.data,
		.len = pubkey->u.rsa.modulus.len,
	};
	chunk_t public_exponent = {
		.ptr = pubkey->u.rsa.publicExponent.data,
		.len = pubkey->u.rsa.publicExponent.len,
	};

	char *hex_ckaid;
	{
		SECItem *ckaid = PK11_GetLowLevelKeyIDForPrivateKey(privkey);
		if (ckaid == NULL) {
			fprintf(stderr, "%s: 'CKAID' calculation failed\n", progname);
			exit(1);
		}
		hex_ckaid = strdup(conv(ckaid->data, ckaid->len, 16));
		SECITEM_FreeItem(ckaid, PR_TRUE);
	}

	/*privkey->wincx = &pwdata;*/
	PORT_Assert(pubkey != NULL);
	fprintf(stderr, "Generated RSA key pair with CKAID %s was stored in the NSS database\n",
		hex_ckaid);

	/* and the output */
	libreswan_log("output...\n");  /* deliberate extra newline */
	printf("\t# RSA %d bits   %s   %s", nbits, outputhostname,
		ctime(&now.rt.tv_sec));
	/* ctime provides \n */
	printf("\t# for signatures only, UNSAFE FOR ENCRYPTION\n");

	printf("\t#ckaid=%s\n", hex_ckaid);

	/* RFC2537/RFC3110-ish format */
	{
		char *base64 = NULL;
		err_t err = rsa_pubkey_to_base64(public_exponent, public_modulus, &base64);
		if (err) {
			fprintf(stderr, "%s: unexpected error encoding RSA public key '%s'\n",
				progname, err);
			exit(1);
		}
		printf("\t#pubkey=%s\n", base64);
		pfree(base64);
	}

	printf("\tModulus: 0x%s\n", conv(public_modulus.ptr, public_modulus.len, 16));
	printf("\tPublicExponent: 0x%s\n", conv(public_exponent.ptr, public_exponent.len, 16));

	if (hex_ckaid != NULL)
		free(hex_ckaid);
	if (privkey != NULL)
		SECKEY_DestroyPrivateKey(privkey);
	if (pubkey != NULL)
		SECKEY_DestroyPublicKey(pubkey);

	lsw_nss_shutdown();
}

/*
 * lsw_random - get some random bytes from /dev/random (or wherever)
 * NOTE: This is only used for additional seeding of the NSS RNG
 */
void lsw_random(size_t nbytes, unsigned char *buf)
{
	size_t ndone;
	int dev;
	ssize_t got;

	dev = open(device, 0);
	if (dev < 0) {
		fprintf(stderr, "%s: could not open %s (%s)\n", progname,
			device, strerror(errno));
		exit(1);
	}

	ndone = 0;
	libreswan_log("getting %d random seed bytes for NSS from %s...\n",
		      (int) nbytes * BITS_PER_BYTE, device);
	while (ndone < nbytes) {
		got = read(dev, buf + ndone, nbytes - ndone);
		if (got < 0) {
			fprintf(stderr, "%s: read error on %s (%s)\n", progname,
				device, strerror(errno));
			exit(1);
		}
		if (got == 0) {
			fprintf(stderr, "%s: eof on %s!?!\n", progname, device);
			exit(1);
		}
		ndone += got;
	}

	close(dev);
}

/*
   - conv - convert bits to output in specified datatot format
 * NOTE: result points into a STATIC buffer
 */
static const char *conv(const unsigned char *bits, size_t nbytes, int format)
{
	static char convbuf[MAXBITS / 4 + 50];  /* enough for hex */
	size_t n;

	n = datatot(bits, nbytes, format, convbuf, sizeof(convbuf));
	if (n == 0) {
		fprintf(stderr, "%s: can't-happen convert error\n", progname);
		exit(1);
	}
	if (n > sizeof(convbuf)) {
		fprintf(stderr,
			"%s: can't-happen convert overflow (need %d)\n",
			progname, (int) n);
		exit(1);
	}
	return convbuf;
}
Beispiel #28
0
int
PKIX_PL_GetPLErrorCode()
{
    return PORT_GetError();
}
Beispiel #29
0
int nss_crypto_init(struct crypto_mech_data *mech_props,
                    enum crypto_mech_op crypto_op,
                    struct sss_nss_crypto_ctx *cctx)
{
    CK_ATTRIBUTE_TYPE op;
    int ret;

    switch (crypto_op) {
    case op_encrypt:
        op = CKA_ENCRYPT;
        break;
    case op_decrypt:
        op = CKA_DECRYPT;
        break;
    case op_sign:
        op = CKA_SIGN;
        break;
    default:
        return EFAULT;
    }

    /* turn the raw key into a key object */
    cctx->keyobj = PK11_ImportSymKey(cctx->slot, mech_props->cipher,
                                     PK11_OriginUnwrap, op, cctx->key, NULL);
    if (cctx->keyobj == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Failure to import key into NSS (err %d)\n",
              PR_GetError());
        ret = EIO;
        goto done;
    }

    if (crypto_op == op_encrypt || crypto_op == op_decrypt) {
        /* turn the raw IV into a initialization vector object */
        cctx->sparam = PK11_ParamFromIV(mech_props->cipher, cctx->iv);
        if (cctx->sparam == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE,
                  "Failure to set up PKCS11 param (err %d)\n",
                  PR_GetError());
            ret = EIO;
            goto done;
        }
    } else {
        cctx->sparam = SECITEM_AllocItem(NULL, NULL, 0);
        if (cctx->sparam == NULL) {
            DEBUG(SSSDBG_CRIT_FAILURE, "Failure to allocate SECItem\n");
            ret = EIO;
            goto done;
        }
        MAKE_SECITEM(NULL, 0, cctx->sparam);
    }

    /* Create cipher context */
    cctx->ectx = PK11_CreateContextBySymKey(mech_props->cipher, op,
                                            cctx->keyobj, cctx->sparam);
    if (cctx->ectx == NULL) {
        DEBUG(SSSDBG_CRIT_FAILURE, "Cannot create cipher context (err %d)\n",
              PORT_GetError());
        ret = EIO;
        goto done;
    }

    ret = EOK;
done:
    return ret;
}
Beispiel #30
0
int
main()
{
    SECItem badTime;
    PRTime prtime;
    SECStatus rv;
    int error;
    PRBool failed = PR_FALSE;

    /* A UTCTime string with an embedded null. */
    badTime.type = siBuffer;
    badTime.data = (unsigned char *)"091219000000Z\0junkjunkjunkjunkjunkjunk";
    badTime.len = 38;
    rv = DER_UTCTimeToTime(&prtime, &badTime);
    if (rv == SECSuccess) {
        fprintf(stderr, "DER_UTCTimeToTime should have failed but "
                        "succeeded\n");
        failed = PR_TRUE;
    } else {
        error = PORT_GetError();
        if (error != SEC_ERROR_INVALID_TIME) {
            fprintf(stderr, "DER_UTCTimeToTime failed with error %d, "
                            "expected error %d\n",
                    error, SEC_ERROR_INVALID_TIME);
            failed = PR_TRUE;
        }
    }

    /* A UTCTime string with junk after a valid date/time. */
    badTime.type = siBuffer;
    badTime.data = (unsigned char *)"091219000000Zjunk";
    badTime.len = 17;
    rv = DER_UTCTimeToTime(&prtime, &badTime);
    if (rv == SECSuccess) {
        fprintf(stderr, "DER_UTCTimeToTime should have failed but "
                        "succeeded\n");
        failed = PR_TRUE;
    } else {
        error = PORT_GetError();
        if (error != SEC_ERROR_INVALID_TIME) {
            fprintf(stderr, "DER_UTCTimeToTime failed with error %d, "
                            "expected error %d\n",
                    error, SEC_ERROR_INVALID_TIME);
            failed = PR_TRUE;
        }
    }

    /* A GeneralizedTime string with an embedded null. */
    badTime.type = siBuffer;
    badTime.data = (unsigned char *)"20091219000000Z\0junkjunkjunkjunkjunkjunk";
    badTime.len = 40;
    rv = DER_GeneralizedTimeToTime(&prtime, &badTime);
    if (rv == SECSuccess) {
        fprintf(stderr, "DER_GeneralizedTimeToTime should have failed but "
                        "succeeded\n");
        failed = PR_TRUE;
    } else {
        error = PORT_GetError();
        if (error != SEC_ERROR_INVALID_TIME) {
            fprintf(stderr, "DER_GeneralizedTimeToTime failed with error %d, "
                            "expected error %d\n",
                    error, SEC_ERROR_INVALID_TIME);
            failed = PR_TRUE;
        }
    }

    /* A GeneralizedTime string with junk after a valid date/time. */
    badTime.type = siBuffer;
    badTime.data = (unsigned char *)"20091219000000Zjunk";
    badTime.len = 19;
    rv = DER_GeneralizedTimeToTime(&prtime, &badTime);
    if (rv == SECSuccess) {
        fprintf(stderr, "DER_GeneralizedTimeToTime should have failed but "
                        "succeeded\n");
        failed = PR_TRUE;
    } else {
        error = PORT_GetError();
        if (error != SEC_ERROR_INVALID_TIME) {
            fprintf(stderr, "DER_GeneralizedTimeToTime failed with error %d, "
                            "expected error %d\n",
                    error, SEC_ERROR_INVALID_TIME);
            failed = PR_TRUE;
        }
    }

    if (failed) {
        fprintf(stderr, "FAIL\n");
        return 1;
    }
    printf("PASS\n");
    return 0;
}