Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

asn.cpp

00001 // asn.cpp - written and placed in the public domain by Wei Dai 00002 00003 #include "pch.h" 00004 00005 #ifndef CRYPTOPP_IMPORTS 00006 00007 #include "asn.h" 00008 00009 #include <iomanip> 00010 #include <time.h> 00011 00012 NAMESPACE_BEGIN(CryptoPP) 00013 USING_NAMESPACE(std) 00014 00015 /// DER Length 00016 unsigned int DERLengthEncode(BufferedTransformation &bt, unsigned int length) 00017 { 00018 unsigned int i=0; 00019 if (length <= 0x7f) 00020 { 00021 bt.Put(byte(length)); 00022 i++; 00023 } 00024 else 00025 { 00026 bt.Put(byte(BytePrecision(length) | 0x80)); 00027 i++; 00028 for (int j=BytePrecision(length); j; --j) 00029 { 00030 bt.Put(byte(length >> (j-1)*8)); 00031 i++; 00032 } 00033 } 00034 return i; 00035 } 00036 00037 bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length, bool &definiteLength) 00038 { 00039 byte b; 00040 00041 if (!bt.Get(b)) 00042 return false; 00043 00044 if (!(b & 0x80)) 00045 { 00046 definiteLength = true; 00047 length = b; 00048 } 00049 else 00050 { 00051 unsigned int lengthBytes = b & 0x7f; 00052 00053 if (lengthBytes == 0) 00054 { 00055 definiteLength = false; 00056 return true; 00057 } 00058 00059 definiteLength = true; 00060 length = 0; 00061 while (lengthBytes--) 00062 { 00063 if (length >> (8*(sizeof(length)-1))) 00064 BERDecodeError(); // length about to overflow 00065 00066 if (!bt.Get(b)) 00067 return false; 00068 00069 length = (length << 8) | b; 00070 } 00071 } 00072 return true; 00073 } 00074 00075 bool BERLengthDecode(BufferedTransformation &bt, unsigned int &length) 00076 { 00077 bool definiteLength; 00078 if (!BERLengthDecode(bt, length, definiteLength)) 00079 BERDecodeError(); 00080 return definiteLength; 00081 } 00082 00083 void DEREncodeNull(BufferedTransformation &out) 00084 { 00085 out.Put(TAG_NULL); 00086 out.Put(0); 00087 } 00088 00089 void BERDecodeNull(BufferedTransformation &in) 00090 { 00091 byte b; 00092 if (!in.Get(b) || b != TAG_NULL) 00093 BERDecodeError(); 00094 unsigned int length; 00095 if (!BERLengthDecode(in, length) || length != 0) 00096 BERDecodeError(); 00097 } 00098 00099 /// ASN Strings 00100 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const byte *str, unsigned int strLen) 00101 { 00102 bt.Put(OCTET_STRING); 00103 unsigned int lengthBytes = DERLengthEncode(bt, strLen); 00104 bt.Put(str, strLen); 00105 return 1+lengthBytes+strLen; 00106 } 00107 00108 unsigned int DEREncodeOctetString(BufferedTransformation &bt, const SecByteBlock &str) 00109 { 00110 return DEREncodeOctetString(bt, str.begin(), str.size()); 00111 } 00112 00113 unsigned int BERDecodeOctetString(BufferedTransformation &bt, SecByteBlock &str) 00114 { 00115 byte b; 00116 if (!bt.Get(b) || b != OCTET_STRING) 00117 BERDecodeError(); 00118 00119 unsigned int bc; 00120 if (!BERLengthDecode(bt, bc)) 00121 BERDecodeError(); 00122 00123 str.resize(bc); 00124 if (bc != bt.Get(str, bc)) 00125 BERDecodeError(); 00126 return bc; 00127 } 00128 00129 unsigned int BERDecodeOctetString(BufferedTransformation &bt, BufferedTransformation &str) 00130 { 00131 byte b; 00132 if (!bt.Get(b) || b != OCTET_STRING) 00133 BERDecodeError(); 00134 00135 unsigned int bc; 00136 if (!BERLengthDecode(bt, bc)) 00137 BERDecodeError(); 00138 00139 bt.TransferTo(str, bc); 00140 return bc; 00141 } 00142 00143 unsigned int DEREncodeTextString(BufferedTransformation &bt, const std::string &str, byte asnTag) 00144 { 00145 bt.Put(asnTag); 00146 unsigned int lengthBytes = DERLengthEncode(bt, str.size()); 00147 bt.Put((const byte *)str.data(), str.size()); 00148 return 1+lengthBytes+str.size(); 00149 } 00150 00151 unsigned int BERDecodeTextString(BufferedTransformation &bt, std::string &str, byte asnTag) 00152 { 00153 byte b; 00154 if (!bt.Get(b) || b != asnTag) 00155 BERDecodeError(); 00156 00157 unsigned int bc; 00158 if (!BERLengthDecode(bt, bc)) 00159 BERDecodeError(); 00160 00161 SecByteBlock temp(bc); 00162 if (bc != bt.Get(temp, bc)) 00163 BERDecodeError(); 00164 str.assign((char *)temp.begin(), bc); 00165 return bc; 00166 } 00167 00168 /// ASN BitString 00169 unsigned int DEREncodeBitString(BufferedTransformation &bt, const byte *str, unsigned int strLen, unsigned int unusedBits) 00170 { 00171 bt.Put(BIT_STRING); 00172 unsigned int lengthBytes = DERLengthEncode(bt, strLen+1); 00173 bt.Put((byte)unusedBits); 00174 bt.Put(str, strLen); 00175 return 2+lengthBytes+strLen; 00176 } 00177 00178 unsigned int BERDecodeBitString(BufferedTransformation &bt, SecByteBlock &str, unsigned int &unusedBits) 00179 { 00180 byte b; 00181 if (!bt.Get(b) || b != BIT_STRING) 00182 BERDecodeError(); 00183 00184 unsigned int bc; 00185 if (!BERLengthDecode(bt, bc)) 00186 BERDecodeError(); 00187 00188 byte unused; 00189 if (!bt.Get(unused)) 00190 BERDecodeError(); 00191 unusedBits = unused; 00192 str.resize(bc-1); 00193 if ((bc-1) != bt.Get(str, bc-1)) 00194 BERDecodeError(); 00195 return bc-1; 00196 } 00197 00198 void DERReencode(BufferedTransformation &source, BufferedTransformation &dest) 00199 { 00200 byte tag; 00201 source.Peek(tag); 00202 BERGeneralDecoder decoder(source, tag); 00203 DERGeneralEncoder encoder(dest, tag); 00204 if (decoder.IsDefiniteLength()) 00205 decoder.TransferTo(encoder, decoder.RemainingLength()); 00206 else 00207 { 00208 while (!decoder.EndReached()) 00209 DERReencode(decoder, encoder); 00210 } 00211 decoder.MessageEnd(); 00212 encoder.MessageEnd(); 00213 } 00214 00215 void OID::EncodeValue(BufferedTransformation &bt, unsigned long v) 00216 { 00217 for (unsigned int i=RoundUpToMultipleOf(STDMAX(7U,BitPrecision(v)), 7U)-7; i != 0; i-=7) 00218 bt.Put((byte)(0x80 | ((v >> i) & 0x7f))); 00219 bt.Put((byte)(v & 0x7f)); 00220 } 00221 00222 unsigned int OID::DecodeValue(BufferedTransformation &bt, unsigned long &v) 00223 { 00224 byte b; 00225 unsigned int i=0; 00226 v = 0; 00227 while (true) 00228 { 00229 if (!bt.Get(b)) 00230 BERDecodeError(); 00231 i++; 00232 v <<= 7; 00233 v += b & 0x7f; 00234 if (!(b & 0x80)) 00235 return i; 00236 } 00237 } 00238 00239 void OID::DEREncode(BufferedTransformation &bt) const 00240 { 00241 assert(m_values.size() >= 2); 00242 ByteQueue temp; 00243 temp.Put(byte(m_values[0] * 40 + m_values[1])); 00244 for (unsigned int i=2; i<m_values.size(); i++) 00245 EncodeValue(temp, m_values[i]); 00246 bt.Put(OBJECT_IDENTIFIER); 00247 DERLengthEncode(bt, temp.CurrentSize()); 00248 temp.TransferTo(bt); 00249 } 00250 00251 void OID::BERDecode(BufferedTransformation &bt) 00252 { 00253 byte b; 00254 if (!bt.Get(b) || b != OBJECT_IDENTIFIER) 00255 BERDecodeError(); 00256 00257 unsigned int length; 00258 if (!BERLengthDecode(bt, length) || length < 1) 00259 BERDecodeError(); 00260 00261 if (!bt.Get(b)) 00262 BERDecodeError(); 00263 00264 length--; 00265 m_values.resize(2); 00266 m_values[0] = b / 40; 00267 m_values[1] = b % 40; 00268 00269 while (length > 0) 00270 { 00271 unsigned long v; 00272 unsigned int valueLen = DecodeValue(bt, v); 00273 if (valueLen > length) 00274 BERDecodeError(); 00275 m_values.push_back(v); 00276 length -= valueLen; 00277 } 00278 } 00279 00280 void OID::BERDecodeAndCheck(BufferedTransformation &bt) const 00281 { 00282 OID oid(bt); 00283 if (*this != oid) 00284 BERDecodeError(); 00285 } 00286 00287 inline BufferedTransformation & EncodedObjectFilter::CurrentTarget() 00288 { 00289 if (m_flags & PUT_OBJECTS) 00290 return *AttachedTransformation(); 00291 else 00292 return TheBitBucket(); 00293 } 00294 00295 void EncodedObjectFilter::Put(const byte *inString, unsigned int length) 00296 { 00297 if (m_nCurrentObject == m_nObjects) 00298 { 00299 AttachedTransformation()->Put(inString, length); 00300 return; 00301 } 00302 00303 LazyPutter lazyPutter(m_queue, inString, length); 00304 00305 while (m_queue.AnyRetrievable()) 00306 { 00307 switch (m_state) 00308 { 00309 case IDENTIFIER: 00310 if (!m_queue.Get(m_id)) 00311 return; 00312 m_queue.TransferTo(CurrentTarget(), 1); 00313 m_state = LENGTH; // fall through 00314 case LENGTH: 00315 { 00316 byte b; 00317 if (m_level > 0 && m_id == 0 && m_queue.Peek(b) && b == 0) 00318 { 00319 m_queue.TransferTo(CurrentTarget(), 1); 00320 m_level--; 00321 m_state = IDENTIFIER; 00322 break; 00323 } 00324 ByteQueue::Walker walker(m_queue); 00325 bool definiteLength; 00326 if (!BERLengthDecode(walker, m_lengthRemaining, definiteLength)) 00327 return; 00328 m_queue.TransferTo(CurrentTarget(), walker.GetCurrentPosition()); 00329 if (!((m_id & CONSTRUCTED) || definiteLength)) 00330 BERDecodeError(); 00331 if (!definiteLength) 00332 { 00333 if (!(m_id & CONSTRUCTED)) 00334 BERDecodeError(); 00335 m_level++; 00336 m_state = IDENTIFIER; 00337 break; 00338 } 00339 m_state = BODY; // fall through 00340 } 00341 case BODY: 00342 m_lengthRemaining -= m_queue.TransferTo(CurrentTarget(), m_lengthRemaining); 00343 00344 if (m_lengthRemaining == 0) 00345 m_state = IDENTIFIER; 00346 } 00347 00348 if (m_state == IDENTIFIER && m_level == 0) 00349 { 00350 // just finished processing a level 0 object 00351 ++m_nCurrentObject; 00352 00353 if (m_flags & PUT_MESSANGE_END_AFTER_EACH_OBJECT) 00354 AttachedTransformation()->MessageEnd(); 00355 00356 if (m_nCurrentObject == m_nObjects) 00357 { 00358 if (m_flags & PUT_MESSANGE_END_AFTER_ALL_OBJECTS) 00359 AttachedTransformation()->MessageEnd(); 00360 00361 if (m_flags & PUT_MESSANGE_SERIES_END_AFTER_ALL_OBJECTS) 00362 AttachedTransformation()->MessageSeriesEnd(); 00363 00364 m_queue.TransferAllTo(*AttachedTransformation()); 00365 return; 00366 } 00367 } 00368 } 00369 } 00370 00371 BERGeneralDecoder::BERGeneralDecoder(BufferedTransformation &inQueue, byte asnTag) 00372 : m_inQueue(inQueue), m_finished(false) 00373 { 00374 Init(asnTag); 00375 } 00376 00377 BERGeneralDecoder::BERGeneralDecoder(BERGeneralDecoder &inQueue, byte asnTag) 00378 : m_inQueue(inQueue), m_finished(false) 00379 { 00380 Init(asnTag); 00381 } 00382 00383 void BERGeneralDecoder::Init(byte asnTag) 00384 { 00385 byte b; 00386 if (!m_inQueue.Get(b) || b != asnTag) 00387 BERDecodeError(); 00388 00389 m_definiteLength = BERLengthDecode(m_inQueue, m_length); 00390 if (!m_definiteLength && !(asnTag & CONSTRUCTED)) 00391 BERDecodeError(); // cannot be primitive and have indefinite length 00392 } 00393 00394 BERGeneralDecoder::~BERGeneralDecoder() 00395 { 00396 try // avoid throwing in constructor 00397 { 00398 if (!m_finished) 00399 MessageEnd(); 00400 } 00401 catch (...) 00402 { 00403 } 00404 } 00405 00406 bool BERGeneralDecoder::EndReached() const 00407 { 00408 if (m_definiteLength) 00409 return m_length == 0; 00410 else 00411 { // check end-of-content octets 00412 word16 i; 00413 return (m_inQueue.PeekWord16(i)==2 && i==0); 00414 } 00415 } 00416 00417 byte BERGeneralDecoder::PeekByte() const 00418 { 00419 byte b; 00420 if (!Peek(b)) 00421 BERDecodeError(); 00422 return b; 00423 } 00424 00425 void BERGeneralDecoder::CheckByte(byte check) 00426 { 00427 byte b; 00428 if (!Get(b) || b != check) 00429 BERDecodeError(); 00430 } 00431 00432 void BERGeneralDecoder::MessageEnd() 00433 { 00434 m_finished = true; 00435 if (m_definiteLength) 00436 { 00437 if (m_length != 0) 00438 BERDecodeError(); 00439 } 00440 else 00441 { // remove end-of-content octets 00442 word16 i; 00443 if (m_inQueue.GetWord16(i) != 2 || i != 0) 00444 BERDecodeError(); 00445 } 00446 } 00447 00448 unsigned int BERGeneralDecoder::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking) 00449 { 00450 if (m_definiteLength && transferBytes > m_length) 00451 transferBytes = m_length; 00452 unsigned int blockedBytes = m_inQueue.TransferTo2(target, transferBytes, channel, blocking); 00453 ReduceLength(transferBytes); 00454 return blockedBytes; 00455 } 00456 00457 unsigned int BERGeneralDecoder::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const 00458 { 00459 if (m_definiteLength) 00460 end = STDMIN((unsigned long)m_length, end); 00461 return m_inQueue.CopyRangeTo2(target, begin, end, channel, blocking); 00462 } 00463 00464 unsigned int BERGeneralDecoder::ReduceLength(unsigned int delta) 00465 { 00466 if (m_definiteLength) 00467 { 00468 if (m_length < delta) 00469 BERDecodeError(); 00470 m_length -= delta; 00471 } 00472 return delta; 00473 } 00474 00475 DERGeneralEncoder::DERGeneralEncoder(BufferedTransformation &outQueue, byte asnTag) 00476 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) 00477 { 00478 } 00479 00480 DERGeneralEncoder::DERGeneralEncoder(DERGeneralEncoder &outQueue, byte asnTag) 00481 : m_outQueue(outQueue), m_finished(false), m_asnTag(asnTag) 00482 { 00483 } 00484 00485 DERGeneralEncoder::~DERGeneralEncoder() 00486 { 00487 try // avoid throwing in constructor 00488 { 00489 if (!m_finished) 00490 MessageEnd(); 00491 } 00492 catch (...) 00493 { 00494 } 00495 } 00496 00497 void DERGeneralEncoder::MessageEnd() 00498 { 00499 m_finished = true; 00500 unsigned int length = (unsigned int)CurrentSize(); 00501 m_outQueue.Put(m_asnTag); 00502 DERLengthEncode(m_outQueue, length); 00503 TransferTo(m_outQueue); 00504 } 00505 00506 // ************************************************************* 00507 00508 void X509PublicKey::BERDecode(BufferedTransformation &bt) 00509 { 00510 BERSequenceDecoder subjectPublicKeyInfo(bt); 00511 BERSequenceDecoder algorithm(subjectPublicKeyInfo); 00512 GetAlgorithmID().BERDecodeAndCheck(algorithm); 00513 bool parametersPresent = algorithm.EndReached() ? false : BERDecodeAlgorithmParameters(algorithm); 00514 algorithm.MessageEnd(); 00515 00516 BERGeneralDecoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); 00517 subjectPublicKey.CheckByte(0); // unused bits 00518 BERDecodeKey2(subjectPublicKey, parametersPresent, subjectPublicKey.RemainingLength()); 00519 subjectPublicKey.MessageEnd(); 00520 subjectPublicKeyInfo.MessageEnd(); 00521 } 00522 00523 void X509PublicKey::DEREncode(BufferedTransformation &bt) const 00524 { 00525 DERSequenceEncoder subjectPublicKeyInfo(bt); 00526 00527 DERSequenceEncoder algorithm(subjectPublicKeyInfo); 00528 GetAlgorithmID().DEREncode(algorithm); 00529 DEREncodeAlgorithmParameters(algorithm); 00530 algorithm.MessageEnd(); 00531 00532 DERGeneralEncoder subjectPublicKey(subjectPublicKeyInfo, BIT_STRING); 00533 subjectPublicKey.Put(0); // unused bits 00534 DEREncodeKey(subjectPublicKey); 00535 subjectPublicKey.MessageEnd(); 00536 00537 subjectPublicKeyInfo.MessageEnd(); 00538 } 00539 00540 void PKCS8PrivateKey::BERDecode(BufferedTransformation &bt) 00541 { 00542 BERSequenceDecoder privateKeyInfo(bt); 00543 word32 version; 00544 BERDecodeUnsigned<word32>(privateKeyInfo, version, INTEGER, 0, 0); // check version 00545 00546 BERSequenceDecoder algorithm(privateKeyInfo); 00547 GetAlgorithmID().BERDecodeAndCheck(algorithm); 00548 bool parametersPresent = BERDecodeAlgorithmParameters(algorithm); 00549 algorithm.MessageEnd(); 00550 00551 BERGeneralDecoder octetString(privateKeyInfo, OCTET_STRING); 00552 BERDecodeKey2(octetString, parametersPresent, privateKeyInfo.RemainingLength()); 00553 octetString.MessageEnd(); 00554 00555 if (!privateKeyInfo.EndReached()) 00556 BERDecodeOptionalAttributes(privateKeyInfo); 00557 privateKeyInfo.MessageEnd(); 00558 } 00559 00560 void PKCS8PrivateKey::DEREncode(BufferedTransformation &bt) const 00561 { 00562 DERSequenceEncoder privateKeyInfo(bt); 00563 DEREncodeUnsigned<word32>(privateKeyInfo, 0); // version 00564 00565 DERSequenceEncoder algorithm(privateKeyInfo); 00566 GetAlgorithmID().DEREncode(algorithm); 00567 DEREncodeAlgorithmParameters(algorithm); 00568 algorithm.MessageEnd(); 00569 00570 DERGeneralEncoder octetString(privateKeyInfo, OCTET_STRING); 00571 DEREncodeKey(octetString); 00572 octetString.MessageEnd(); 00573 00574 DEREncodeOptionalAttributes(privateKeyInfo); 00575 privateKeyInfo.MessageEnd(); 00576 } 00577 00578 void PKCS8PrivateKey::BERDecodeOptionalAttributes(BufferedTransformation &bt) 00579 { 00580 DERReencode(bt, m_optionalAttributes); 00581 } 00582 00583 void PKCS8PrivateKey::DEREncodeOptionalAttributes(BufferedTransformation &bt) const 00584 { 00585 m_optionalAttributes.CopyTo(bt); 00586 } 00587 00588 NAMESPACE_END 00589 00590 #endif

Generated on Wed Jul 21 19:15:20 2004 for Crypto++ by doxygen 1.3.7-20040704