| // Copyright 2026 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 THIRD_PARTY_CREDENTIO_CRYPTO_DEFAULT_CMS_CMS_PARSER_H_ | |
| #define THIRD_PARTY_CREDENTIO_CRYPTO_DEFAULT_CMS_CMS_PARSER_H_ | |
| #include <cstddef> | |
| #include <string> | |
| #include <utility> | |
| #include <vector> | |
| #include "crypto/default/cms/cms_error_code.h" | |
| #include "openssl/bytestring.h" | |
| namespace credentio_cms { | |
| // Class making sure that the CRYPTO ByteString used are always initialized. | |
| class ByteString { | |
| public: | |
| ByteString() { CBS_init(&cbs_, nullptr, 0); } | |
| CBS* cbs_ptr() { return &cbs_; } | |
| const CBS* cbs_ptr() const { return &cbs_; } | |
| const CBS& cbs() const { return cbs_; } | |
| private: | |
| CBS cbs_; | |
| }; | |
| // https://tools.ietf.org/html/rfc5280#section-4.1.1.2 | |
| struct AlgorithmIdentifier { | |
| ByteString algorithm_oid; | |
| ByteString parameter; | |
| // The un-parsed bytes so that d2i_X509_ALGOR can be used. | |
| ByteString raw_value; | |
| }; | |
| // https://tools.ietf.org/html/rfc5652#section-6.2.2 | |
| struct OriginatorIdentifierOrKey { | |
| // The issuer name and serial numbers are used if the subject_key_identifier | |
| // is not set. | |
| ByteString issuer_name; | |
| ByteString serial_number; | |
| ByteString subject_key_identifier; | |
| AlgorithmIdentifier public_key_algorithm; | |
| ByteString public_key_value; | |
| }; | |
| // https://tools.ietf.org/html/rfc5652#section-6.2.2 | |
| struct RecipientEncryptedKey { | |
| // The issuer name and serial numbers are used if the subject_key_identifier | |
| // is not set. | |
| ByteString issuer_name; | |
| ByteString serial_number; | |
| ByteString subject_key_identifier; | |
| // Optional | |
| ByteString date; | |
| // Optional OtherKeyAttribute from the RecipientKeyIdentifier. | |
| ByteString other; | |
| ByteString encrypted_key; | |
| }; | |
| // https://tools.ietf.org/html/rfc5652#section-5.3 | |
| // Signed or unsigned attribute. | |
| struct Attribute { | |
| ByteString type; | |
| std::vector<ByteString> values; | |
| }; | |
| // https://tools.ietf.org/html/rfc5751#section-2.5.3 | |
| struct SmimeEncryptionKeyPreference { | |
| // If the SMIMEEncryptionKeyPreference is not present all the fields will be | |
| // empty. | |
| ByteString issuer_name; | |
| ByteString serial_number; | |
| ByteString subject_key_identifier; | |
| // Optional | |
| ByteString date; | |
| // Optional OtherKeyAttribute from the RecipientKeyIdentifier. | |
| ByteString other; | |
| }; | |
| struct SignerInfo { | |
| int version; | |
| // The issuer name and serial numbers are used if the subject_key_identifier | |
| // is not set. | |
| ByteString issuer_name; | |
| ByteString serial_number; | |
| ByteString subject_key_identifier; | |
| AlgorithmIdentifier digest_algorithm; | |
| ByteString raw_signed_attributes; | |
| ByteString raw_unsigned_attributes; | |
| // The 'message_digest' and 'content_type_signed' fields are extracted from | |
| // the signed attributes (if present). | |
| ByteString message_digest; | |
| ByteString content_type_signed; | |
| // All the signed attributes other than message digest and content type. | |
| std::vector<Attribute> signed_attributes; | |
| std::vector<Attribute> unsigned_attributes; | |
| AlgorithmIdentifier signature_algorithm; | |
| ByteString signature_value; | |
| SmimeEncryptionKeyPreference encryption_key_preference; | |
| }; | |
| // https://tools.ietf.org/html/rfc5652#section-6.2.1 | |
| struct RecipientInfo { | |
| int version; | |
| OriginatorIdentifierOrKey originator_identifier_or_key; | |
| // Used for some key agreement algorithms. | |
| ByteString user_keying_material; | |
| AlgorithmIdentifier key_encryption_algorithm; | |
| std::vector<RecipientEncryptedKey> encrypted_keys; | |
| }; | |
| // https://tools.ietf.org/html/rfc5652#section-11.1 | |
| enum class ContentType { | |
| // Using the last digit of the OID defined in RFC 2315 section 14 as the enum | |
| // value. | |
| DATA = 1, | |
| SIGNED_DATA = 2, | |
| ENVELOPED_DATA = 3, | |
| SIGNED_AND_ENVELOPED_DATA = 4, | |
| DIGESTED_DATA = 5, | |
| ENCRYPTED_DATA = 6 | |
| }; | |
| struct Content { | |
| enum ContentType type; | |
| int version; | |
| std::vector<AlgorithmIdentifier> digest_algorithms; | |
| // The encapsulated_content_info.type for signed data, | |
| // encrypted_content_info.type for enveloped data. | |
| ByteString content_type; | |
| // The content can be absent, for example in detached signatures, or it | |
| // can be in one or more chunks. | |
| std::vector<ByteString> content; | |
| // ASN.1 tag of the content (CBS_ASN1_OCTETSTRING, etc.) | |
| unsigned content_tag; | |
| // The byte stream offsets of the first content tag byte and the first byte | |
| // after the content. | |
| std::pair<size_t, size_t> content_offsets; | |
| // The encryption_algorithm_identifier and encryption_algorithm_iv are used | |
| // for enveloped data. | |
| AlgorithmIdentifier encryption_algorithm; | |
| std::vector<ByteString> certificates; | |
| std::vector<SignerInfo> signers; | |
| std::vector<RecipientInfo> recipients; | |
| }; | |
| // Zero copy CMS parser. | |
| // | |
| // - 'data' and 'size' should point to the binary data. This data must remain | |
| // valid as long | |
| // as 'contents' is used. | |
| // - 'contents' is a view into the data and is only valid if the function | |
| // returns ErrorCode::OK. | |
| ErrorCode ParseCms(const char* data, size_t size, Content* contents, | |
| std::string* error_message); | |
| } // namespace credentio_cms | |
| #endif // THIRD_PARTY_CREDENTIO_CRYPTO_DEFAULT_CMS_CMS_PARSER_H_ |