Beispiel #1
0
/*
	Preferred version for commercial users who make use of memory pools.

	This use of the sslKeys_t param implies this is for use in the MatrixSSL
	product (input to matrixSslNewSession).  However, we didn't want to
	expose this API at the matrixSsl.h level due to the pool parameter. This
	is strictly an API that commerical users will have access to.
*/
int32 matrixRsaParseKeysMem(psPool_t *pool, sslKeys_t **keys,
			unsigned char *certBuf,	int32 certLen, unsigned char *privBuf,
			int32 privLen, unsigned char *trustedCABuf, int32 trustedCALen)
{
	sslKeys_t		*lkeys;
	sslLocalCert_t	*current, *next;
	unsigned char	*binPtr;
	int32			len, lenOh, i;
#ifdef USE_CLIENT_SIDE_SSL
	sslRsaCert_t	*currentCA, *nextCA;
#endif /* USE_CLIENT_SIDE_SSL */

	*keys = lkeys = psMalloc(pool, sizeof(sslKeys_t));
	if (lkeys == NULL) {
		return -8; /* SSL_MEM_ERROR */
	}
	memset(lkeys, 0x0, sizeof(sslKeys_t));
/*
	The buffers are just the ASN.1 streams so the intermediate parse
	that used to be here is gone.  Doing a straight memcpy for this
	and passing that along to X509ParseCert
*/
	i = 0;
	current = &lkeys->cert;
	binPtr = certBuf;
/*
	Need to check for a chain here.  Only way to do this is to read off the
	length id from the DER stream for each.  The chain must be just a stream
	of DER certs with the child-most cert always first.
*/
	while (certLen > 0) {
		if (getSequence(&certBuf, certLen, &len) < 0) {
			matrixStrDebugMsg("Unable to parse length of cert stream\n", NULL);
			matrixRsaFreeKeys(lkeys);
			return -1;
		}
/*
		Account for the overhead of storing the length itself
*/
		lenOh = (int32)(certBuf - binPtr);
		len += lenOh;
		certBuf -= lenOh;
/*
		First cert is already malloced
*/
		if (i > 0) {
			next = psMalloc(pool, sizeof(sslLocalCert_t));
			memset(next, 0x0, sizeof(sslLocalCert_t));
			current->next = next;
			current = next;
		}
		current->certBin = psMalloc(pool, len);
		memcpy(current->certBin, certBuf, len);
		current->certLen = len;
		certLen -= len;
		certBuf += len;
		binPtr = certBuf;
		i++;
	}

/*
	Parse private key
*/
	if (privLen > 0) {
		if (matrixRsaParsePrivKey(pool, privBuf, privLen,
				&lkeys->cert.privKey) < 0) {
			matrixStrDebugMsg("Error reading private key mem\n", NULL);
			matrixRsaFreeKeys(lkeys);
			return -1;
		}
	}


/*
	Trusted CAs
*/
#ifdef USE_CLIENT_SIDE_SSL
	if (trustedCABuf != NULL && trustedCALen > 0) {
		i = 0;
		binPtr = trustedCABuf;
		currentCA = NULL;
/*
		Need to check for list here.  Only way to do this is to read off the
		length id from the DER stream for each.
*/
		while (trustedCALen > 0) {
			if (getSequence(&trustedCABuf, trustedCALen, &len) < 0) {
				matrixStrDebugMsg("Unable to parse length of CA stream\n",
					NULL);
				matrixRsaFreeKeys(lkeys);
				return -1;
			}
/*
			Account for the overhead of storing the length itself
*/
			lenOh = (int32)(trustedCABuf - binPtr);
			len += lenOh;
			trustedCABuf -= lenOh;

			if (matrixX509ParseCert(pool, trustedCABuf, len, &currentCA) < 0) {
				matrixStrDebugMsg("Error parsing CA cert\n", NULL);
				matrixRsaFreeKeys(lkeys);
				return -1;
			}
/*
			First cert should be assigned to lkeys
*/
			if (i == 0) {
				lkeys->caCerts = currentCA;
				nextCA = lkeys->caCerts;
			} else {
				nextCA->next = currentCA;
				nextCA = currentCA;
			}
			currentCA = currentCA->next;
			trustedCALen -= len;
			trustedCABuf += len;
			binPtr = trustedCABuf;
			i++;
		}
	}
#endif /* USE_CLIENT_SIDE_SSL */

	return 0;
}
Beispiel #2
0
void matrixSslFreeKeys(sslKeys_t *keys)
{
    matrixRsaFreeKeys(keys);
}
Beispiel #3
0
/*
	Preferred version for commercial users who make use of memory pools.

	This use of the sslKeys_t param implies this is for use in the MatrixSSL
	product (input to matrixSslNewSession).  However, we didn't want to
	expose this API at the matrixSsl.h level due to the pool parameter. This
	is strictly an API that commerical users will have access to
*/
int32 matrixRsaReadKeysEx(psPool_t *pool, sslKeys_t **keys,
				const char *certFile, const char *privFile,
				const char *privPass, const char *trustedCAFiles)
{
	sslKeys_t		*lkeys;
	unsigned char	*privKeyMem;
	int32			rc, privKeyMemLen;
#ifdef USE_CLIENT_SIDE_SSL
	sslRsaCert_t	*currCert, *prevCert = NULL;
	unsigned char	*caCert, *caStream;
	sslChainLen_t	chain;
	int32			caCertLen, first, i;
#endif /* USE_CLIENT_SIDE_SSL */

	*keys = lkeys = psMalloc(pool, sizeof(sslKeys_t));
	if (lkeys == NULL) {
		return -8; /* SSL_MEM_ERROR */
	}
	memset(lkeys, 0x0, sizeof(sslKeys_t));
/*
	Load certificate files.  Any additional certificate files should chain
	to the root CA held on the other side.
*/
	rc = readCertChain(pool, certFile, &lkeys->cert);
	if (rc < 0 ) {
		matrixRsaFreeKeys(lkeys);
		return rc;
	}
/*
	The first cert in certFile must be associated with the provided
	private key. 
*/
	if (privFile) {
		rc = matrixRsaReadPrivKey(pool, privFile, privPass, &privKeyMem,
			&privKeyMemLen);
		if (rc < 0) {
			matrixStrDebugMsg("Error reading private key file: %s\n",
				(char*)privFile);
			matrixRsaFreeKeys(lkeys);
			return rc;
		}
		rc = matrixRsaParsePrivKey(pool, privKeyMem, privKeyMemLen,
			&lkeys->cert.privKey);
		if (rc < 0) {
			matrixStrDebugMsg("Error parsing private key file: %s\n",
				(char*)privFile);
			psFree(privKeyMem);
			matrixRsaFreeKeys(lkeys);
			return rc;
		}
		psFree(privKeyMem);
	}

#ifdef USE_CLIENT_SIDE_SSL
/*
	Now deal with Certificate Authorities
*/
	if (trustedCAFiles != NULL) {
		if (matrixX509ReadCert(pool, trustedCAFiles, &caCert, &caCertLen,
				&chain) < 0 || caCert == NULL) {
			matrixStrDebugMsg("Error reading CA cert files %s\n",
				(char*)trustedCAFiles);
			matrixRsaFreeKeys(lkeys);
			return -1;
		}

		caStream = caCert;
		i = first = 0;
		while (chain[i] != 0) {
/*
			Don't allow one bad cert to ruin the whole bunch if possible
*/
			if (matrixX509ParseCert(pool, caStream, chain[i], &currCert) < 0) {
				matrixX509FreeCert(currCert);
				matrixStrDebugMsg("Error parsing CA cert %s\n",
					(char*)trustedCAFiles);
				caStream += chain[i]; caCertLen -= chain[i];
				i++;
				continue;
			}
		
			if (first == 0) {
				lkeys->caCerts = currCert;
			} else {
				prevCert->next = currCert;
			}
			first++;
			prevCert = currCert;
			currCert = NULL;
			caStream += chain[i]; caCertLen -= chain[i];
			i++;
		}
		sslAssert(caCertLen == 0);
		psFree(caCert);
	}
/*
	Check to see that if a set of CAs were passed in at least
	one ended up being valid.
*/
	if (trustedCAFiles != NULL && lkeys->caCerts == NULL) {
		matrixStrDebugMsg("No valid CA certs in %s\n",
			(char*)trustedCAFiles);
		matrixRsaFreeKeys(lkeys);
		return -1;
	}
#endif /* USE_CLIENT_SIDE_SSL */
	return 0; 
}