SignedCertificateTimestamp.cpp (2762B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "SignedCertificateTimestamp.h" 8 9 #include "CTUtils.h" 10 11 namespace mozilla { 12 namespace ct { 13 14 pkix::Result SignedCertificateTimestamp::DecodeExtensions() { 15 if (extensions.empty()) { 16 return pkix::Success; 17 } 18 19 // `extensions` is a sequence of Extension: 20 // struct { 21 // ExtensionType extension_type; 22 // opaque extension_data<0..2^16-1>; 23 // } Extension; 24 const size_t kExtensionDataLengthBytes = 2; 25 // Currently, the only supported extension type is `leaf_index`. Others are 26 // ignored. 27 // enum { 28 // leaf_index(0), (255) 29 // } ExtensionType; 30 const size_t kExtensionTypeLength = 1; 31 const uint8_t kExtensionTypeLeafIndex = 0; 32 33 pkix::Input input; 34 pkix::Result rv = input.Init(extensions.data(), extensions.size()); 35 if (rv != pkix::Success) { 36 return rv; 37 } 38 pkix::Reader reader(input); 39 while (!reader.AtEnd()) { 40 uint8_t extensionType; 41 rv = ReadUint<kExtensionTypeLength>(reader, extensionType); 42 if (rv != pkix::Success) { 43 return rv; 44 } 45 pkix::Input extensionData; 46 rv = ReadVariableBytes<kExtensionDataLengthBytes>(reader, extensionData); 47 if (rv != pkix::Success) { 48 return rv; 49 } 50 if (extensionType == kExtensionTypeLeafIndex) { 51 // Duplicate extensions are not allowed. 52 if (leafIndex.isSome()) { 53 return pkix::Result::ERROR_EXTENSION_VALUE_INVALID; 54 } 55 // A leaf index is a big-endian, unsigned 40-bit value. In other words, 56 // it is 5 8-bit bytes, like so: 57 // uint8 uint40[5]; 58 // uint40 LeafIndex; 59 const size_t kLeafIndexLength = 5; 60 uint64_t leafIndexValue; 61 pkix::Reader leafIndexReader(extensionData); 62 rv = ReadUint<kLeafIndexLength>(leafIndexReader, leafIndexValue); 63 if (rv != pkix::Success) { 64 return rv; 65 } 66 if (!leafIndexReader.AtEnd()) { 67 return pkix::Result::ERROR_EXTENSION_VALUE_INVALID; 68 } 69 leafIndex.emplace(leafIndexValue); 70 } 71 } 72 return pkix::Success; 73 } 74 75 void LogEntry::Reset() { 76 type = LogEntry::Type::X509; 77 leafCertificate.clear(); 78 issuerKeyHash.clear(); 79 tbsCertificate.clear(); 80 } 81 82 bool DigitallySigned::SignatureParametersMatch( 83 HashAlgorithm aHashAlgorithm, 84 SignatureAlgorithm aSignatureAlgorithm) const { 85 return (hashAlgorithm == aHashAlgorithm) && 86 (signatureAlgorithm == aSignatureAlgorithm); 87 } 88 89 } // namespace ct 90 } // namespace mozilla