Coverage Report

Created: 2025-03-18 06:55

/src/gnutls/lib/x509/virt-san.c
Line
Count
Source (jump to first uncovered line)
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
  }
49
50
0
  return GNUTLS_SAN_OTHERNAME;
51
0
}
52
53
static const char *virtual_to_othername_oid(unsigned type)
54
0
{
55
0
  switch (type) {
56
0
  case GNUTLS_SAN_OTHERNAME_XMPP:
57
0
    return XMPP_OID;
58
0
  case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
59
0
    return KRB5_PRINCIPAL_OID;
60
0
  case GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL:
61
0
    return MSUSER_PRINCIPAL_NAME_OID;
62
0
  default:
63
0
    return NULL;
64
0
  }
65
0
}
66
67
int _gnutls_alt_name_assign_virt_type(struct name_st *name, unsigned type,
68
              gnutls_datum_t *san,
69
              const char *othername_oid, unsigned raw)
70
0
{
71
0
  gnutls_datum_t encoded = { NULL, 0 };
72
0
  gnutls_datum_t xmpp = { NULL, 0 };
73
0
  int ret;
74
75
0
  if (type < 1000) {
76
0
    name->type = type;
77
0
    ret = _gnutls_alt_name_process(&name->san, type, san, raw);
78
0
    if (ret < 0)
79
0
      return gnutls_assert_val(ret);
80
0
    gnutls_free(san->data);
81
82
0
    if (othername_oid) {
83
0
      name->othername_oid.data = (uint8_t *)othername_oid;
84
0
      name->othername_oid.size = strlen(othername_oid);
85
0
    } else {
86
0
      name->othername_oid.data = NULL;
87
0
      name->othername_oid.size = 0;
88
0
    }
89
0
  } else { /* virtual types */
90
0
    const char *oid = virtual_to_othername_oid(type);
91
92
0
    if (oid == NULL)
93
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
94
95
0
    switch (type) {
96
0
    case GNUTLS_SAN_OTHERNAME_XMPP:
97
98
0
      ret = gnutls_idna_map((char *)san->data, san->size,
99
0
                &xmpp, 0);
100
0
      if (ret < 0)
101
0
        return gnutls_assert_val(ret);
102
103
0
      ret = _gnutls_x509_encode_string(ASN1_ETYPE_UTF8_STRING,
104
0
               xmpp.data, xmpp.size,
105
0
               &encoded);
106
107
0
      gnutls_free(xmpp.data);
108
0
      if (ret < 0)
109
0
        return gnutls_assert_val(ret);
110
111
0
      name->type = GNUTLS_SAN_OTHERNAME;
112
0
      name->san.data = encoded.data;
113
0
      name->san.size = encoded.size;
114
0
      name->othername_oid.data = (void *)gnutls_strdup(oid);
115
0
      name->othername_oid.size = strlen(oid);
116
0
      break;
117
118
0
    case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
119
0
      ret = _gnutls_krb5_principal_to_der((char *)san->data,
120
0
                  &name->san);
121
0
      if (ret < 0)
122
0
        return gnutls_assert_val(ret);
123
124
0
      name->othername_oid.data = (void *)gnutls_strdup(oid);
125
0
      name->othername_oid.size = strlen(oid);
126
0
      name->type = GNUTLS_SAN_OTHERNAME;
127
0
      break;
128
129
0
    default:
130
0
      return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
131
0
    }
132
133
0
    gnutls_free(san->data);
134
0
  }
135
136
0
  return 0;
137
0
}
138
139
/**
140
 * gnutls_x509_othername_to_virtual:
141
 * @oid: The othername object identifier
142
 * @othername: The othername data
143
 * @virt_type: GNUTLS_SAN_OTHERNAME_XXX
144
 * @virt: allocated printable data
145
 *
146
 * This function will parse and convert the othername data to a virtual
147
 * type supported by gnutls.
148
 *
149
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a negative error value.
150
 *
151
 * Since: 3.3.8
152
 **/
153
int gnutls_x509_othername_to_virtual(const char *oid,
154
             const gnutls_datum_t *othername,
155
             unsigned int *virt_type,
156
             gnutls_datum_t *virt)
157
0
{
158
0
  int ret;
159
0
  unsigned type;
160
161
0
  type = san_othername_to_virtual(oid, strlen(oid));
162
0
  if (type == GNUTLS_SAN_OTHERNAME)
163
0
    return gnutls_assert_val(GNUTLS_E_X509_UNKNOWN_SAN);
164
165
0
  if (virt_type)
166
0
    *virt_type = type;
167
168
0
  switch (type) {
169
0
  case GNUTLS_SAN_OTHERNAME_XMPP:
170
0
    ret = _gnutls_x509_decode_string(ASN1_ETYPE_UTF8_STRING,
171
0
             othername->data,
172
0
             othername->size, virt, 0);
173
0
    if (ret < 0) {
174
0
      gnutls_assert();
175
0
      return ret;
176
0
    }
177
0
    return 0;
178
0
  case GNUTLS_SAN_OTHERNAME_KRB5PRINCIPAL:
179
0
    ret = _gnutls_krb5_der_to_principal(othername, virt);
180
0
    if (ret < 0) {
181
0
      gnutls_assert();
182
0
      return ret;
183
0
    }
184
0
    return 0;
185
0
  case GNUTLS_SAN_OTHERNAME_MSUSERPRINCIPAL:
186
0
    ret = _gnutls_x509_decode_string(ASN1_ETYPE_UTF8_STRING,
187
0
             othername->data,
188
0
             othername->size, virt, 0);
189
0
    if (ret < 0) {
190
0
      gnutls_assert();
191
0
      return ret;
192
0
    }
193
0
    return 0;
194
0
  default:
195
0
    return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR);
196
0
  }
197
0
}