Skip to content

Commit f4914f0

Browse files
committed
Add IA5String support to Asn1Value class
PiperOrigin-RevId: 341948242 Change-Id: I9650d014f36e21d573f2f97c2e25ebd5faf48b32
1 parent 49f94c7 commit f4914f0

File tree

4 files changed

+115
-1
lines changed

4 files changed

+115
-1
lines changed

asylo/crypto/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ cc_library(
187187
":bignum_util",
188188
"//asylo/crypto/util:bssl_util",
189189
"//asylo/crypto/util:byte_container_view",
190+
"//asylo/util:error_codes",
190191
"//asylo/util:logging",
191192
"//asylo/util:status",
192193
"@boringssl//:crypto",

asylo/crypto/asn1.cc

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,13 @@
3333
#include "absl/base/macros.h"
3434
#include "absl/strings/str_cat.h"
3535
#include "absl/strings/str_format.h"
36+
#include "absl/strings/string_view.h"
3637
#include "absl/types/optional.h"
3738
#include "absl/types/span.h"
3839
#include "asylo/crypto/util/bssl_util.h"
3940
#include "asylo/crypto/util/byte_container_view.h"
4041
#include "asylo/util/logging.h"
42+
#include "asylo/util/error_codes.h"
4143
#include "asylo/util/status.h"
4244
#include "asylo/util/status_macros.h"
4345
#include "asylo/util/statusor.h"
@@ -63,6 +65,8 @@ absl::optional<Asn1Type> FromOpensslType(int openssl_type) {
6365
return Asn1Type::kObjectId;
6466
case V_ASN1_SEQUENCE:
6567
return Asn1Type::kSequence;
68+
case V_ASN1_IA5STRING:
69+
return Asn1Type::kIA5String;
6670
default:
6771
return absl::nullopt;
6872
}
@@ -85,6 +89,8 @@ int ToOpensslType(Asn1Type type) {
8589
return V_ASN1_OBJECT;
8690
case Asn1Type::kSequence:
8791
return V_ASN1_SEQUENCE;
92+
case Asn1Type::kIA5String:
93+
return V_ASN1_IA5STRING;
8894
}
8995

9096
return V_ASN1_UNDEF;
@@ -397,6 +403,12 @@ StatusOr<Asn1Value> Asn1Value::CreateSequence(
397403
return result;
398404
}
399405

406+
StatusOr<Asn1Value> Asn1Value::CreateIA5String(absl::string_view value) {
407+
Asn1Value result;
408+
ASYLO_RETURN_IF_ERROR(result.SetIA5String(value));
409+
return result;
410+
}
411+
400412
StatusOr<Asn1Value> Asn1Value::CreateSequenceFromStatusOrs(
401413
absl::Span<const StatusOr<Asn1Value>> results) {
402414
Asn1Value result;
@@ -495,6 +507,14 @@ StatusOr<std::vector<Asn1Value>> Asn1Value::GetSequence() const {
495507
return result;
496508
}
497509

510+
StatusOr<std::string> Asn1Value::GetIA5String() const {
511+
ASYLO_RETURN_IF_ERROR(CheckIsType(Asn1Type::kIA5String));
512+
const ASN1_IA5STRING *str = value_->value.ia5string;
513+
514+
return std::string(reinterpret_cast<const char *>(ASN1_STRING_get0_data(str)),
515+
ASN1_STRING_length(str));
516+
}
517+
498518
Status Asn1Value::SetBoolean(bool value) { return SetBsslBoolean(value); }
499519

500520
Status Asn1Value::SetInteger(const BIGNUM &value) {
@@ -564,6 +584,21 @@ Status Asn1Value::SetSequence(absl::Span<const Asn1Value> elements) {
564584
return SetBsslSequence(*sequence);
565585
}
566586

587+
Status Asn1Value::SetIA5String(absl::string_view value) {
588+
bssl::UniquePtr<ASN1_IA5STRING> ia5_string(ASN1_IA5STRING_new());
589+
if (ia5_string == nullptr) {
590+
return Status(error::GoogleError::INTERNAL, BsslLastErrorString());
591+
}
592+
593+
if (ASN1_STRING_set(ia5_string.get(), value.data(), value.length()) != 1) {
594+
return Status(error::GoogleError::INTERNAL, BsslLastErrorString());
595+
}
596+
597+
ASN1_TYPE_set(value_.get(), V_ASN1_IA5STRING, ia5_string.release());
598+
599+
return Status::OkStatus();
600+
}
601+
567602
Status Asn1Value::SetSequenceFromStatusOrs(
568603
absl::Span<const StatusOr<Asn1Value>> results) {
569604
std::vector<Asn1Value> elements(results.size());
@@ -636,6 +671,13 @@ StatusOr<Asn1Value> Asn1Value::CreateSequenceFromBssl(
636671
return asn1;
637672
}
638673

674+
StatusOr<Asn1Value> Asn1Value::CreateIA5StringFromBssl(
675+
const ASN1_IA5STRING &bssl_value) {
676+
Asn1Value asn1;
677+
ASYLO_RETURN_IF_ERROR(asn1.SetBsslIA5String(bssl_value));
678+
return asn1;
679+
}
680+
639681
StatusOr<ASN1_BOOLEAN> Asn1Value::GetBsslBoolean() const {
640682
ASYLO_RETURN_IF_ERROR(CheckIsType(Asn1Type::kBoolean));
641683
return value_->value.boolean;
@@ -687,6 +729,12 @@ StatusOr<bssl::UniquePtr<ASN1_SEQUENCE_ANY>> Asn1Value::GetBsslSequence()
687729
return std::move(sequence);
688730
}
689731

732+
StatusOr<bssl::UniquePtr<ASN1_IA5STRING>> Asn1Value::GetBsslIA5String() const {
733+
ASYLO_RETURN_IF_ERROR(CheckIsType(Asn1Type::kIA5String));
734+
return bssl::UniquePtr<ASN1_IA5STRING>(
735+
CHECK_NOTNULL(ASN1_STRING_dup(value_->value.ia5string)));
736+
}
737+
690738
Status Asn1Value::SetBsslBoolean(ASN1_BOOLEAN bssl_value) {
691739
// A non-null pointer. Used when calling ASN1_TYPE_set() with V_ASN1_BOOLEAN.
692740
void *const kNonNullPointer = reinterpret_cast<void *>(true);
@@ -749,6 +797,13 @@ Status Asn1Value::SetBsslSequence(const ASN1_SEQUENCE_ANY &bssl_value) {
749797
return Status::OkStatus();
750798
}
751799

800+
Status Asn1Value::SetBsslIA5String(const ASN1_IA5STRING &bssl_value) {
801+
if (ASN1_TYPE_set1(value_.get(), V_ASN1_IA5STRING, &bssl_value) != 1) {
802+
return Status(error::GoogleError::INTERNAL, BsslLastErrorString());
803+
}
804+
return Status::OkStatus();
805+
}
806+
752807
Asn1Value::Asn1Value(bssl::UniquePtr<ASN1_TYPE> value)
753808
: value_(std::move(value)) {}
754809

@@ -794,6 +849,7 @@ bool operator==(const Asn1Value &lhs, const Asn1Value &rhs) {
794849
case Asn1Type::kBitString:
795850
case Asn1Type::kObjectId:
796851
case Asn1Type::kOctetString:
852+
case Asn1Type::kIA5String:
797853
return ASN1_TYPE_cmp(lhs.value_.get(), rhs.value_.get()) == 0;
798854
}
799855

asylo/crypto/asn1.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ enum class Asn1Type {
6363

6464
// SEQUENCE values are represented by arrays of Asn1Values.
6565
kSequence,
66+
67+
// IA5String values are represented by an ASCII string.
68+
kIA5String,
6669
};
6770

6871
// Represents an ASN.1 OBJECT IDENTIFIER. Each object identifier can be
@@ -153,6 +156,7 @@ class Asn1Value {
153156
static StatusOr<Asn1Value> CreateObjectId(const ObjectId &value);
154157
static StatusOr<Asn1Value> CreateSequence(
155158
absl::Span<const Asn1Value> elements);
159+
static StatusOr<Asn1Value> CreateIA5String(absl::string_view value);
156160

157161
// Factory methods for creating INTEGER and ENUMERATED values directly from
158162
// integral types.
@@ -199,6 +203,7 @@ class Asn1Value {
199203
StatusOr<std::vector<uint8_t>> GetOctetString() const;
200204
StatusOr<ObjectId> GetObjectId() const;
201205
StatusOr<std::vector<Asn1Value>> GetSequence() const;
206+
StatusOr<std::string> GetIA5String() const;
202207

203208
// Getters that get an INTEGER or ENUMERATED value directly as an integral
204209
// type.
@@ -224,6 +229,7 @@ class Asn1Value {
224229
Status SetOctetString(ByteContainerView value);
225230
Status SetObjectId(const ObjectId &value);
226231
Status SetSequence(absl::Span<const Asn1Value> elements);
232+
Status SetIA5String(absl::string_view value);
227233

228234
// Setters for setting an Asn1Value to be an INTEGER or ENUMERATED value from
229235
// an integral type.
@@ -264,6 +270,8 @@ class Asn1Value {
264270
const ASN1_OBJECT &bssl_value);
265271
static StatusOr<Asn1Value> CreateSequenceFromBssl(
266272
const ASN1_SEQUENCE_ANY &bssl_value);
273+
static StatusOr<Asn1Value> CreateIA5StringFromBssl(
274+
const ASN1_IA5STRING &bssl_value);
267275

268276
// Each "Bssl" getter returns the contained value in the appropriate BoringSSL
269277
// type. Fails if the Asn1Value does not have the appropriate type.
@@ -276,6 +284,7 @@ class Asn1Value {
276284
StatusOr<bssl::UniquePtr<ASN1_OCTET_STRING>> GetBsslOctetString() const;
277285
StatusOr<bssl::UniquePtr<ASN1_OBJECT>> GetBsslObjectId() const;
278286
StatusOr<bssl::UniquePtr<ASN1_SEQUENCE_ANY>> GetBsslSequence() const;
287+
StatusOr<bssl::UniquePtr<ASN1_IA5STRING>> GetBsslIA5String() const;
279288

280289
// Each "Bssl" setter sets the Asn1Value to have the appropriate type and the
281290
// given value. If a setter fails, then the value of the Asn1Value is
@@ -287,6 +296,7 @@ class Asn1Value {
287296
Status SetBsslOctetString(const ASN1_OCTET_STRING &bssl_value);
288297
Status SetBsslObjectId(const ASN1_OBJECT &bssl_value);
289298
Status SetBsslSequence(const ASN1_SEQUENCE_ANY &bssl_value);
299+
Status SetBsslIA5String(const ASN1_IA5STRING &bssl_value);
290300

291301
private:
292302
friend bool operator==(const Asn1Value &lhs, const Asn1Value &rhs);

asylo/crypto/asn1_test.cc

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,53 @@ class Asn1Test<Asn1TypeTag<Asn1Type::kSequence>> : public Test {
934934
}
935935
};
936936

937+
// Specialization of Asn1Test for Asn1Type::kIA5String.
938+
template <>
939+
class Asn1Test<Asn1TypeTag<Asn1Type::kIA5String>> : public Test {
940+
public:
941+
using ValueType = std::string;
942+
using BsslValueType = bssl::UniquePtr<ASN1_IA5STRING>;
943+
944+
static constexpr Asn1Type Type() { return Asn1Type::kIA5String; }
945+
946+
static std::vector<ValueType> TestData() {
947+
return {"", "t", "Test string.", "This is a test string.",
948+
"This has \0 null \0\0 characters"};
949+
}
950+
951+
static std::vector<std::vector<ValueType>> EqualTestData() { return {}; }
952+
953+
static std::vector<ValueType> BadTestData() { return {}; }
954+
955+
static void ExpectEqual(const ValueType &lhs, const ValueType &rhs) {
956+
EXPECT_THAT(lhs, Eq(rhs));
957+
}
958+
959+
static StatusOr<Asn1Value> Create(const ValueType &value) {
960+
return Asn1Value::CreateIA5String(value);
961+
}
962+
963+
static StatusOr<ValueType> Get(const Asn1Value &asn1) {
964+
return asn1.GetIA5String();
965+
}
966+
967+
static Status Set(Asn1Value *asn1, const ValueType &value) {
968+
return asn1->SetIA5String(value);
969+
}
970+
971+
static StatusOr<Asn1Value> CreateFromBssl(const BsslValueType &bssl_value) {
972+
return Asn1Value::CreateIA5StringFromBssl(*bssl_value);
973+
}
974+
975+
static StatusOr<BsslValueType> GetBssl(const Asn1Value &asn1) {
976+
return asn1.GetBsslIA5String();
977+
}
978+
979+
static Status SetBssl(Asn1Value *asn1, const BsslValueType &bssl_value) {
980+
return asn1->SetBsslIA5String(*bssl_value);
981+
}
982+
};
983+
937984
using Asn1TestingTypes = Types<
938985
Asn1TypeTag<Asn1Type::kBoolean>, Asn1TypeTag<Asn1Type::kInteger>,
939986
Asn1IntegerConversionTag<int8_t>, Asn1IntegerConversionTag<uint8_t>,
@@ -946,7 +993,7 @@ using Asn1TestingTypes = Types<
946993
Asn1EnumeratedConversionTag<uint32_t>, Asn1EnumeratedConversionTag<int64_t>,
947994
Asn1EnumeratedConversionTag<uint16_t>, Asn1TypeTag<Asn1Type::kBitString>,
948995
Asn1TypeTag<Asn1Type::kOctetString>, Asn1TypeTag<Asn1Type::kObjectId>,
949-
Asn1TypeTag<Asn1Type::kSequence>>;
996+
Asn1TypeTag<Asn1Type::kSequence>, Asn1TypeTag<Asn1Type::kIA5String>>;
950997
TYPED_TEST_SUITE(Asn1Test, Asn1TestingTypes);
951998

952999
// std::vector<Asn1ValueType<TestParam::value>>::const_reference is used for

0 commit comments

Comments
 (0)