Coverage Report

Created: 2026-05-16 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnutls/lib/x509/virt-san.c
Line
Count
Source
1
/*
2
 * Copyright (C) 2015-2016 Nikos Mavrogiannopoulos
3
 * Copyright (C) 2015-2016 Red Hat, Inc.
4
 *
5
 * This file is part of GnuTLS.
6
 *
7
 * The GnuTLS is free software; you can redistribute it and/or
8
 * modify it under the terms of the GNU Lesser General Public License
9
 * as published by the Free Software Foundation; either version 2.1 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * This library is distributed in the hope that it will be useful, but
13
 * WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
19
 *
20
 */
21
22
/* This file contains functions to handle the virtual subject alternative names,
23
 * based on othernames, such as GNUTLS_SAN_OTHERNAME_XMPP.
24
 */
25
26
#include "gnutls_int.h"
27
#include "x509_int.h"
28
#include "x509_ext_int.h"
29
#include "common.h"
30
#include "krb5.h"
31
#include "virt-san.h"
32
33
static int san_othername_to_virtual(const char *oid, size_t size)
34
0
{
35
0
  if (oid) {
36
0
    if ((unsigned)size == (sizeof(XMPP_OID) - 1) &&
37
0
        memcmp(oid, XMPP_OID, sizeof(XMPP_OID) - 1) == 0)
38
0
      return GNUTLS_SAN_OTHERNAME_XMPP;
39
0
    else if ((unsigned)size == (sizeof(KRB5_PRINCIPAL_OID) - 1) &&
40
0
       memcmp(oid, KRB5_PRINCIPAL_OID,
41
0
        sizeof(KRB5_PRINCIPAL_OID) - 1) == 0)
42
0
      return GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL;
43
0
    else if ((unsigned)size ==
44
0
         (sizeof(MSUSER_PRINCIPAL_NAME_OID) - 1) &&
45
0
       memcmp(oid, MSUSER_PRINCIPAL_NAME_OID,
46
0
        sizeof(MSUSER_PRINCIPAL_NAME_OID) - 1) == 0)
47
0
      return GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL;
48
0
    else if ((unsigned)size == (sizeof(SRV_OID) - 1) &&
49
0
       memcmp(oid, SRV_OID, sizeof(SRV_OID) - 1) == 0)
50
0
      return GNUTLS_SAN_OTHERNAME_SRV;
51
0
  }
52
53
0
  return GNUTLS_SAN_OTHERNAME;
54
0
}
55
56
static const char *virtual_to_othername_oid(unsigned type)
57
0
{
58
0
  switch (type) {
59
0
  case GNUTLS_SAN_OTHERNAME_XMPP:
60
0
    return XMPP_OID;
61
0
  case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
62
0
    return KRB5_PRINCIPAL_OID;
63
0
  case GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL:
64
0
    return MSUSER_PRINCIPAL_NAME_OID;
65
0
  case GNUTLS_SAN_OTHERNAME_SRV:
66
0
    return SRV_OID;
67
0
  default:
68
0
    return NULL;
69
0
  }
70
0
}
71
72
int _gnutls_alt_name_assign_virt_type(struct name_st *name, unsigned type,
73
              gnutls_datum_t *san,
74
              const char *othername_oid, unsigned raw)
75
0
{
76
0
  gnutls_datum_t encoded = { NULL, 0 };
77
0
  gnutls_datum_t xmpp = { NULL, 0 };
78
0
  int ret;
79
80
0
  if (type < 1000) {
81
0
    name->type = type;
82
0
    ret = _gnutls_alt_name_process(&name->san, type, san, raw);
83
0
    if (ret < 0)
84
0
      return gnutls_assert_val(ret);
85
0
    gnutls_free(san->data);
86
87
0
    if (othername_oid) {
88
0
      name->othername_oid.data = (uint8_t *)othername_oid;
89
0
      name->othername_oid.size = strlen(othername_oid);
90
0
    } else {
91
0
      name->othername_oid.data = NULL;
92
0
      name->othername_oid.size = 0;
93
0
    }
94
0
  } else { /* virtual types */
95
0
    const char *oid = virtual_to_othername_oid(type);
96
97
0
    if (oid == NULL)
98
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
99
100
0
    switch (type) {
101
0
    case GNUTLS_SAN_OTHERNAME_XMPP:
102
103
0
      ret = gnutls_idna_map((char *)san->data, san->size,
104
0
                &xmpp, 0);
105
0
      if (ret < 0)
106
0
        return gnutls_assert_val(ret);
107
108
0
      ret = _gnutls_x509_encode_string(ASN1_ETYPE_UTF8_STRING,
109
0
               xmpp.data, xmpp.size,
110
0
               &encoded);
111
112
0
      gnutls_free(xmpp.data);
113
0
      if (ret < 0)
114
0
        return gnutls_assert_val(ret);
115
116
0
      name->san = _gnutls_take_datum(&encoded);
117
0
      break;
118
119
0
    case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
120
0
      ret = _gnutls_krb5_principal_to_der((char *)san->data,
121
0
                  &name->san);
122
0
      if (ret < 0)
123
0
        return gnutls_assert_val(ret);
124
0
      break;
125
126
0
    case GNUTLS_SAN_OTHERNAME_SRV:
127
0
      ret = _gnutls_x509_encode_string(ASN1_ETYPE_IA5_STRING,
128
0
               san->data, san->size,
129
0
               &encoded);
130
0
      if (ret < 0)
131
0
        return gnutls_assert_val(ret);
132
0
      name->san = _gnutls_take_datum(&encoded);
133
0
      break;
134
135
0
    default:
136
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
137
0
    }
138
0
    ret = _gnutls_set_strdatum(&name->othername_oid, oid,
139
0
             strlen(oid));
140
0
    if (ret < 0) {
141
0
      gnutls_assert();
142
0
      _gnutls_free_datum(&name->san);
143
0
      return ret;
144
0
    }
145
0
    name->type = GNUTLS_SAN_OTHERNAME;
146
147
0
    gnutls_free(san->data);
148
0
  }
149
150
0
  return 0;
151
0
}
152
153
/**
154
 * gnutls_x509_othername_to_virtual:
155
 * @oid: The othername object identifier
156
 * @othername: The othername data
157
 * @virt_type: GNUTLS_SAN_OTHERNAME_XXX
158
 * @virt: allocated printable data
159
 *
160
 * This function will parse and convert the othername data to a virtual
161
 * type supported by gnutls.
162
 *
163
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
164
 *
165
 * Since: 3.3.8
166
 **/
167
int gnutls_x509_othername_to_virtual(const char *oid,
168
             const gnutls_datum_t *othername,
169
             unsigned int *virt_type,
170
             gnutls_datum_t *virt)
171
0
{
172
0
  int ret;
173
0
  unsigned type;
174
175
0
  type = san_othername_to_virtual(oid, strlen(oid));
176
0
  if (type == GNUTLS_SAN_OTHERNAME)
177
0
    return gnutls_assert_val(GNUTLS_E_X509_UNKNOWN_SAN);
178
179
0
  if (virt_type)
180
0
    *virt_type = type;
181
182
0
  switch (type) {
183
0
  case GNUTLS_SAN_OTHERNAME_XMPP:
184
0
    ret = _gnutls_x509_decode_string(ASN1_ETYPE_UTF8_STRING,
185
0
             othername->data,
186
0
             othername->size, virt, 0);
187
0
    if (ret < 0) {
188
0
      gnutls_assert();
189
0
      return ret;
190
0
    }
191
0
    return 0;
192
0
  case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
193
0
    ret = _gnutls_krb5_der_to_principal(othername, virt);
194
0
    if (ret < 0) {
195
0
      gnutls_assert();
196
0
      return ret;
197
0
    }
198
0
    return 0;
199
0
  case GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL:
200
0
    ret = _gnutls_x509_decode_string(ASN1_ETYPE_UTF8_STRING,
201
0
             othername->data,
202
0
             othername->size, virt, 0);
203
0
    if (ret < 0) {
204
0
      gnutls_assert();
205
0
      return ret;
206
0
    }
207
0
    return 0;
208
0
  case GNUTLS_SAN_OTHERNAME_SRV:
209
0
    ret = _gnutls_x509_decode_string(ASN1_ETYPE_IA5_STRING,
210
0
             othername->data,
211
0
             othername->size, virt, 0);
212
0
    if (ret < 0) {
213
0
      gnutls_assert();
214
0
      return ret;
215
0
    }
216
0
    return 0;
217
0
  default:
218
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
219
0
  }
220
0
}