blob: a34528fb3eb756c1aa34b048e6198441fd0e308f [file] [edit]
// 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_