int pemEncode(
	const unsigned char 	*inData,
	unsigned 				inDataLen,
	unsigned char 			**outData,
	unsigned 				*outDataLen,
	const char 				*headerString)
{
	unsigned char *enc;
	unsigned encLen;
	
	/* First base64 encode */
	enc = cuEnc64WithLines(inData, inDataLen, 64, &encLen);
	if(enc == NULL) {
		/* malloc error is actually the only known failure */
		printf("***pemEncode: Error encoding file. Aborting.\n");
		return -1;
	}
		
	/* estimate outsize - just be sloppy, way conservative */
	size_t outSize = encLen + (2 * strlen(headerString)) + 200;
	*outData = (unsigned char *)malloc(outSize);
	sprintf((char *)*outData, "-----BEGIN %s-----\n%s-----END %s-----\n",
		headerString, (char *)enc, headerString);
	*outDataLen = (unsigned int)strlen((char *)*outData);

	if((*outData)[*outDataLen - 1] == '\0') {
		(*outDataLen)--;
	}
	free(enc);
	return 0;
}
/*
 * PEM encode a single SecExportRep's data, appending to a CFData.
 */
OSStatus impExpPemEncodeExportRep(
	CFDataRef			derData,
	const char			*pemHeader,
	CFArrayRef			pemParamLines,  // optional 
	CFMutableDataRef	outData)
{
	unsigned char *enc;
	unsigned encLen;
	
	char headerLine[200];
	if(strlen(pemHeader) > 150) {
		return errSecParam;
	}

	/* First base64 encode */
	enc = cuEnc64WithLines(CFDataGetBytePtr(derData), (unsigned)CFDataGetLength(derData),
		64, &encLen);
	if(enc == NULL) {
		/* malloc error is actually the only known failure */
		SecImpExpDbg("impExpPemEncodeExportRep: cuEnc64WithLines failure");
		return errSecAllocate;
	}
	
	/* strip off trailing NULL */
	if((encLen != 0) && (enc[encLen - 1] == '\0')) {
		encLen--;
	}
	sprintf(headerLine, "-----BEGIN %s-----\n", pemHeader);
	CFDataAppendBytes(outData, (const UInt8 *)headerLine, strlen(headerLine));
	
	/* optional PEM parameters lines (currently used for openssl wrap format only) */
	if(pemParamLines != NULL) {
		CFIndex numLines = CFArrayGetCount(pemParamLines);
		for(CFIndex dex=0; dex<numLines; dex++) {
			CFStringRef cfStr = 
				(CFStringRef)CFArrayGetValueAtIndex(pemParamLines, dex);
			char cStr[512];
			UInt8 nl = '\n';
			if(!CFStringGetCString(cfStr, cStr, sizeof(cStr), 
					kCFStringEncodingASCII)) {
				/* 
				 * Should never happen; this module created this CFString
				 * from a C string with ASCII encoding. Keep going, though
				 * this is probably fatal to the exported representation.
				 */
				SecImpExpDbg("impExpPemEncodeExportRep: pemParamLine screwup");
				continue; 
			}
			CFDataAppendBytes(outData, (const UInt8 *)cStr, strlen(cStr));
			CFDataAppendBytes(outData, &nl, 1);
		}
	}
	CFDataAppendBytes(outData, enc, encLen);
	sprintf(headerLine, "-----END %s-----\n", pemHeader);
	CFDataAppendBytes(outData, (const UInt8 *)headerLine, strlen(headerLine));
	free((void *)enc);
	return errSecSuccess;
}