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

Generated on Fri Aug 13 09:56:52 2004 for Crypto++ by doxygen 1.3.7