| // Copyright 2021 Google LLC |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| // use this file except in compliance with the License. You may obtain a copy of |
| // the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| // License for the specific language governing permissions and limitations under |
| // the License. |
| |
| #ifndef DICE_CBOR_READER_H_ |
| #define DICE_CBOR_READER_H_ |
| |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| struct CborIn { |
| const uint8_t* buffer; |
| size_t buffer_size; |
| size_t cursor; |
| }; |
| |
| enum CborReadResult { |
| CBOR_READ_RESULT_OK, |
| // The end of the input was reached before the token was fully read. |
| CBOR_READ_RESULT_END, |
| // A malformed or unsupported token was found. |
| CBOR_READ_RESULT_MALFORMED, |
| // The requested token was not found. |
| CBOR_READ_RESULT_NOT_FOUND, |
| }; |
| |
| // Initializes an input stream for reading CBOR tokens. |
| static inline void CborInInit(const uint8_t* buffer, size_t buffer_size, |
| struct CborIn* in) { |
| in->buffer = buffer; |
| in->buffer_size = buffer_size; |
| in->cursor = 0; |
| } |
| |
| // Returns the number of bytes that have been read from the input. |
| static inline size_t CborInOffset(const struct CborIn* in) { |
| return in->cursor; |
| } |
| |
| // Returns whether the input stream has been fully consumed. |
| static inline bool CborInAtEnd(const struct CborIn* in) { |
| return in->cursor == in->buffer_size; |
| } |
| |
| // These functions read simple CBOR tokens from the input stream. Interpreting |
| // the greater structure of the data left to the caller and it is expected that |
| // these functions are just being used to validate and extract data from a known |
| // structure. |
| enum CborReadResult CborReadInt(struct CborIn* in, int64_t* val); |
| enum CborReadResult CborReadUint(struct CborIn* in, uint64_t* val); |
| enum CborReadResult CborReadBstr(struct CborIn* in, size_t* data_size, |
| const uint8_t** data); |
| enum CborReadResult CborReadTstr(struct CborIn* in, size_t* size, |
| const char** str); |
| enum CborReadResult CborReadArray(struct CborIn* in, size_t* num_elements); |
| enum CborReadResult CborReadMap(struct CborIn* in, size_t* num_pairs); |
| enum CborReadResult CborReadFalse(struct CborIn* in); |
| enum CborReadResult CborReadTrue(struct CborIn* in); |
| enum CborReadResult CborReadNull(struct CborIn* in); |
| // Returns CBOR_READ_RESULT_OK even if the value read does not correspond to |
| // a valid tag. See https://www.iana.org/assignments/cbor-tags/cbor-tags.xhtml |
| // for a registry of reserved and invalid tag values. |
| enum CborReadResult CborReadTag(struct CborIn* in, uint64_t* tag); |
| |
| // Skips over the next CBOR item in the input. The item may contain nested |
| // items, in the case of an array, map, or tag, and this function will attempt |
| // to descend and skip all nested items in order to skip the parent item. There |
| // is a limit on the level of nesting, after which this function will fail with |
| // CBOR_READ_RESULT_MALFORMED. |
| #define CBOR_READ_SKIP_STACK_SIZE 10 |
| enum CborReadResult CborReadSkip(struct CborIn* in); |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #endif // DICE_CBOR_READER_H_ |