xref: /openssl/crypto/asn1/a_type.c (revision 3c2bdd7d)
1 /*
2  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 #include <stdio.h>
11 #include "internal/cryptlib.h"
12 #include <openssl/asn1t.h>
13 #include <openssl/objects.h>
14 #include "asn1_local.h"
15 
ASN1_TYPE_get(const ASN1_TYPE * a)16 int ASN1_TYPE_get(const ASN1_TYPE *a)
17 {
18     if (a->type == V_ASN1_BOOLEAN
19             || a->type == V_ASN1_NULL
20             || a->value.ptr != NULL)
21         return a->type;
22     else
23         return 0;
24 }
25 
ASN1_TYPE_set(ASN1_TYPE * a,int type,void * value)26 void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
27 {
28     if (a->type != V_ASN1_BOOLEAN
29             && a->type != V_ASN1_NULL
30             && a->value.ptr != NULL) {
31         ASN1_TYPE **tmp_a = &a;
32         ossl_asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0);
33     }
34     a->type = type;
35     if (type == V_ASN1_BOOLEAN)
36         a->value.boolean = value ? 0xff : 0;
37     else
38         a->value.ptr = value;
39 }
40 
ASN1_TYPE_set1(ASN1_TYPE * a,int type,const void * value)41 int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
42 {
43     if (!value || (type == V_ASN1_BOOLEAN)) {
44         void *p = (void *)value;
45         ASN1_TYPE_set(a, type, p);
46     } else if (type == V_ASN1_OBJECT) {
47         ASN1_OBJECT *odup;
48         odup = OBJ_dup(value);
49         if (!odup)
50             return 0;
51         ASN1_TYPE_set(a, type, odup);
52     } else {
53         ASN1_STRING *sdup;
54         sdup = ASN1_STRING_dup(value);
55         if (!sdup)
56             return 0;
57         ASN1_TYPE_set(a, type, sdup);
58     }
59     return 1;
60 }
61 
62 /* Returns 0 if they are equal, != 0 otherwise. */
ASN1_TYPE_cmp(const ASN1_TYPE * a,const ASN1_TYPE * b)63 int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
64 {
65     int result = -1;
66 
67     if (!a || !b || a->type != b->type)
68         return -1;
69 
70     switch (a->type) {
71     case V_ASN1_OBJECT:
72         result = OBJ_cmp(a->value.object, b->value.object);
73         break;
74     case V_ASN1_BOOLEAN:
75         result = a->value.boolean - b->value.boolean;
76         break;
77     case V_ASN1_NULL:
78         result = 0;             /* They do not have content. */
79         break;
80     case V_ASN1_INTEGER:
81     case V_ASN1_ENUMERATED:
82     case V_ASN1_BIT_STRING:
83     case V_ASN1_OCTET_STRING:
84     case V_ASN1_SEQUENCE:
85     case V_ASN1_SET:
86     case V_ASN1_NUMERICSTRING:
87     case V_ASN1_PRINTABLESTRING:
88     case V_ASN1_T61STRING:
89     case V_ASN1_VIDEOTEXSTRING:
90     case V_ASN1_IA5STRING:
91     case V_ASN1_UTCTIME:
92     case V_ASN1_GENERALIZEDTIME:
93     case V_ASN1_GRAPHICSTRING:
94     case V_ASN1_VISIBLESTRING:
95     case V_ASN1_GENERALSTRING:
96     case V_ASN1_UNIVERSALSTRING:
97     case V_ASN1_BMPSTRING:
98     case V_ASN1_UTF8STRING:
99     case V_ASN1_OTHER:
100     default:
101         result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
102                                  (ASN1_STRING *)b->value.ptr);
103         break;
104     }
105 
106     return result;
107 }
108 
ASN1_TYPE_pack_sequence(const ASN1_ITEM * it,void * s,ASN1_TYPE ** t)109 ASN1_TYPE *ASN1_TYPE_pack_sequence(const ASN1_ITEM *it, void *s, ASN1_TYPE **t)
110 {
111     ASN1_OCTET_STRING *oct;
112     ASN1_TYPE *rt;
113 
114     oct = ASN1_item_pack(s, it, NULL);
115     if (oct == NULL)
116         return NULL;
117 
118     if (t && *t) {
119         rt = *t;
120     } else {
121         rt = ASN1_TYPE_new();
122         if (rt == NULL) {
123             ASN1_OCTET_STRING_free(oct);
124             return NULL;
125         }
126         if (t)
127             *t = rt;
128     }
129     ASN1_TYPE_set(rt, V_ASN1_SEQUENCE, oct);
130     return rt;
131 }
132 
ASN1_TYPE_unpack_sequence(const ASN1_ITEM * it,const ASN1_TYPE * t)133 void *ASN1_TYPE_unpack_sequence(const ASN1_ITEM *it, const ASN1_TYPE *t)
134 {
135     if (t == NULL || t->type != V_ASN1_SEQUENCE || t->value.sequence == NULL)
136         return NULL;
137     return ASN1_item_unpack(t->value.sequence, it);
138 }
139