Example #1
0
static int readDsaPrivateKeyOld( INOUT STREAM *stream, 
								 INOUT CONTEXT_INFO *contextInfoPtr )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;
	int dummy, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA );

	/* Skip the PKCS #8 wrapper */
	readSequence( stream, NULL );		/* Outer wrapper */
	readShortInteger( stream, NULL );	/* Version */
	status = readAlgoIDparam( stream, &cryptAlgo, &dummy, 
							  ALGOID_CLASS_PKC );
	if( cryptStatusError( status ) || cryptAlgo != CRYPT_ALGO_DSA )
		return( CRYPT_ERROR_BADDATA );

	/* Read the DSA parameters if we haven't already got them via the
	   associated public key/certificate */
	if( BN_is_zero( &dlpKey->dlpParam_p ) )
		{
		readSequence( stream, NULL );	/* Parameter wrapper */
		status = readBignumChecked( stream, &dlpKey->dlpParam_p,
									DLPPARAM_MIN_P, DLPPARAM_MAX_P, 
									NULL );
		if( cryptStatusOK( status ) )
			status = readBignumChecked( stream, &dlpKey->dlpParam_q,
										DLPPARAM_MIN_Q, DLPPARAM_MAX_Q, 
										NULL );
		if( cryptStatusOK( status ) )
			status = readBignumChecked( stream, &dlpKey->dlpParam_g,
										DLPPARAM_MIN_G, DLPPARAM_MAX_G, 
										NULL );
		}
	else
		status = readUniversal( stream );
	if( cryptStatusError( status ) )
		return( status );

	/* Read the DSA private key component */
	status = readOctetStringHole( stream, NULL, 20, DEFAULT_TAG );
	if( cryptStatusOK( status ) )	/* OCTET STRING encapsulation */
		status = readBignum( stream, &dlpKey->dlpParam_x,
							 DLPPARAM_MIN_X, DLPPARAM_MAX_X,
							 &dlpKey->dlpParam_p );
	return( status );
	}
Example #2
0
void VcfMaterializer::_loadLevels(int rID)
{
    currentLevels.clear();

    std::stringstream ssTop, ssBottom;
    ssTop << sequenceName(faiIndex, rID) << "/TOP";
    unsigned idx = 0;
    if (!getIdByName(idx, methFaiIndex, ssTop.str().c_str()))
        throw MasonIOException("Could not find top levels in methylation FASTA.");
    readSequence(currentLevels.forward, methFaiIndex, idx);
    ssBottom << sequenceName(faiIndex, rID) << "/BOT";
    if (!getIdByName(idx, methFaiIndex, ssBottom.str().c_str()))
        throw MasonIOException("Could not find bottom levels in methylation FASTA.");
    readSequence(currentLevels.reverse, methFaiIndex, idx);
}
Example #3
0
std::vector<Repeat> getTopNRepeats(const std::string & sequenceFile, size_t N) {
    std::string sequence = readSequence(sequenceFile);
    suffix::SuffixArray arr(sequence);
    std::vector<Repeat> result(N);
    std::map<int, Repeat, std::greater<int> > LCPRepeats;
    std::map<int, Repeat, std::greater<int> >::iterator it1;
    for (size_t i = 0; i < arr.size(); ++i) {
        saidx_t value = arr.getLCPArray()[i];
        it1 = LCPRepeats.find(value);
        if (it1 == LCPRepeats.end()) {
            Repeat rep;
            rep.length = value;
            rep.positions.push_back(arr.getSuffixArray()[i]);
            LCPRepeats.insert(std::make_pair(value, rep));
        } else {
            it1->second.positions.push_back(arr.getSuffixArray()[i]);
        }
    }
    it1 = LCPRepeats.begin();
    for (size_t i = 0; i < N && it1 != LCPRepeats.end(); ++i, ++it1) {
        result[i] = it1->second;
        extendRepeat(result[i], arr);
    }
    return result;
}
Example #4
0
static int readDlpPrivateKey( INOUT STREAM *stream, 
							  INOUT CONTEXT_INFO *contextInfoPtr )
	{
	PKC_INFO *dlpKey = contextInfoPtr->ctxPKC;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
			  ( contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DH || \
				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_DSA || \
				contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ELGAMAL ) );

	/* Read the key components */
	if( peekTag( stream ) == BER_SEQUENCE )
		{
		/* Erroneously written in older code */
		readSequence( stream, NULL );
		return( readBignumTag( stream, &dlpKey->dlpParam_x,
							   DLPPARAM_MIN_X, DLPPARAM_MAX_X, 
							   &dlpKey->dlpParam_p, 0 ) );
		}
	return( readBignum( stream, &dlpKey->dlpParam_x,
						DLPPARAM_MIN_X, DLPPARAM_MAX_X,
						&dlpKey->dlpParam_p ) );
	}
Example #5
0
static int readProtAlgoInfo( INOUT STREAM *stream, 
							 OUT_ALGO_Z CRYPT_ALGO_TYPE *cryptAlgo,
							 OUT_INT_SHORT_Z int *keySize )
	{
	const OID_INFO *oidInfoPtr;
	const PKCS12_ALGO_MAP *algoMapInfoPtr;
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( cryptAlgo, sizeof( CRYPT_ALGO_TYPE ) ) );
	assert( isWritePtr( keySize, sizeof( int ) ) );

	/* Clear return values */
	*cryptAlgo = CRYPT_ALGO_NONE;
	*keySize = 0;

	/* Read the wrapper and the protection algorithm OID and extract the
	   protection information parameters for it */
	readSequence( stream, NULL );
	status = readOIDEx( stream, encryptionOIDinfo, 
						FAILSAFE_ARRAYSIZE( encryptionOIDinfo, OID_INFO ), 
						&oidInfoPtr );
	if( cryptStatusError( status ) )
		return( status );
	algoMapInfoPtr = oidInfoPtr->extraInfo;
	*cryptAlgo = algoMapInfoPtr->cryptAlgo;
	*keySize = algoMapInfoPtr->keySize;

	return( CRYPT_OK );
	}
Example #6
0
static int readGeneralInfo( INOUT STREAM *stream, 
							INOUT CMP_PROTOCOL_INFO *protocolInfo )
	{
	long endPos;
	int length, iterationCount, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( protocolInfo, sizeof( CMP_PROTOCOL_INFO ) ) );

	/* Go through the various attributes looking for anything that we can
	   use */
	readConstructed( stream, NULL, CTAG_PH_GENERALINFO );
	status = readSequence( stream, &length );
	if( cryptStatusError( status ) )
		return( status );
	endPos = stell( stream ) + length;
	for( iterationCount = 0; 
		 stell( stream ) < endPos && \
			iterationCount < FAILSAFE_ITERATIONS_MED; iterationCount++ )
		{
		status = readGeneralInfoAttribute( stream, protocolInfo );
		if( cryptStatusError( status ) )
			return( status );
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );

	return( status );
	}
Example #7
0
void takePrefix(const std::string & sequenceFile, const std::string & outputSeqFile, size_t prefixLength) {
    std::string seq = readSequence(sequenceFile);
    assert(seq.length() >= prefixLength);
    std::string prefixSeq = seq.substr(0, prefixLength);
    std::ofstream out(outputSeqFile.c_str());
    out << ">BK0000000 TPA_inf: Prefix Sequence, " << prefixLength << "bp, complete sequence"  << std::endl;
    out << prefixSeq << std::endl;
    out.close();
}
Example #8
0
//function definitions
// Takes 2 fasta files and scoring matrix. Prints optimal alignment score and local alignment.
int localAlignment(FILE *fasta1, FILE *fasta2, int score[3]) {
    int numSeqs1;
    int numSeqs2;
    sequence_t *seq1 = readSequence(fasta1, &numSeqs1);
    sequence_t *seq2 = readSequence(fasta2, &numSeqs2);
    int dp_rows = seq1->sequence_length+1; //length of sequence + null character + 1. Need extra space for base case.
    int dp_cols = seq2->sequence_length+1;
    direction **bt = allocateMemDirection(dp_rows, dp_cols); //backtrace table
    int **distance = allocateMemInt(dp_rows, dp_cols); //table of scores
    fillMatrixLocal(dp_rows, dp_cols, distance, bt, seq1->sequence, seq2->sequence, score);
    //printMatrix(dp_rows, dp_cols, distance, bt); //print DP table for debugging
    //print out the highest score in the table.
    int highest_score_coordinates[2] = {0, 0};
    int maxScore = max_score_in_dp(dp_rows, dp_cols, distance, highest_score_coordinates);
    printScore(maxScore, -2);
    //void backtrace(int srow, int scol, sequence_t *seq1, sequence_t *seq2, int dp_cols, direction bt[][dp_cols])
    backtraceAlignment(highest_score_coordinates[0], highest_score_coordinates[1], seq1, seq2, bt, -2);
    return 0;
}
Example #9
0
void eskoTest() {
    unsigned step = 5000;
    unsigned start = 30000;
    unsigned stop = 120000;
    unsigned topL = 300;
    unsigned minL = 5;

    for(unsigned cur = start; cur <= stop; cur += step) {
        takeSubstring("data/ecoli.seq", "data/tmpseq.seq", 0, cur);
        //takeSubstring("data/ecoli.seq", "data/tmpseq.seq", 278000, 293000);

        unsigned L = minL;
        unsigned R = topL;
        unsigned ans = 0U;

        while (L<=R) {
            unsigned mid = (L+R) / 2U;
            unsigned k = mid-1U;
            Genome genome;
            readGenome("data/tmpseq.seq", mid, genome);

            AhoCorasick * aho = new AhoCorasick(genome);

            aho->filterOverlaps(k);

            NFA_Automata nfa(*aho, genome, 0, genome.generatedReads.size()-1);

            delete aho;

            DFA_Automata dfa(nfa, genome, 1.0);
            // remove reads since we do not need them anymore
            genome.generatedReads.resize(0);
            genome.sequence.resize(0);

            bool uniqueOk = dfa.isCOAUnique();

            if (uniqueOk) {
                R = mid-1U;
                ans = mid;
            } else {
                L = mid+1U;
            }

        }

        std::string seq = readSequence("data/tmpseq.seq");

        std::cout << cur << " " << ans << " " << getLongestSingleRepeat(seq) << std::endl;



    }

}
Example #10
0
static int readAVA( INOUT STREAM *stream, 
					OUT_INT_Z int *type, 
					OUT_LENGTH_SHORT_Z int *length, 
					OUT_TAG_ENCODED_Z int *stringTag )
	{
	const DN_COMPONENT_INFO *dnComponentInfo;
	BYTE oid[ MAX_OID_SIZE + 8 ];
	int oidLength, tag, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( type, sizeof( int ) ) );
	assert( isWritePtr( length, sizeof( int ) ) );
	assert( isWritePtr( stringTag, sizeof( int ) ) );

	/* Clear return values */
	*type = 0;
	*length = 0;
	*stringTag = 0;

	/* Read the start of the AVA and determine the type from the 
	   AttributeType field.  If we find something that we don't recognise we 
	   indicate it as a non-component type that can be read or written but 
	   not directly accessed by the user (although it can still be accessed 
	   using the cursor functions) */
	readSequence( stream, NULL );
	status = readEncodedOID( stream, oid, MAX_OID_SIZE, &oidLength, 
							 BER_OBJECT_IDENTIFIER );
	if( cryptStatusError( status ) )
		return( status );
	dnComponentInfo = findDNInfoByOID( oid, oidLength );
	if( dnComponentInfo == NULL )
		{
		/* If we don't recognise the component type at all, skip it */
		status = readUniversal( stream );
		return( cryptStatusError( status ) ? status : OK_SPECIAL );
		}
	*type = dnComponentInfo->type;

	/* We've reached the data value, make sure that it's in order.  When we
	   read the wrapper around the string type with readGenericHole() we have 
	   to allow a minimum length of zero instead of one because of broken 
	   AVAs with zero-length strings */
	tag = peekTag( stream );
	if( cryptStatusError( tag ) )
		return( tag );
	if( tag == BER_BITSTRING )
		return( readAVABitstring( stream, length, stringTag ) );
	*stringTag = tag;
	return( readGenericHole( stream, length, 0, tag ) );
	}
Example #11
0
Repeat getLongestRepeat(const std::string & sequenceFile) {
    std::string sequence = readSequence(sequenceFile);
    suffix::SuffixArray arr(sequence);
    size_t value = *std::max_element(arr.getLCPArray(), arr.getLCPArray() + arr.size());
    Repeat rep;
    rep.length = value;
    for (size_t i = 0; i < arr.size(); ++i) {
        if (value == arr.getLCPArray()[i]) {
            rep.positions.push_back(arr.getSuffixArray()[i]);
        }
    }
    extendRepeat(rep, arr);
    return rep;
}
Example #12
0
void readGenome(const std::string & sequenceFile, size_t readLength, Genome & genomeContainer) {
    genomeContainer.sequence = "#" + readSequence(sequenceFile) + "$";
    assert(readLength <= genomeContainer.sequence.size());
    size_t till = genomeContainer.sequence.length() - readLength;
    genomeContainer.generatedReads.resize(till+1);
    for (size_t i = 0; i <= till; ++i) {
        genomeContainer.generatedReads[i] = Genome::Read_t(i, i+readLength);
    }
    if (genomeContainer.generatedReads.size() >= 3) {
        std::random_shuffle(
            genomeContainer.generatedReads.begin()+1,
            genomeContainer.generatedReads.end()-1
        );
    }
}
Example #13
0
void takeSubstring(const std::string & sequenceFile, const std::string & outputSeqFile, int from, int to) {
    std::string seq = readSequence(sequenceFile);
    if (to == -1) {
        to = seq.length();
    }
    if (from == -1) {
        from = 0;
    }
    assert(to <= seq.length());
    std::string prefixSeq = seq.substr(from, (to-from+1));
    std::ofstream out(outputSeqFile.c_str());
    out << ">BK0000000 TPA_inf: Prefix Sequence, " << (to-from+1) << "bp, complete sequence"  << std::endl;
    out << prefixSeq << std::endl;
    out.close();
}
Example #14
0
File: cpg.c Project: sktu/kentUtils
/*------------------------------------------------------*/
void main (int argc, char **argv)
{ 
  
  char *seq, *seqname, *desc ;
  int conv[] =   { 0, 1, 2, 3, 4 } ;
  
  int length ;
  int i ;
  static FILE *fil ;

  char c, *cp ;
  extern char* malloc() ;

  /*------------------------------------------------------*/  
  switch ( argc )
    {
    default: if (argc != 2)
      usage () ;
    }
     if (!(seqname = malloc (MAXNAMELEN+1)))
     { fprintf (stderr, "Couldn't malloc %d bytes", MAXNAMELEN) ;
     exit (-1) ;
     }
     
     if (!(seq = malloc (MALLOCBLOCK+1)))
       { fprintf (stderr, "Couldn't malloc %d bytes", MALLOCBLOCK) ;
	 exit (-1) ;
       }

  if (!(fil = fopen ( argv[1], "r" ))) 
    usage ();
  
  while ( readSequence(fil, dna2textConv, &seq, &seqname, &desc, &length) ) 
    /* once through per sequence */
    { 
      i = 0 ;
      while ( seqname[i] != ' ' && seqname[i] != '\0' && i < 256 )
	++i ;
      seqname[i] = '\0' ;

      findspans ( 0, length, seq, seqname ) ;
    }

  exit (0);
}
Example #15
0
int readDN( INOUT STREAM *stream, 
			OUT_OPT_PTR DN_PTR **dnComponentListPtrPtr )
	{
	DN_COMPONENT *dnComponentListPtr = NULL;
	int length, iterationCount, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( dnComponentListPtrPtr, sizeof( DN_COMPONENT * ) ) );

	/* Clear return value */
	*dnComponentListPtrPtr = NULL;

	/* Read the encoded DN into the local copy of the DN (in other words 
	   into the dnComponentListPtr, not the externally-visible
	   dnComponentListPtrPtr) */
	status = readSequence( stream, &length );
	if( cryptStatusError( status ) )
		return( status );
	for( iterationCount = 0;
		 length > 0 && iterationCount < FAILSAFE_ITERATIONS_MED;
		 iterationCount++ )
		{
		const int startPos = stell( stream );

		REQUIRES( startPos > 0 && startPos < MAX_INTLENGTH_SHORT );

		status = readDNComponent( stream, &dnComponentListPtr );
		if( cryptStatusError( status ) )
			break;
		length -= stell( stream ) - startPos;
		}
	if( cryptStatusError( status ) || \
		length < 0 || iterationCount >= FAILSAFE_ITERATIONS_MED )
		{
		/* Delete the local copy of the DN read so far if necessary */
		if( dnComponentListPtr != NULL )
			deleteDN( ( DN_PTR ** ) &dnComponentListPtr );
		return( cryptStatusError( status ) ? status : CRYPT_ERROR_BADDATA );
		}

	/* Copy the local copy of the DN back to the caller */
	*dnComponentListPtrPtr = dnComponentListPtr;
	return( CRYPT_OK );
	}
Example #16
0
TranscriptSequence::TranscriptSequence(string fileName, refFormatT format){//{{{
   TranscriptSequence();
   readSequence(fileName,format);
}//}}}
Example #17
0
CHECK_RETVAL_SPECIAL STDC_NONNULL_ARG( ( 1, 2 ) ) \
static int readClassAttributes( INOUT STREAM *stream, 
								INOUT PKCS15_INFO *pkcs15infoPtr,
								IN_ENUM( PKCS15_OBJECT ) \
									const PKCS15_OBJECT_TYPE type )
	{
	BOOLEAN isCryptlibObject = FALSE;
	int tag, length, endPos, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) );

	REQUIRES( type > PKCS15_OBJECT_NONE && type < PKCS15_OBJECT_LAST );

	/* Read the attribute wrapper */
	status = readSequence( stream, &length );
	if( cryptStatusError( status ) )
		return( status );
	endPos = stell( stream ) + length;

	/* Process per-object-type attributes */
	switch( type )
		{
		case PKCS15_OBJECT_PUBKEY:
		case PKCS15_OBJECT_PRIVKEY:
			/* It's a public/private-key object, read the ID and assorted 
			   flags */
			if( length < sizeofObject( MIN_NAME_LENGTH ) )
				return( CRYPT_ERROR_BADDATA );
			status = readOctetString( stream, pkcs15infoPtr->iD,
									  &pkcs15infoPtr->iDlength, 
Example #18
0
static int readEccPrivateKeyOld( INOUT STREAM *stream, 
								 INOUT CONTEXT_INFO *contextInfoPtr )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	PKC_INFO *eccKey = contextInfoPtr->ctxPKC;
	long value;
	int tag, length, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_ECDSA );

	/* Read the ECC key components.  These were never standardised in any 
	   PKCS standard, nor in the PKCS #12 RFC.  RFC 5915 "Elliptic Curve 
	   Private Key Structure" specifies the format for PKCS #8 as:

		ECPrivateKey ::= SEQUENCE {
			version			INTEGER (1),
			privateKey		OCTET STRING,
			parameters	[0]	ECParameters {{ NamedCurve }} OPTIONAL,
			publicKey	[1]	BIT STRING OPTIONAL
			}

	   but this isn't what's present in encoded forms created by OpenSSL.
	   Instead it's:

		ECSomething ::= SEQUENCE {
			version			INTEGER (0),
			parameters		SEQUENCE {
				type		OBJECT IDENTIFIER ecPublicKey,
				namedCurve	OBJECT IDENTIFIER
				}
			something		OCTET STRING {
				key			ECPrivateKey		-- As above
				}
			}

	   so we have to tunnel into this in order to find the PKCS #8-like
	   data that we're actually interested in.

	   Note that we can't use the ECC p value for a range check because it 
	   hasn't been set yet, all that we have at this point is a curve ID */
	readSequence( stream, NULL );		/* Outer wrapper */
	status = readShortInteger( stream, &value );/* Version */
	if( cryptStatusError( status ) || value != 0 )
		return( CRYPT_ERROR_BADDATA );
	status = readAlgoIDparam( stream, &cryptAlgo, &length, 
							  ALGOID_CLASS_PKC );
	if( cryptStatusError( status ) || cryptAlgo != CRYPT_ALGO_ECDSA )
		return( CRYPT_ERROR_BADDATA );
	readUniversal( stream );			/* Named curve */
	readOctetStringHole( stream, NULL, MIN_PKCSIZE_ECC_THRESHOLD, 
						 DEFAULT_TAG );		/* OCTET STRING hole wrapper */
	readSequence( stream, NULL );				/* ECPrivateKey wrapper */
	status = readShortInteger( stream, &value );	/* Version */
	if( cryptStatusError( status ) || value != 1 )
		return( CRYPT_ERROR_BADDATA );

	/* We've finalled made it down to the private key value.  At this point 
	   we can't use readBignumTag() directly because it's designed to read 
	   either standard INTEGERs (via DEFAULT_TAG) or context-specific tagged 
	   items, so passing in a BER_OCTETSTRING will be interpreted as 
	   [4] IMPLICIT INTEGER rather than an OCTET STRING-tagged integer.  To 
	   get around this we read the tag separately and tell readBignumTag() 
	   to skip the tag read */
	tag = readTag( stream );
	if( cryptStatusError( tag ) || tag != BER_OCTETSTRING )
		return( CRYPT_ERROR_BADDATA );
	return( readBignumTag( stream, &eccKey->eccParam_d,
						   ECCPARAM_MIN_D, ECCPARAM_MAX_D, NULL,
						   NO_TAG ) );
	}
Example #19
0
static int readPkiHeader( INOUT STREAM *stream, 
						  INOUT CMP_PROTOCOL_INFO *protocolInfo,
						  INOUT ERROR_INFO *errorInfo,
						  const BOOLEAN isServerInitialMessage )
	{
	int length, endPos, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( protocolInfo, sizeof( CMP_PROTOCOL_INFO ) ) );
	assert( isWritePtr( errorInfo, sizeof( ERROR_INFO ) ) );

	/* Clear per-message state information */
	protocolInfo->userIDchanged = protocolInfo->certIDchanged = \
		protocolInfo->useMACreceive = FALSE;
	protocolInfo->macInfoPos = CRYPT_ERROR;
	protocolInfo->senderDNPtr = NULL;
	protocolInfo->senderDNlength = 0;
	protocolInfo->headerRead = FALSE;

	/* Read the wrapper and skip the static information, which matches what 
	   we sent and is protected by the MAC so there's little point in 
	   looking at it */
	status = readSequence( stream, &length );
	if( cryptStatusError( status ) )
		return( status );
	endPos = stell( stream ) + length;
	readShortInteger( stream, NULL );		/* Version */
	if( !protocolInfo->isCryptlib )
		{
		/* The ID of the key used for integrity protection (or in general
		   the identity of the sender) can be specified either as the sender
		   DN or the senderKID or both, or in some cases even indirectly via
		   the transaction ID.  With no real guidance as to which one to 
		   use, implementors are using any of these options to identify the 
		   key.  Since we need to check that the integrity-protection key 
		   that we're using is correct so that we can report a more 
		   appropriate error than bad signature or bad data, we need to 
		   remember the sender DN for later in case this is the only form of 
		   key identification provided.  Unfortunately since the sender DN 
		   can't uniquely identify a certificate, if this is the only 
		   identifier that we're given then the caller can still get a bad 
		   signature error, yet another one of CMPs many wonderful features */
		status = readConstructed( stream, &protocolInfo->senderDNlength, 4 );
		if( cryptStatusOK( status ) && protocolInfo->senderDNlength > 0 )
			{
			status = sMemGetDataBlock( stream, &protocolInfo->senderDNPtr, 
									   protocolInfo->senderDNlength );
			if( cryptStatusOK( status ) )
				status = readUniversal( stream );
			}
		}
	else
		{
		/* cryptlib includes a proper certID so the whole signer
		   identification mess is avoided and we can ignore the sender DN */
		status = readUniversal( stream );	/* Sender DN */
		}
	if( cryptStatusOK( status ) )
		status = readUniversal( stream );	/* Recipient DN */
	if( peekTag( stream ) == MAKE_CTAG( CTAG_PH_MESSAGETIME ) )
		status = readUniversal( stream );	/* Message time */
	if( cryptStatusError( status ) )
		{
		retExt( CRYPT_ERROR_BADDATA, 
				( CRYPT_ERROR_BADDATA, errorInfo, 
				  "Invalid DN information in PKI header" ) );
		}
	if( peekTag( stream ) != MAKE_CTAG( CTAG_PH_PROTECTIONALGO ) )
		{
		/* The message was sent without integrity protection, report it as
		   a signature error rather than the generic bad data error that
		   we'd get from the following read */
		retExt( CRYPT_ERROR_SIGNATURE,
				( CRYPT_ERROR_SIGNATURE, errorInfo, 
				  "Message was sent without integrity protection" ) );
		}
	status = readProtectionAlgo( stream, protocolInfo );
	if( cryptStatusError( status ) )
		{
		retExt( status,
				( status, errorInfo, 
				  "Invalid integrity protection information in PKI "
				  "header" ) );
		}
	if( peekTag( stream ) == MAKE_CTAG( CTAG_PH_SENDERKID ) )
		{								/* Sender protection keyID */
		status = readUserID( stream, protocolInfo );
		if( cryptStatusError( status ) )
			{
			retExt( status,
					( status, errorInfo, 
					  "Invalid PKI user ID in PKI header" ) );
			}
		}
	else
		{
		/* If we're the server, the client must provide a PKI user ID in the
		   first message unless we got one in an earlier transaction */
		if( isServerInitialMessage && protocolInfo->userIDsize <= 0 )
			{
			retExt( CRYPT_ERROR_BADDATA, 
					( CRYPT_ERROR_BADDATA, errorInfo, 
					  "Missing PKI user ID in PKI header" ) );
			}
		}
	if( peekTag( stream ) == MAKE_CTAG( CTAG_PH_RECIPKID ) )
		readUniversal( stream );			/* Recipient protection keyID */

	/* Record the transaction ID (which is effectively the nonce) or make 
	   sure that it matches the one that we sent.  There's no real need to 
	   do an explicit duplicate check since a replay attempt will be 
	   rejected as a duplicate by the certificate store and the locking 
	   performed at that level makes it a much better place to catch 
	   duplicates, but we do it anyway because it doesn't cost anything and
	   we can catch at least some problems a bit earlier */
	status = readConstructed( stream, NULL, CTAG_PH_TRANSACTIONID );
	if( cryptStatusError( status ) )
		{
		retExt( status, 
				( status, errorInfo, 
				  "Missing transaction ID in PKI header" ) );
		}
	status = readTransactionID( stream, protocolInfo, 
								isServerInitialMessage );
	if( cryptStatusError( status ) )
		{
		protocolInfo->pkiFailInfo = CMPFAILINFO_BADRECIPIENTNONCE;
		retExt( status, 
				( status, errorInfo, 
				  ( status == CRYPT_ERROR_SIGNATURE ) ? \
				  "Returned message transaction ID doesn't match our "
						"transaction ID" : \
				  "Invalid transaction ID in PKI header" ) );
		}

	/* Read the sender nonce, which becomes the new recipient nonce, and skip
	   the recipient nonce if there's one present.  These values may be
	   absent, either because the other side doesn't implement them or
	   because they're not available, for example because it's sending a
	   response to an error that occurred before it could read the nonce from
	   a request.  In any case we don't bother checking the nonce values
	   since the transaction ID serves the same purpose */
	if( stell( stream ) < endPos && \
		peekTag( stream ) == MAKE_CTAG( CTAG_PH_SENDERNONCE ) )
		{
		readConstructed( stream, NULL, CTAG_PH_SENDERNONCE );
		status = readOctetString( stream, protocolInfo->recipNonce,
								  &protocolInfo->recipNonceSize,
								  4, CRYPT_MAX_HASHSIZE );
		if( cryptStatusError( status ) )
			{
			protocolInfo->pkiFailInfo = CMPFAILINFO_BADSENDERNONCE;
			retExt( status,
					( status, errorInfo, 
					  "Invalid sender nonce in PKI header" ) );
			}
		}
	if( stell( stream ) < endPos && \
		peekTag( stream ) == MAKE_CTAG( CTAG_PH_RECIPNONCE ) )
		{
		readConstructed( stream, NULL, CTAG_PH_RECIPNONCE );
		status = readUniversal( stream );
		if( cryptStatusError( status ) )
			{
			protocolInfo->pkiFailInfo = CMPFAILINFO_BADRECIPIENTNONCE;
			retExt( status,
					( status, errorInfo, 
					  "Invalid recipient nonce in PKI header" ) );
			}
		}

	/* Remember that we've successfully read enough of the header 
	   information to generate a response */
	protocolInfo->headerRead = TRUE;

	/* Skip any further junk and process the general information if there is 
	   any */
	if( stell( stream ) < endPos && \
		peekTag( stream ) == MAKE_CTAG( CTAG_PH_FREETEXT ) )
		{
		status = readUniversal( stream );	/* Junk */
		if( cryptStatusError( status ) )
			return( status );
		}
	if( stell( stream ) < endPos && \
		peekTag( stream ) == MAKE_CTAG( CTAG_PH_GENERALINFO ) )
		{
		status = readGeneralInfo( stream, protocolInfo );
		if( cryptStatusError( status ) )
			{
			retExt( status,
					( status, errorInfo, 
					  "Invalid generalInfo information in PKI header" ) );
			}
		}

	return( CRYPT_OK );
	}
Example #20
0
static int readKeyDerivationInfo( INOUT STREAM *stream, 
								  OUT QUERY_INFO *queryInfo )
	{
	long endPos, value;
	int length, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( queryInfo, sizeof( QUERY_INFO ) ) );

	/* Clear return value */
	memset( queryInfo, 0, sizeof( QUERY_INFO ) );

	/* Read the outer wrapper and key derivation algorithm OID */
	readConstructed( stream, NULL, CTAG_KK_DA );
	status = readFixedOID( stream, OID_PBKDF2, sizeofOID( OID_PBKDF2 ) );
	if( cryptStatusError( status ) )
		return( status );

	/* Read the PBKDF2 parameters, limiting the salt and iteration count to
	   sane values */
	status = readSequence( stream, &length );
	if( cryptStatusError( status ) )
		return( status );
	endPos = stell( stream ) + length;
	readOctetString( stream, queryInfo->salt, &queryInfo->saltLength, 
					 2, CRYPT_MAX_HASHSIZE );
	status = readShortInteger( stream, &value );
	if( cryptStatusError( status ) )
		return( status );
	if( value < 1 || value > MAX_KEYSETUP_ITERATIONS )
		return( CRYPT_ERROR_BADDATA );
	queryInfo->keySetupIterations = ( int ) value;
	queryInfo->keySetupAlgo = CRYPT_ALGO_HMAC_SHA1;
	if( stell( stream ) < endPos && \
		sPeek( stream ) == BER_INTEGER )
		{
		/* There's an optional key length that may override the default 
		   key size present, read it.  Note that we compare the upper
		   bound to MAX_WORKING_KEYSIZE rather than CRYPT_MAX_KEYSIZE,
		   since this is a key used directly with an encryption algorithm
		   rather than a generic keying value that may be hashed down to 
		   size */
		status = readShortInteger( stream, &value );
		if( cryptStatusError( status ) )
			return( status );
		if( value < MIN_KEYSIZE || value > MAX_WORKING_KEYSIZE )
			return( CRYPT_ERROR_BADDATA );
		queryInfo->keySize = ( int ) value;
		}
	if( stell( stream ) < endPos )
		{
		CRYPT_ALGO_TYPE prfAlgo;
	
		/* There's a non-default hash algorithm ID present, read it */
		status = readAlgoID( stream, &prfAlgo, ALGOID_CLASS_HASH );
		if( cryptStatusError( status ) )
			return( status );
		queryInfo->keySetupAlgo = prfAlgo;
		}

	return( CRYPT_OK );
	}
Example #21
0
static int readRsaPrivateKeyOld( INOUT STREAM *stream, 
								 INOUT CONTEXT_INFO *contextInfoPtr )
	{
	CRYPT_ALGO_TYPE cryptAlgo;
	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
	const int startPos = stell( stream );
	int length, endPos, iterationCount, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );

	/* Skip the PKCS #8 wrapper.  When we read the OCTET STRING 
	   encapsulation we use MIN_PKCSIZE_THRESHOLD rather than MIN_PKCSIZE
	   so that a too-short key will get to readBignumChecked(), which
	   returns an appropriate error code */
	readSequence( stream, &length );	/* Outer wrapper */
	readShortInteger( stream, NULL );	/* Version */
	status = readAlgoID( stream, &cryptAlgo, ALGOID_CLASS_PKC );
	if( cryptStatusError( status ) || cryptAlgo != CRYPT_ALGO_RSA )
		return( CRYPT_ERROR_BADDATA );
	status = readOctetStringHole( stream, NULL, 
								  ( 2 * MIN_PKCSIZE_THRESHOLD ) + \
									( 5 * ( MIN_PKCSIZE_THRESHOLD / 2 ) ), 
								  DEFAULT_TAG );
	if( cryptStatusError( status ) )	/* OCTET STRING encapsulation */
		return( status );

	/* Read the header */
	readSequence( stream, NULL );
	status = readShortInteger( stream, NULL );
	if( cryptStatusError( status ) )
		return( status );

	/* Read the RSA key components, skipping n and e if we've already got 
	   them via the associated public key/certificate */
	if( BN_is_zero( &rsaKey->rsaParam_n ) )
		{
		status = readBignumChecked( stream, &rsaKey->rsaParam_n,
									RSAPARAM_MIN_N, RSAPARAM_MAX_N, 
									NULL );
		if( cryptStatusOK( status ) )
			status = readBignum( stream, &rsaKey->rsaParam_e,
								 RSAPARAM_MIN_E, RSAPARAM_MAX_E,
								 &rsaKey->rsaParam_n );
		}
	else
		{
		readUniversal( stream );
		status = readUniversal( stream );
		}
	if( cryptStatusOK( status ) )
		{
		/* d isn't used so we skip it */
		status = readUniversal( stream );
		}
	if( cryptStatusOK( status ) )
		status = readBignum( stream, &rsaKey->rsaParam_p,
							 RSAPARAM_MIN_P, RSAPARAM_MAX_P,
							 &rsaKey->rsaParam_n );
	if( cryptStatusOK( status ) )
		status = readBignum( stream, &rsaKey->rsaParam_q,
							 RSAPARAM_MIN_Q, RSAPARAM_MAX_Q,
							 &rsaKey->rsaParam_n );
	if( cryptStatusOK( status ) )
		status = readBignum( stream, &rsaKey->rsaParam_exponent1,
							 RSAPARAM_MIN_EXP1, RSAPARAM_MAX_EXP1,
							 &rsaKey->rsaParam_n );
	if( cryptStatusOK( status ) )
		status = readBignum( stream, &rsaKey->rsaParam_exponent2,
							 RSAPARAM_MIN_EXP2, RSAPARAM_MAX_EXP2,
							 &rsaKey->rsaParam_n );
	if( cryptStatusOK( status ) )
		status = readBignum( stream, &rsaKey->rsaParam_u,
							 RSAPARAM_MIN_U, RSAPARAM_MAX_U,
							 &rsaKey->rsaParam_n );
	if( cryptStatusError( status ) )
		return( status );

	/* Check whether there are any attributes present */
	if( stell( stream ) >= startPos + length )
		return( CRYPT_OK );

	/* Read the attribute wrapper */
	status = readConstructed( stream, &length, 0 );
	if( cryptStatusError( status ) )
		return( status );
	endPos = stell( stream ) + length;

	/* Read the collection of attributes.  Unlike any other key-storage 
	   format, PKCS #8 stores the key usage information as an X.509 
	   attribute alongside the encrypted private key data so we have to
	   process whatever attributes may be present in order to find the
	   keyUsage (if there is any) in order to set the object action 
	   permissions */
	for( iterationCount = 0;
		 stell( stream ) < endPos && \
			iterationCount < FAILSAFE_ITERATIONS_MED;
		 iterationCount++ )
		{
		BYTE oid[ MAX_OID_SIZE + 8 ];
		int oidLength, actionFlags, value;

		/* Read the attribute.  Since there's only one attribute type that 
		   we can use, we hardcode the read in here rather than performing a 
		   general-purpose attribute read */
		readSequence( stream, NULL );
		status = readEncodedOID( stream, oid, MAX_OID_SIZE, &oidLength, 
								 BER_OBJECT_IDENTIFIER );
		if( cryptStatusError( status ) )
			return( status );

		/* If it's not a key-usage attribute, we can't do much with it */
		if( oidLength != sizeofOID( OID_X509_KEYUSAGE ) || \
			memcmp( oid, OID_X509_KEYUSAGE, oidLength ) )
			{
			status = readUniversal( stream );
			if( cryptStatusError( status ) )
				return( status );
			continue;
			}

		/* Read the keyUsage attribute and convert it into cryptlib action 
		   permissions */
		readSet( stream, NULL );
		status = readBitString( stream, &value );
		if( cryptStatusError( status ) )
			return( status );
		actionFlags = ACTION_PERM_NONE;
		if( value & ( KEYUSAGE_SIGN | KEYUSAGE_CA ) )
			{
			actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_SIGN, \
										   ACTION_PERM_ALL ) | \
						   MK_ACTION_PERM( MESSAGE_CTX_SIGCHECK, \
										   ACTION_PERM_ALL );
			}
		if( value & KEYUSAGE_CRYPT )
			{
			actionFlags |= MK_ACTION_PERM( MESSAGE_CTX_ENCRYPT, \
										   ACTION_PERM_ALL ) | \
						   MK_ACTION_PERM( MESSAGE_CTX_DECRYPT, \
										   ACTION_PERM_ALL );
			}
#if 0	/* 11/6/13 Windows sets these flags to what are effectively
				   gibberish values (dataEncipherment for a signing key,
				   digitalSignature for an encryption key) so in order
				   to be able to use the key we have to ignore the keyUsage 
				   settings, in the same way that every other application 
				   seems to */
		if( actionFlags == ACTION_PERM_NONE )
			return( CRYPT_ERROR_NOTAVAIL );
		status = krnlSendMessage( contextInfoPtr->objectHandle, 
								  IMESSAGE_SETATTRIBUTE, &actionFlags, 
								  CRYPT_IATTRIBUTE_ACTIONPERMS );
		if( cryptStatusError( status ) )
			return( status );
#else
		assert( actionFlags != ACTION_PERM_NONE );	/* Warn in debug mode */
#endif /* 0 */
		}
	ENSURES( iterationCount < FAILSAFE_ITERATIONS_MED );

	return( CRYPT_OK );
	}
Example #22
0
static int readGeneralInfoAttribute( INOUT STREAM *stream, 
									 INOUT CMP_PROTOCOL_INFO *protocolInfo )
	{
	BYTE oid[ MAX_OID_SIZE + 8 ];
	int length, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( protocolInfo, sizeof( CMP_PROTOCOL_INFO ) ) );

	/* Read the attribute.  Since there are only two attribute types that we 
	   use, we hardcode the read in here rather than performing a general-
	   purpose attribute read */
	readSequence( stream, NULL );
	status = readEncodedOID( stream, oid, MAX_OID_SIZE, &length, 
							 BER_OBJECT_IDENTIFIER );
	if( cryptStatusError( status ) )
		return( status );

	/* Process the cryptlib presence-check value */
	if( length == sizeofOID( OID_CRYPTLIB_PRESENCECHECK ) && \
		!memcmp( oid, OID_CRYPTLIB_PRESENCECHECK, length ) )
		{
		/* The other side is running cryptlib, we can make some common-sense 
		   assumptions about its behaviour */
		protocolInfo->isCryptlib = TRUE;
		return( readUniversal( stream ) );			/* Attribute */
		}

	/* Check for the ESSCertID, which fixes CMP's broken certificate 
	   identification mechanism */
	if( length == sizeofOID( OID_ESS_CERTID ) && \
		!memcmp( oid, OID_ESS_CERTID, length ) )
		{
		BYTE certID[ CRYPT_MAX_HASHSIZE + 8 ];
		int certIDsize, endPos;

		/* Extract the certificate hash from the ESSCertID */
		readSet( stream, NULL );					/* Attribute */
		readSequence( stream, NULL );				/* SigningCerts */
		readSequence( stream, NULL );				/* Certs */
		status = readSequence( stream, &length );	/* ESSCertID */
		if( cryptStatusError( status ) )
			return( status );
		endPos = stell( stream ) + length;
		status = readOctetString( stream, certID, &certIDsize, 
								  KEYID_SIZE, KEYID_SIZE );
		if( cryptStatusError( status ) )
			return( status );
		if( protocolInfo->certIDsize != KEYID_SIZE || \
			memcmp( certID, protocolInfo->certID, KEYID_SIZE ) )
			{
			/* The certificate used for authentication purposes has changed,
			   remember the new certID */
			memcpy( protocolInfo->certID, certID, KEYID_SIZE );
			protocolInfo->certIDsize = KEYID_SIZE;
			protocolInfo->certIDchanged = TRUE;
			}
		if( stell( stream ) < endPos )
			{
			/* Skip the issuerSerial if there's one present.  We can't 
			   really do much with it in this form without rewriting it into 
			   the standard issuerAndSerialNumber, but in any case we don't 
			   need it because we've already got the certificate ID */
			status = readUniversal( stream );
			}
		return( status );
		}

	/* It's something that we don't recognise, skip it */
	return( readUniversal( stream ) );
	}
Example #23
0
static int readRsaPrivateKey( INOUT STREAM *stream, 
							  INOUT CONTEXT_INFO *contextInfoPtr )
	{
	PKC_INFO *rsaKey = contextInfoPtr->ctxPKC;
	int status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( contextInfoPtr, sizeof( CONTEXT_INFO ) ) );

	REQUIRES( contextInfoPtr->type == CONTEXT_PKC && \
			  contextInfoPtr->capabilityInfo->cryptAlgo == CRYPT_ALGO_RSA );

	/* Read the header */
	status = readSequence( stream, NULL );
	if( cryptStatusOK( status ) && \
		peekTag( stream ) == MAKE_CTAG( 0 ) )
		{
		/* Erroneously written in older code */
		status = readConstructed( stream, NULL, 0 );
		}
	if( cryptStatusError( status ) )
		return( status );

	/* Read the key components */
	if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 0 ) )
		{
		/* The public components may already have been read when we read a
		   corresponding public key or certificate so we only read them if
		   they're not already present */
		if( BN_is_zero( &rsaKey->rsaParam_n ) && \
			BN_is_zero( &rsaKey->rsaParam_e ) )
			{
			status = readBignumTag( stream, &rsaKey->rsaParam_n, 
									RSAPARAM_MIN_N, RSAPARAM_MAX_N, 
									NULL, 0 );
			if( cryptStatusOK( status ) )
				{
				status = readBignumTag( stream, &rsaKey->rsaParam_e, 
										RSAPARAM_MIN_E, RSAPARAM_MAX_E, 
										&rsaKey->rsaParam_n, 1 );
				}
			}
		else
			{
			/* The key components are already present, skip them */
			REQUIRES( !BN_is_zero( &rsaKey->rsaParam_n ) && \
					  !BN_is_zero( &rsaKey->rsaParam_e ) );
			readUniversal( stream );
			status = readUniversal( stream );
			}
		if( cryptStatusError( status ) )
			return( status );
		}
	if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 2 ) )
		{
		/* d isn't used so we skip it */
		status = readUniversal( stream );
		if( cryptStatusError( status ) )
			return( status );
		}
	status = readBignumTag( stream, &rsaKey->rsaParam_p, 
							RSAPARAM_MIN_P, RSAPARAM_MAX_P, 
							&rsaKey->rsaParam_n, 3 );
	if( cryptStatusOK( status ) )
		status = readBignumTag( stream, &rsaKey->rsaParam_q, 
								RSAPARAM_MIN_Q, RSAPARAM_MAX_Q, 
								&rsaKey->rsaParam_n, 4 );
	if( cryptStatusError( status ) )
		return( status );
	if( peekTag( stream ) == MAKE_CTAG_PRIMITIVE( 5 ) )
		{
		status = readBignumTag( stream, &rsaKey->rsaParam_exponent1, 
								RSAPARAM_MIN_EXP1, RSAPARAM_MAX_EXP1, 
								&rsaKey->rsaParam_n, 5 );
		if( cryptStatusOK( status ) )
			status = readBignumTag( stream, &rsaKey->rsaParam_exponent2, 
									RSAPARAM_MIN_EXP2, RSAPARAM_MAX_EXP2, 
									&rsaKey->rsaParam_n, 6 );
		if( cryptStatusOK( status ) )
			status = readBignumTag( stream, &rsaKey->rsaParam_u, 
									RSAPARAM_MIN_U, RSAPARAM_MAX_U, 
									&rsaKey->rsaParam_n, 7 );
		}
	return( status );
	}
Example #24
0
static int readConfigOption( INOUT STREAM *stream, 
							 IN_HANDLE CRYPT_USER iCryptUser )
	{
	CRYPT_ATTRIBUTE_TYPE attributeType;
	const BUILTIN_OPTION_INFO *builtinOptionInfoPtr;
	MESSAGE_DATA msgData;
	void *dataPtr DUMMY_INIT_PTR;
	long optionCode;
	int value, tag, length, status;

	/* Read the wrapper and option index and map it to the actual option.  
	   If we find an unknown index or one that shouldn't be writeable to 
	   persistent storage, we skip it and continue.  This is done to handle 
	   new options that may have been added after this version of cryptlib 
	   was built (for unknown indices) and because the stored configuration 
	   options are an untrusted source so we have to check for attempts to 
	   feed in bogus values (for non-writeable options) */
	readSequence( stream, NULL );
	status = readShortInteger( stream, &optionCode );
	if( cryptStatusError( status ) )
		return( status );
	if( optionCode < 0 || optionCode > LAST_OPTION_INDEX )
		{
		/* Unknown option, ignore it */
		return( readUniversal( stream ) );
		}
	builtinOptionInfoPtr = getBuiltinOptionInfoByCode( optionCode );
	if( builtinOptionInfoPtr == NULL || \
		builtinOptionInfoPtr->index < 0 || \
		builtinOptionInfoPtr->index > LAST_OPTION_INDEX || \
		builtinOptionInfoPtr->index == CRYPT_UNUSED )
		{
		/* Unknown option, ignore it */
		return( readUniversal( stream ) );
		}
	attributeType = builtinOptionInfoPtr->option;

	/* Read the option value and set the option.  We don't treat a failure 
	   to set the option as a problem since the user probably doesn't want 
	   the entire system to fail because of a bad configuration option, and 
	   in any case we'll fall back to a safe default value */
	status = tag = peekTag( stream );
	if( cryptStatusError( status ) )
		return( status );
	if( tag == BER_BOOLEAN || tag == BER_INTEGER )
		{
		/* It's a numeric value, read the appropriate type and try and set 
		   the option */
		if( tag == BER_BOOLEAN )
			status = readBoolean( stream, &value );
		else
			{
			long integer;

			status = readShortInteger( stream, &integer );
			if( cryptStatusOK( status ) )
				value = ( int ) integer;
			}
		if( cryptStatusError( status ) )
			return( status );
		( void ) krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE, 
								  &value, attributeType );
		return( CRYPT_OK );
		}

	/* It's a string value, set the option straight from the encoded data */
	status = readGenericHole( stream, &length, 1, BER_STRING_UTF8 );
	if( cryptStatusOK( status ) )
		status = sMemGetDataBlock( stream, &dataPtr, length );
	if( cryptStatusOK( status ) )
		status = sSkip( stream, length, SSKIP_MAX );
	if( cryptStatusError( status ) )
		return( status );
	setMessageData( &msgData, dataPtr, length );
	( void ) krnlSendMessage( iCryptUser, IMESSAGE_SETATTRIBUTE_S, 
							  &msgData, attributeType );

	return( CRYPT_OK );
	}
bool SwissProtPlainTextFormat::readEntry(ParserState* st, U2SequenceImporter& seqImporter, int& sequenceLen,int& fullSequenceLen, bool merge, int gapSize, U2OpStatus& os) {
    Q_UNUSED(merge);
    Q_UNUSED(gapSize);
    U2OpStatus& si = st->si;
    QString lastTagName;
    bool hasLine = false;
    while (hasLine || st->readNextLine(false)) {
        hasLine = false;
        if (st->entry->name.isEmpty()) {
            readIdLine(st);
            assert(si.hasError() || !st->entry->name.isEmpty());
            if (si.hasError()) {
                break;
            }
            continue;
        }
        //
        if (st->hasKey("FH") || st->hasKey("AH")) {
            continue;
        }
        if (st->hasKey("AC")) { //The AC (ACcession number) line lists the accession number(s) associated with an entry.
            QVariant v = st->entry->tags.value(DNAInfo::ACCESSION);
            QStringList l = st->value().split(QRegExp(";\\s*"), QString::SkipEmptyParts);
            st->entry->tags[DNAInfo::ACCESSION] = QVariantUtils::addStr2List(v, l);
            continue;
        }
        if (st->hasKey("OS")) { //The OS (Organism Species) line specifies the organism(s) which was (were) the source of the stored sequence.
            DNASourceInfo soi;
            soi.name = st->value();
            soi.organism = soi.name;
            while (st->readNextLine()) {
                if (st->hasKey("OS")) {
                    soi.organism.append(" ").append(st->value());
                } else if (!st->hasKey("XX")) {
                    break;
                }
            }
            if (st->hasKey("OC")) { //The OC (Organism Classification) lines contain the taxonomic classification of the source organism.
                soi.taxonomy += st->value();
                while (st->readNextLine()) {
                    if (st->hasKey("OC")) {
                        soi.taxonomy.append(st->value());
                    } else if (!st->hasKey("XX")) {
                        break;
                    }
                }
            }
            if (st->hasKey("OG")) { //The OG (OrGanelle) line indicates if the gene coding for a protein originates from the mitochondria, the chloroplast, a cyanelle, or a plasmid.
                soi.organelle = st->value();
            } else {
                hasLine = true;
            }
            st->entry->tags.insertMulti(DNAInfo::SOURCE, qVariantFromValue<DNASourceInfo>(soi));
            continue;
        }
        if (st->hasKey("RF") || st->hasKey("RN")) { //The RN (Reference Number) line gives a sequential number to each reference citation in an entry.
            while (st->readNextLine() && st->buff[0] == 'R')
            {
                //TODO
            }
            hasLine = true;
            continue;
        }
        /*The FT (Feature Table) lines provide a precise but simple means for the annotation of the sequence data.
          The table describes regions or sites of interest in the sequence.
          In general the feature table lists posttranslational modifications, binding sites, enzyme active sites, local secondary structure or other characteristics reported in the cited references.
        */
        if (st->hasKey("FT", 2)) {
            readAnnotations(st, fullSequenceLen + gapSize);
            hasLine = true;
            continue;
        }
        //read simple tag;
        if (st->hasKey("//", 2)) {
            // end of entry
            return true;
        }
        else if (st->hasKey("SQ", 2)) {
            //reading sequence
            readSequence(st,seqImporter,sequenceLen,fullSequenceLen,os);
            if (fullSequenceLen != st->entry->seqLen && !si.getWarnings().contains(EMBLGenbankAbstractDocument::SEQ_LEN_WARNING_MESSAGE)) {
                si.addWarning(EMBLGenbankAbstractDocument::SEQ_LEN_WARNING_MESSAGE);
            }
            CHECK_OP(os,false);
            return true;
        }

        QString key = st->key().trimmed();
        if (tagMap.contains(key)) {
            key = tagMap.value(key);
        }
        if (lastTagName == key) {
            QVariant v = st->entry->tags.take(lastTagName);
            v = QVariantUtils::addStr2List(v, st->value());
            st->entry->tags.insert(lastTagName, v);
        } else if (st->hasValue()) {
            lastTagName = key;
            st->entry->tags.insertMulti(lastTagName, st->value());
        }
    }
    if (!st->isNull() && !si.isCoR()) {
        si.setError(U2::EMBLGenbankAbstractDocument::tr("Record is truncated."));
    }

    return false;
}
Example #26
0
bool VcfMaterializer::_materializeNext(seqan::Dna5String & seq,
                                       MethylationLevels * levels,
                                       std::vector<SmallVarInfo> & varInfos,
                                       std::vector<std::pair<int, int> > & breakpoints,
                                       int & rID,
                                       int & haplotype)
{
    if (levels)
        SEQAN_CHECK(!empty(methFastaFileName), "Must initialize with methylation FASTA file for levels");

    if (empty(vcfFileName))
    {
        if (currRID >= (int)(numSeqs(faiIndex) - 1))
            return false;
        currRID += 1;
        rID = currRID;
        readSequence(seq, faiIndex, currRID);
        if (levels && !empty(methFastaFileName))
        {
            _loadLevels(currRID);
            swap(*levels, currentLevels);
        }

        // Build identity PositionMap.
        TJournalEntries journal;
        reinit(journal, length(seq));
        posMap.reinit(journal);
        GenomicInterval gi(0, length(seq), 0, length(seq));
        seqan::String<PositionMap::TInterval> intervals;
        appendValue(intervals, PositionMap::TInterval(gi.svBeginPos, gi.svEndPos, gi));
        createIntervalTree(posMap.svIntervalTree, intervals);
        createIntervalTree(posMap.svIntervalTreeSTL, intervals);

        return true;
    }

    // Number of sequences.
    int numSeqs = length(contigNames(context(vcfFileIn)));

    // Stop if there are no more haplotypes to materialize.
    if (currRID >= (numSeqs - 1) && nextHaplotype == numHaplotypes)
        return false;

    // Load variants for next contig if necessary.
    if (currRID == -1 || nextHaplotype == numHaplotypes)
    {
        currRID += 1;
        nextHaplotype = 0;

        _loadVariantsForContig(contigVariants, currRID);
        readSequence(contigSeq, faiIndex, currRID);
        if (levels && !empty(methFastaFileName))
            _loadLevels(currRID);
    }

    // Materialize variants for the current haplotype.
    VariantMaterializer varMat(rng, contigVariants, *methOptions);
    if (levels)
        varMat.run(seq, posMap, *levels, varInfos, breakpoints, contigSeq, currentLevels, nextHaplotype);
    else
        varMat.run(seq, posMap, varInfos, breakpoints, contigSeq, nextHaplotype);

    // Write out rID and haploty
    rID = currRID;
    haplotype = nextHaplotype++;
    return true;
}
Example #27
0
int main(int argc, char const ** argv)
{
    double startTime = 0;
    
    // -----------------------------------------------------------------------
    // Parse command line.
    // -----------------------------------------------------------------------
    FxSamCoverageOptions options;
    seqan::ArgumentParser::ParseResult res = parseArgs(options, argc, argv);
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res == seqan::ArgumentParser::PARSE_ERROR;  // 1 on errors, 0 otherwise

    // -----------------------------------------------------------------------
    // Show options.
    // -----------------------------------------------------------------------
    if (options.verbosity >= 1)
    {
        std::cerr << "____OPTIONS___________________________________________________________________\n"
                  << "\n"
                  << "VERBOSITY    " << options.verbosity << "\n"
                  << "GENOME       " << options.inGenomePath << "\n"
                  << "SAM          " << options.inSamPath << "\n"
                  << "OUT          " << options.outPath << "\n"
                  << "WINDOW SIZE  " << options.windowSize << "\n";
    }

    // -----------------------------------------------------------------------
    // Load Genome FAI Index
    // -----------------------------------------------------------------------

    std::cerr << "\n"
              << "___PREPRATION_____________________________________________________________________\n"
              << "\n"
              << "Indexing GENOME file  " << options.inGenomePath << " ...";
    seqan::FaiIndex faiIndex;
    if (build(faiIndex, toCString(options.inGenomePath)) != 0)
    {
        std::cerr << "Could not build FAI index.\n";
        return 1;
    }
    std::cerr << " OK\n";

    // Prepare bins.
    seqan::String<seqan::String<BinData> > bins;
    resize(bins, numSeqs(faiIndex));

    // -----------------------------------------------------------------------
    // Compute C+G content 
    // -----------------------------------------------------------------------

    std::cerr << "\n"
              << "___C+G CONTENT COMPUTATION________________________________________________________\n"
              << "\n";

    for (unsigned i = 0; i < numSeqs(faiIndex); ++i)
    {
        std::cerr << "[" << sequenceName(faiIndex, i) << "] ...";
        unsigned numBins = (sequenceLength(faiIndex, i) + options.windowSize - 1) / options.windowSize;
        resize(bins[i], numBins);
        seqan::Dna5String contigSeq;
        if (readSequence(contigSeq, faiIndex, i) != 0)
        {
            std::cerr << "\nERROR: Could not read sequence " << sequenceName(faiIndex, i) << " from file!\n";
            return 1;
        }

        for (unsigned bin = 0; bin < numBins; ++bin)
        {
            unsigned cgCounter = 0;
            unsigned binSize = 0;
            bins[i][bin].length = options.windowSize;
            if ((bin + 1) * options.windowSize > length(contigSeq))
                bins[i][bin].length = length(contigSeq) - bin * options.windowSize;
            for (unsigned pos = bin * options.windowSize; pos < length(contigSeq) && pos < (bin + 1) * options.windowSize; ++pos, ++binSize)
                cgCounter += (contigSeq[pos] == 'C' || contigSeq[pos] == 'G');
            bins[i][bin].cgContent = 1.0 * cgCounter / binSize;
        }
        std::cerr << "DONE\n";
    }

    // -----------------------------------------------------------------------
    // Compute Coverage
    // -----------------------------------------------------------------------

    std::cerr << "\n"
              << "___COVERAGE COMPUATATION________________________________________________________\n"
              << "\n"
              << "Computing Coverage...";

    seqan::BamStream bamStream(toCString(options.inSamPath));
    if (!isGood(bamStream))
    {
        std::cerr << "Could not open " << options.inSamPath << "!\n";
        return 1;
    }

    seqan::BamAlignmentRecord record;
    while (!atEnd(bamStream))
    {
        if (readRecord(record, bamStream) != 0)
        {
            std::cerr << "ERROR: Could not read record from BAM file!\n";
            return 1;
        }

        if (hasFlagUnmapped(record) || hasFlagSecondary(record) || record.rId == seqan::BamAlignmentRecord::INVALID_REFID)
            continue;  // Skip these records.

        int contigId = 0;
        seqan::CharString const & contigName = nameStore(bamStream.bamIOContext)[record.rId];
        if (!getIdByName(faiIndex, contigName, contigId))
        {
            std::cerr << "ERROR: Alignment to unknown contig " << contigId << "!\n";
            return 1;
        }
        unsigned binNo = record.pos / options.windowSize;
        bins[contigId][binNo].coverage += 1;
    }

    std::cerr << "DONE\n";

    // -----------------------------------------------------------------------
    // Write Output
    // -----------------------------------------------------------------------

    std::ostream * out = &std::cout;
    std::ofstream outFile;
    if (options.outPath != "-")
    {
        outFile.open(toCString(options.outPath), std::ios::binary | std::ios::out);
        if (!outFile.good())
        {
            std::cerr << "ERROR: Could not open output file " << options.outPath << "!\n";
            return 1;
        }
        out = &outFile;
    }

    (*out) << "#BIN\tREF_NAME\tREF_BIN\tBIN_BEGIN\tBIN_LENGTH\tCOVERAGE\tCG_CONTENT\n";
    for (unsigned i = 0, globalBin = 0; i < length(bins); ++i)
    {
        for (unsigned refBin = 0; refBin < length(bins[i]); ++refBin, ++globalBin)
        {
            (*out) << globalBin << '\t'
                   << sequenceName(faiIndex, i) << '\t'
                   << refBin << '\t'
                   << refBin * options.windowSize << '\t'
                   << bins[i][refBin].length << '\t'
                   << bins[i][refBin].coverage << '\t'
                   << bins[i][refBin].cgContent << '\n';
        }
    }

    if (options.verbosity >= 2)
        std::cerr << "Took " << (sysTime() - startTime) << " s\n";

    return 0;
}
Example #28
0
/* 
 * createFrame () - Initialize frame buffer
 * 
 * Also, frame header bytes are initiliazed with default values
 * 
 */
void WaspFrame::createFrame(uint8_t mode, const char* moteID)
{	
	// local variables
	uint8_t sequence;
	
	// store mode: ASCII or BINARY
	_mode=mode;	
	
	// init buffer
	for( int i=0; i < MAX_DATA ; i++ )
	{
		buffer[i]='\0';
	}
	
	// init counter
	numFields = 0;	
	
	// set frame delimiter
	buffer[0] = '<';
	buffer[1] = '=';
	buffer[2] = '>';
		
	uint8_t type;

	// set type of frame depending on the frame mode
	if( _mode == ASCII )
	{
		/** ASCII FRAME **/
		type=B10000000;
		buffer[3]= type;

		//! Queda tipo trama especial !//
	
		// set a "don't care" character in number of fields byte
		buffer[4]='?';
		
		// set the '#' separator
		buffer[5]='#';
		
		// set serial ID
		length=6;
		char str[16];		
		
		// _serial_id is read in main.cxx
		sprintf(str,"%lu",_serial_id);
		
		for( int i=0 ; i<strlen(str) ; i++ )
		{
			// break if end of string
			if( str[i] == '\0') 
			{
				break;
			}
			else
			{
				buffer[length]=str[i];
				length++;
			}
		}

		// set separator '#'
		buffer[length]='#';	
		length++;

		// set identifier
		for( int i=0 ; i<16 ; i++ )
		{
			// break if end of string
			if( moteID[i] == '\0') 
			{
				break;
			}
			else
			{
				buffer[length]=moteID[i];
				length++;
			}
		}

		// set separator '#'
		buffer[length]='#';	
		length++;

		// read and set the sequence number to the frame   
		sequence=readSequence();

		char seqStr[4];
		itoa(sequence, seqStr, 10);		
		strncat((char*)buffer, seqStr, strlen(seqStr));
		length += strlen(seqStr);
		buffer[length]='#';		
		length++;

		// increment and store the frame sequence number
		sequence++;
		storeSequence(sequence);
		
		// now the frame is ready to be filled with new sensor values!		
	}
	else 
	{		
		if (_mode == BINARY)
		{
			/** BINARY FRAME **/
			type=B00000000;
			buffer[3]= type;
		}
		
		// set a "don't care" character in number of fields byte
		buffer[4]='?';	
		
		// set serial ID
		// _serial_id is read in main.cxx				
		char val[4]; 
		memcpy(val, (const void*)&_serial_id, 4);
		
		/*union {
		  unsigned long f;
		  char b[4];
		} u;
		u.b[3] = val[3];
		u.b[2] = val[2];
		u.b[1] = val[1];
		u.b[0] = val[0];

		USB.println(u.f);	*/

		// concatenate sensor name to frame string
        buffer[5] = val[0];
		buffer[6] = val[1];
        buffer[7] = val[2];
		buffer[8] = val[3];
		length=9;		

		// set identifier
		for( int i=0 ; i<16 ; i++ )
		{
			// break if end of string
			if( moteID[i] == '\0') 
			{
				break;
			}
			else
			{
				buffer[length]=moteID[i];
				length++;
			}
		}

		// set separator '#'
		buffer[length]='#';	
		length++;

		// read and set the sequence number to the frame   
		sequence=readSequence();
		buffer[length]=sequence;
		length++;

		sequence++;
		storeSequence(sequence);

	}
}
Example #29
0
/**
 * FASTQ format specification: http://maq.sourceforge.net/fastq.shtml
 */
static void load(IOAdapter* io, const U2DbiRef& dbiRef, const QVariantMap& hints, const GUrl& docUrl, QList<GObject*>& objects, U2OpStatus& os,
                 int gapSize, int predictedSize, QString& writeLockReason) {
    DbiOperationsBlock opBlock(dbiRef, os);
    CHECK_OP(os, );
    Q_UNUSED(opBlock);
    writeLockReason.clear();

    bool merge = gapSize!=-1;
    QByteArray sequence;
    QByteArray qualityScores;
    QStringList headers;
    QSet<QString> uniqueNames;

    QVector<U2Region> mergedMapping;
    QByteArray gapSequence((merge ? gapSize : 0), 0);
    sequence.reserve(predictedSize);
    qualityScores.reserve(predictedSize);

    // for lower case annotations
    GObjectReference sequenceRef;
    qint64 sequenceStart = 0;

    U2SequenceImporter seqImporter(hints, true);
    const QString folder = hints.value(DocumentFormat::DBI_FOLDER_HINT, U2ObjectDbi::ROOT_FOLDER).toString();
    int seqNumber = 0;
    int progressUpNum = 0;

    const int objectsCountLimit = hints.contains(DocumentReadingMode_MaxObjectsInDoc) ? hints[DocumentReadingMode_MaxObjectsInDoc].toInt() : -1;
    const bool settingsMakeUniqueName = !hints.value(DocumentReadingMode_DontMakeUniqueNames, false).toBool();
    while (!os.isCoR()) {
        //read header
        QString sequenceName = readSequenceName(os, io, '@');
        // check for eof while trying to read another FASTQ block
        if (io->isEof()) {
            break;
        }

        CHECK_OP_BREAK(os);

        if(sequenceName.isEmpty()){
            sequenceName = "Sequence";
        }

        if ((merge == false) || (seqNumber == 0)) {
            QString objName = sequenceName;
            if (settingsMakeUniqueName) {
                objName = (merge) ? "Sequence" : TextUtils::variate(sequenceName, "_", uniqueNames);
                objName.squeeze();
                uniqueNames.insert(objName);
            }
            seqImporter.startSequence(dbiRef, folder, objName, false, os);
            CHECK_OP_BREAK(os);
        }

        //read sequence
        if (merge && sequence.length() > 0) {
            seqImporter.addDefaultSymbolsBlock(gapSize,os);
            sequenceStart += sequence.length();
            sequenceStart+=gapSize;
            CHECK_OP_BREAK(os);
        }

        sequence.clear();
        readSequence(os, io, sequence);
        MemoryLocker lSequence(os, qCeil(sequence.size()/(1000*1000)));
        CHECK_OP_BREAK(os);
        Q_UNUSED(lSequence);

        seqImporter.addBlock(sequence.data(),sequence.length(),os);
        CHECK_OP_BREAK(os);

        QString qualSequenceName = readSequenceName(os, io, '+');
        if (!qualSequenceName.isEmpty()) {
            static const QString err = U2::FastqFormat::tr("Not a valid FASTQ file: %1, sequence name differs from quality scores name: %2 and %3");
            CHECK_EXT_BREAK(sequenceName == qualSequenceName,
                os.setError(err.arg(docUrl.getURLString()).arg(sequenceName).arg(qualSequenceName)));
        }

        // read qualities
        qualityScores.clear();
        readQuality(os, io, qualityScores, sequence.size());
        CHECK_OP_BREAK(os);

        static const QString err = U2::FastqFormat::tr("Not a valid FASTQ file: %1. Bad quality scores: inconsistent size.").arg(docUrl.getURLString());
        CHECK_EXT_BREAK(sequence.length() == qualityScores.length(), os.setError(err));

        seqNumber++;
        progressUpNum++;
        if (merge) {
            headers.append(sequenceName);
            mergedMapping.append(U2Region(sequenceStart, sequence.length() ));
        }
        else {
            if (objectsCountLimit > 0 && objects.size() >= objectsCountLimit) {
                os.setError(FastqFormat::tr("File \"%1\" contains too many sequences to be displayed. "
                    "However, you can process these data using instruments from the menu <i>Tools -> NGS data analysis</i> "
                    "or pipelines built with Workflow Designer.")
                    .arg(io->getURL().getURLString()));
                break;
            }

            U2Sequence u2seq = seqImporter.finalizeSequenceAndValidate(os);
            CHECK_OP_BREAK(os);
            sequenceRef = GObjectReference(io->getURL().getURLString(), u2seq.visualName, GObjectTypes::SEQUENCE, U2EntityRef(dbiRef, u2seq.id));

            U2SequenceObject* seqObj = new U2SequenceObject(u2seq.visualName, U2EntityRef(dbiRef, u2seq.id));
            CHECK_EXT_BREAK(seqObj != NULL, os.setError("U2SequenceObject is NULL"));
            seqObj->setQuality(DNAQuality(qualityScores));
            objects << seqObj;

            U1AnnotationUtils::addAnnotations(objects, seqImporter.getCaseAnnotations(), sequenceRef, NULL, hints);
        }
        if (PROGRESS_UPDATE_STEP == progressUpNum) {
            progressUpNum = 0;
            os.setProgress(io->getProgress());
        }
    }

    CHECK_OP_EXT(os, qDeleteAll(objects); objects.clear(), );
    bool emptyObjects = objects.isEmpty();
    CHECK_EXT(!emptyObjects || merge, os.setError(Document::tr("Document is empty.")), );
    SAFE_POINT(headers.size() == mergedMapping.size(), "headers <-> regions mapping failed!", );

    if (!merge) {
        return;
    }
    U2Sequence u2seq = seqImporter.finalizeSequenceAndValidate(os);
    CHECK_OP(os,);

    sequenceRef = GObjectReference(io->getURL().getURLString(), u2seq.visualName, GObjectTypes::SEQUENCE, U2EntityRef(dbiRef, u2seq.id));

    U1AnnotationUtils::addAnnotations(objects, seqImporter.getCaseAnnotations(), sequenceRef, NULL, hints);
    objects << new U2SequenceObject(u2seq.visualName, U2EntityRef(dbiRef, u2seq.id));
    objects << DocumentFormatUtils::addAnnotationsForMergedU2Sequence(sequenceRef, dbiRef, headers, mergedMapping, hints);
    if (headers.size() > 1) {
        writeLockReason = DocumentFormat::MERGED_SEQ_LOCK;
    }
}
static int readKeyIdentifiers( INOUT STREAM *stream, 
							   INOUT PKCS15_INFO *pkcs15infoPtr,
							   IN_LENGTH const int endPos )
	{
	int iterationCount, status;

	assert( isWritePtr( stream, sizeof( STREAM ) ) );
	assert( isWritePtr( pkcs15infoPtr, sizeof( PKCS15_INFO ) ) );
	
	REQUIRES( endPos > 0 && endPos > stell( stream ) && \
			  endPos < MAX_INTLENGTH );

	for( status = CRYPT_OK, iterationCount = 0;
		 cryptStatusOK( status ) && stell( stream ) < endPos && \
			iterationCount < FAILSAFE_ITERATIONS_MED; iterationCount++ )
		{
		long value;
		int payloadLength;

		/* Read each identifier type and copy the useful ones into the PKCS
		   #15 information */
		readSequence( stream, &payloadLength );
		status = readShortInteger( stream, &value );
		if( cryptStatusError( status ) )
			return( status );
		switch( value )
			{
			case PKCS15_KEYID_ISSUERANDSERIALNUMBER:
				{
				HASHFUNCTION_ATOMIC hashFunctionAtomic;
				void *iAndSPtr = DUMMY_INIT_PTR;
				int iAndSLength, hashSize;

				/* If we've already got the iAndSID, use that version 
				   instead */
				if( pkcs15infoPtr->iAndSIDlength > 0 )
					{
					status = readUniversal( stream );
					continue;
					}

				/* Hash the full issuerAndSerialNumber to get an iAndSID */
				getHashAtomicParameters( CRYPT_ALGO_SHA1, 0,
										 &hashFunctionAtomic, &hashSize );
				status = getStreamObjectLength( stream, &iAndSLength );
				if( cryptStatusOK( status ) )
					status = sMemGetDataBlock( stream, &iAndSPtr, 
											   iAndSLength );
				if( cryptStatusOK( status ) )
					status = sSkip( stream, iAndSLength );
				if( cryptStatusError( status ) )
					return( status );
				hashFunctionAtomic( pkcs15infoPtr->iAndSID, KEYID_SIZE, 
									iAndSPtr, iAndSLength );
				pkcs15infoPtr->iAndSIDlength = hashSize;
				break;
				}

			case PKCS15_KEYID_SUBJECTKEYIDENTIFIER:
				status = readOctetString( stream, pkcs15infoPtr->keyID,
										  &pkcs15infoPtr->keyIDlength, 
										  8, CRYPT_MAX_HASHSIZE );
				break;

			case PKCS15_KEYID_ISSUERANDSERIALNUMBERHASH:
				/* If we've already got the iAndSID by hashing the
				   issuerAndSerialNumber, use that version instead */
				if( pkcs15infoPtr->iAndSIDlength > 0 )
					{
					status = readUniversal( stream );
					continue;
					}
				status = readOctetString( stream, pkcs15infoPtr->iAndSID,
										  &pkcs15infoPtr->iAndSIDlength, 
										  KEYID_SIZE, KEYID_SIZE );
				break;

			case PKCS15_KEYID_ISSUERNAMEHASH:
				status = readOctetString( stream, pkcs15infoPtr->issuerNameID,
										  &pkcs15infoPtr->issuerNameIDlength, 
										  KEYID_SIZE, KEYID_SIZE );
				break;

			case PKCS15_KEYID_SUBJECTNAMEHASH:
				status = readOctetString( stream, pkcs15infoPtr->subjectNameID,
										  &pkcs15infoPtr->subjectNameIDlength, 
										  KEYID_SIZE, KEYID_SIZE );
				break;

			case PKCS15_KEYID_PGP2:
				status = readOctetString( stream, pkcs15infoPtr->pgp2KeyID,
										  &pkcs15infoPtr->pgp2KeyIDlength, 
										  PGP_KEYID_SIZE, PGP_KEYID_SIZE );
				break;

			case PKCS15_KEYID_OPENPGP:
				status = readOctetString( stream, pkcs15infoPtr->openPGPKeyID,
										  &pkcs15infoPtr->openPGPKeyIDlength, 
										  PGP_KEYID_SIZE, PGP_KEYID_SIZE );
				break;

			default:
				status = readUniversal( stream );
			}
		}
	if( iterationCount >= FAILSAFE_ITERATIONS_MED )
		{
		/* This could be either an internal error or some seriously 
		   malformed data, since we can't tell without human intervention
		   we throw a debug exception but otherwise treat it as bad data */
		DEBUG_DIAG(( "Encountered more than %d key IDs", 
					 FAILSAFE_ITERATIONS_MED ));
		assert( DEBUG_WARN );
		return( CRYPT_ERROR_BADDATA );
		}

	return( status );
	}