// Too complicated to be inline Result ReadTagAndGetValue(Reader& input, /*out*/ uint8_t& tag, /*out*/ Input& value) { Result rv; rv = input.Read(tag); if (rv != Success) { return rv; } if ((tag & 0x1F) == 0x1F) { return Result::ERROR_BAD_DER; // high tag number form not allowed } uint16_t length; // The short form of length is a single byte with the high order bit set // to zero. The long form of length is one byte with the high order bit // set, followed by N bytes, where N is encoded in the lowest 7 bits of // the first byte. uint8_t length1; rv = input.Read(length1); if (rv != Success) { return rv; } if (!(length1 & 0x80)) { length = length1; } else if (length1 == 0x81) { uint8_t length2; rv = input.Read(length2); if (rv != Success) { return rv; } if (length2 < 128) { // Not shortest possible encoding return Result::ERROR_BAD_DER; } length = length2; } else if (length1 == 0x82) { rv = input.Read(length); if (rv != Success) { return rv; } if (length < 256) { // Not shortest possible encoding return Result::ERROR_BAD_DER; } } else { // We don't support lengths larger than 2^16 - 1. return Result::ERROR_BAD_DER; } return input.Skip(length, value); }
Result BitStringWithNoUnusedBits(Reader& input, /*out*/ Input& value) { Reader valueWithUnusedBits; Result rv = ExpectTagAndGetValue(input, BIT_STRING, valueWithUnusedBits); if (rv != Success) { return rv; } uint8_t unusedBitsAtEnd; if (valueWithUnusedBits.Read(unusedBitsAtEnd) != Success) { return Result::ERROR_BAD_DER; } // XXX: Really the constraint should be that unusedBitsAtEnd must be less // than 7. But, we suspect there are no real-world values in OCSP responses // or certificates with non-zero unused bits. It seems like NSS assumes this // in various places, so we enforce it too in order to simplify this code. If // we find compatibility issues, we'll know we're wrong and we'll have to // figure out how to shift the bits around. if (unusedBitsAtEnd != 0) { return Result::ERROR_BAD_DER; } Reader::Mark mark(valueWithUnusedBits.GetMark()); valueWithUnusedBits.SkipToEnd(); return valueWithUnusedBits.GetInput(mark, value); }
size_t IngoingCrossNode::Load(const Reader & r, size_t pos, size_t adjacencyIndex) { char buff[sizeof(m_nodeId) + sizeof(uint64_t)]; r.Read(pos, buff, sizeof(buff)); m_nodeId = *reinterpret_cast<decltype(m_nodeId) *>(&buff[0]); m2::PointD bufferPoint = Int64ToPoint(*reinterpret_cast<uint64_t *>(&(buff[sizeof(m_nodeId)])), kCoordBits); m_point = ms::LatLon(bufferPoint.y, bufferPoint.x); m_adjacencyIndex = adjacencyIndex; return pos + sizeof(buff); }
static inline Result ReadDigit(Reader& input, /*out*/ unsigned int& value) { uint8_t b; if (input.Read(b) != Success) { return Result::ERROR_INVALID_TIME; } if (b < '0' || b > '9') { return Result::ERROR_INVALID_TIME; } value = static_cast<unsigned int>(b - static_cast<uint8_t>('0')); return Success; }
int main(int argc, char* argv[]) { Reader *x = new Reader("text_src"); Writer *y = new Writer("text_dest"); if (!x->IsOpened() && !y->IsOpened()) { std::cout << "Could not open file\n"; return 1; } std::vector<uchar> *block = new std::vector<uchar>; int i = 0; while (!x->IsLastBlock()){ i++; block->clear(); x->Read(block); y->Write(*block); } x->~Reader(); y->~Writer(); return 0; }
void CrossRoutingContextReader::Load(Reader const & r) { size_t pos = 0; uint32_t size, ingoingSize; r.Read(pos, &ingoingSize, sizeof(ingoingSize)); pos += sizeof(ingoingSize); for (size_t i = 0; i < ingoingSize; ++i) { IngoingCrossNode node; pos = node.Load(r, pos, i); m_ingoingIndex.Add(node); } r.Read(pos, &size, sizeof(size)); pos += sizeof(size); m_outgoingNodes.resize(size); for (size_t i = 0; i < size; ++i) pos = m_outgoingNodes[i].Load(r, pos, i); size_t adjacencySize = ingoingSize * m_outgoingNodes.size(); size_t const adjMatrixSize = sizeof(TWrittenEdgeWeight) * adjacencySize; m_adjacencyMatrix.resize(adjacencySize); r.Read(pos, &m_adjacencyMatrix[0], adjMatrixSize); pos += adjMatrixSize; uint32_t strsize; r.Read(pos, &strsize, sizeof(strsize)); pos += sizeof(strsize); for (uint32_t i = 0; i < strsize; ++i) { r.Read(pos, &size, sizeof(size)); pos += sizeof(size); vector<char> buffer(size); r.Read(pos, &buffer[0], size); m_neighborMwmList.push_back(string(&buffer[0], size)); pos += size; } }
Result CheckKeyUsage(EndEntityOrCA endEntityOrCA, const Input* encodedKeyUsage, KeyUsage requiredKeyUsageIfPresent) { if (!encodedKeyUsage) { // TODO(bug 970196): Reject certificates that are being used to verify // certificate signatures unless the certificate is a trust anchor, to // reduce the chances of an end-entity certificate being abused as a CA // certificate. // if (endEntityOrCA == EndEntityOrCA::MustBeCA && !isTrustAnchor) { // return Result::ERROR_INADEQUATE_KEY_USAGE; // } // // TODO: Users may configure arbitrary certificates as trust anchors, not // just roots. We should only allow a certificate without a key usage to be // used as a CA when it is self-issued and self-signed. return Success; } Reader input(*encodedKeyUsage); Reader value; if (der::ExpectTagAndGetValue(input, der::BIT_STRING, value) != Success) { return Result::ERROR_INADEQUATE_KEY_USAGE; } uint8_t numberOfPaddingBits; if (value.Read(numberOfPaddingBits) != Success) { return Result::ERROR_INADEQUATE_KEY_USAGE; } if (numberOfPaddingBits > 7) { return Result::ERROR_INADEQUATE_KEY_USAGE; } uint8_t bits; if (value.Read(bits) != Success) { // Reject empty bit masks. return Result::ERROR_INADEQUATE_KEY_USAGE; } // The most significant bit is numbered 0 (digitalSignature) and the least // significant bit is numbered 7 (encipherOnly), and the padding is in the // least significant bits of the last byte. The numbering of bits in a byte // is backwards from how we usually interpret them. // // For example, let's say bits is encoded in one byte with of value 0xB0 and // numberOfPaddingBits == 4. Then, bits is 10110000 in binary: // // bit 0 bit 3 // | | // v v // 10110000 // ^^^^ // | // 4 padding bits // // Since bits is the last byte, we have to consider the padding by ensuring // that the least significant 4 bits are all zero, since DER rules require // all padding bits to be zero. Then we have to look at the bit N bits to the // right of the most significant bit, where N is a value from the KeyUsage // enumeration. // // Let's say we're interested in the keyCertSign (5) bit. We'd need to look // at bit 5, which is zero, so keyCertSign is not asserted. (Since we check // that the padding is all zeros, it is OK to read from the padding bits.) // // Let's say we're interested in the digitalSignature (0) bit. We'd need to // look at the bit 0 (the most significant bit), which is set, so that means // digitalSignature is asserted. Similarly, keyEncipherment (2) and // dataEncipherment (3) are asserted. // // Note that since the KeyUsage enumeration is limited to values 0-7, we // only ever need to examine the first byte test for // requiredKeyUsageIfPresent. if (requiredKeyUsageIfPresent != KeyUsage::noParticularKeyUsageRequired) { // Check that the required key usage bit is set. if ((bits & KeyUsageToBitMask(requiredKeyUsageIfPresent)) == 0) { return Result::ERROR_INADEQUATE_KEY_USAGE; } } if (endEntityOrCA != EndEntityOrCA::MustBeCA) { // RFC 5280 says "The keyCertSign bit is asserted when the subject public // key is used for verifying signatures on public key certificates. If the // keyCertSign bit is asserted, then the cA bit in the basic constraints // extension (Section 4.2.1.9) MUST also be asserted." if ((bits & KeyUsageToBitMask(KeyUsage::keyCertSign)) != 0) { return Result::ERROR_INADEQUATE_KEY_USAGE; } } // The padding applies to the last byte, so skip to the last byte. while (!value.AtEnd()) { if (value.Read(bits) != Success) { return Result::ERROR_INADEQUATE_KEY_USAGE; } } // All of the padding bits must be zero, according to DER rules. uint8_t paddingMask = static_cast<uint8_t>((1 << numberOfPaddingBits) - 1); if ((bits & paddingMask) != 0) { return Result::ERROR_INADEQUATE_KEY_USAGE; } return Success; }
static VALUE danbooru_resize_image(VALUE module, VALUE file_ext_val, VALUE read_path_val, VALUE write_path_val, VALUE output_width_val, VALUE output_height_val, VALUE output_quality_val) { const char * file_ext = StringValueCStr(file_ext_val); const char * read_path = StringValueCStr(read_path_val); const char * write_path = StringValueCStr(write_path_val); int output_width = NUM2INT(output_width_val); int output_height = NUM2INT(output_height_val); int output_quality = NUM2INT(output_quality_val); FILE *read_file = fopen(read_path, "rb"); if(read_file == NULL) rb_raise(rb_eIOError, "can't open %s\n", read_path); FILE *write_file = fopen(write_path, "wb"); if(write_file == NULL) { fclose(read_file); rb_raise(rb_eIOError, "can't open %s\n", write_path); } bool ret = false; char error[1024]; JPEGCompressor *Compressor = NULL; Resizer *resizer = NULL; Reader *Reader = NULL; if (!strcmp(file_ext, "jpg") || !strcmp(file_ext, "jpeg")) Reader = new JPEG; else if (!strcmp(file_ext, "gif")) Reader = new GIF; else if (!strcmp(file_ext, "png")) Reader = new PNG; else { strcpy(error, "unknown filetype"); goto cleanup; } Compressor = new JPEGCompressor(write_file); if(Compressor == NULL) { strcpy(error, "out of memory"); goto cleanup; } resizer = new Resizer(Compressor); if(resizer == NULL || Reader == NULL) { strcpy(error, "out of memory"); goto cleanup; } resizer->SetDest(output_width, output_height, output_quality); ret = Reader->Read(read_file, resizer, error); cleanup: delete Reader; delete resizer; delete Compressor; fclose(read_file); fclose(write_file); if(!ret) rb_raise(rb_eException, "%s", error); return INT2FIX(0); }
// We parse GeneralizedTime and UTCTime according to RFC 5280 and we do not // accept all time formats allowed in the ASN.1 spec. That is, // GeneralizedTime must always be in the format YYYYMMDDHHMMSSZ and UTCTime // must always be in the format YYMMDDHHMMSSZ. Timezone formats of the form // +HH:MM or -HH:MM or NOT accepted. Result TimeChoice(Reader& tagged, uint8_t expectedTag, /*out*/ Time& time) { unsigned int days; Reader input; Result rv = ExpectTagAndGetValue(tagged, expectedTag, input); if (rv != Success) { return rv; } unsigned int yearHi; unsigned int yearLo; if (expectedTag == GENERALIZED_TIME) { rv = ReadTwoDigits(input, 0, 99, yearHi); if (rv != Success) { return rv; } rv = ReadTwoDigits(input, 0, 99, yearLo); if (rv != Success) { return rv; } } else if (expectedTag == UTCTime) { rv = ReadTwoDigits(input, 0, 99, yearLo); if (rv != Success) { return rv; } yearHi = yearLo >= 50u ? 19u : 20u; } else { return NotReached("invalid tag given to TimeChoice", Result::ERROR_INVALID_TIME); } unsigned int year = (yearHi * 100u) + yearLo; if (year < 1970u) { // We don't support dates before January 1, 1970 because that is the epoch. return Result::ERROR_INVALID_TIME; } days = DaysBeforeYear(year); unsigned int month; rv = ReadTwoDigits(input, 1u, 12u, month); if (rv != Success) { return rv; } unsigned int daysInMonth; static const unsigned int jan = 31u; const unsigned int feb = ((year % 4u == 0u) && ((year % 100u != 0u) || (year % 400u == 0u))) ? 29u : 28u; static const unsigned int mar = 31u; static const unsigned int apr = 30u; static const unsigned int may = 31u; static const unsigned int jun = 30u; static const unsigned int jul = 31u; static const unsigned int aug = 31u; static const unsigned int sep = 30u; static const unsigned int oct = 31u; static const unsigned int nov = 30u; static const unsigned int dec = 31u; switch (month) { case 1: daysInMonth = jan; break; case 2: daysInMonth = feb; days += jan; break; case 3: daysInMonth = mar; days += jan + feb; break; case 4: daysInMonth = apr; days += jan + feb + mar; break; case 5: daysInMonth = may; days += jan + feb + mar + apr; break; case 6: daysInMonth = jun; days += jan + feb + mar + apr + may; break; case 7: daysInMonth = jul; days += jan + feb + mar + apr + may + jun; break; case 8: daysInMonth = aug; days += jan + feb + mar + apr + may + jun + jul; break; case 9: daysInMonth = sep; days += jan + feb + mar + apr + may + jun + jul + aug; break; case 10: daysInMonth = oct; days += jan + feb + mar + apr + may + jun + jul + aug + sep; break; case 11: daysInMonth = nov; days += jan + feb + mar + apr + may + jun + jul + aug + sep + oct; break; case 12: daysInMonth = dec; days += jan + feb + mar + apr + may + jun + jul + aug + sep + oct + nov; break; default: return NotReached("month already bounds-checked by ReadTwoDigits", Result::FATAL_ERROR_INVALID_STATE); } unsigned int dayOfMonth; rv = ReadTwoDigits(input, 1u, daysInMonth, dayOfMonth); if (rv != Success) { return rv; } days += dayOfMonth - 1; unsigned int hours; rv = ReadTwoDigits(input, 0u, 23u, hours); if (rv != Success) { return rv; } unsigned int minutes; rv = ReadTwoDigits(input, 0u, 59u, minutes); if (rv != Success) { return rv; } unsigned int seconds; rv = ReadTwoDigits(input, 0u, 59u, seconds); if (rv != Success) { return rv; } uint8_t b; if (input.Read(b) != Success) { return Result::ERROR_INVALID_TIME; } if (b != 'Z') { return Result::ERROR_INVALID_TIME; } if (End(input) != Success) { return Result::ERROR_INVALID_TIME; } uint64_t totalSeconds = (static_cast<uint64_t>(days) * 24u * 60u * 60u) + (static_cast<uint64_t>(hours) * 60u * 60u) + (static_cast<uint64_t>(minutes) * 60u) + seconds; time = TimeFromElapsedSecondsAD(totalSeconds); return Success; }