Coverage Report

Created: 2026-03-31 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gss-ntlmssp/src/gss_signseal.c
Line
Count
Source
1
/* Copyright 2013 Simo Sorce <simo@samba.org>, see COPYING for license */
2
3
#include <errno.h>
4
#include <stdlib.h>
5
#include <string.h>
6
#include <time.h>
7
8
#include "gssapi_ntlmssp.h"
9
#include "gss_ntlmssp.h"
10
11
uint32_t gssntlm_get_mic(uint32_t *minor_status,
12
                         gss_ctx_id_t context_handle,
13
                         gss_qop_t qop_req,
14
                         gss_buffer_t message_buffer,
15
                         gss_buffer_t message_token)
16
0
{
17
0
    struct gssntlm_ctx *ctx;
18
0
    struct ntlm_buffer message;
19
0
    struct ntlm_buffer signature;
20
0
    uint32_t retmaj, retmin;
21
22
0
    ctx = (struct gssntlm_ctx *)context_handle;
23
0
    retmaj = gssntlm_context_is_valid(ctx, NULL);
24
0
    if (retmaj != GSS_S_COMPLETE) {
25
0
        return GSSERRS(ERR_BADCTX, retmaj);
26
0
    }
27
0
    if (qop_req != GSS_C_QOP_DEFAULT) {
28
0
        return GSSERRS(ERR_BADARG, GSS_S_BAD_QOP);
29
0
    }
30
0
    if (!message_buffer->value || message_buffer->length == 0) {
31
0
        return GSSERRS(ERR_BADARG, GSS_S_CALL_INACCESSIBLE_READ);
32
0
    }
33
34
0
    message_token->value = malloc(NTLM_SIGNATURE_SIZE);
35
0
    if (!message_token->value) {
36
0
        return GSSERRS(ENOMEM, GSS_S_FAILURE);
37
0
    }
38
0
    message_token->length = NTLM_SIGNATURE_SIZE;
39
40
0
    message.data = message_buffer->value;
41
0
    message.length = message_buffer->length;
42
0
    signature.data = message_token->value;
43
0
    signature.length = message_token->length;
44
0
    retmin = ntlm_sign(ctx->neg_flags, NTLM_SEND,
45
0
                       &ctx->crypto_state,
46
0
                       &message, &signature);
47
0
    if (retmin) {
48
0
        safefree(message_token->value);
49
0
        return GSSERRS(retmin, GSS_S_FAILURE);
50
0
    }
51
52
0
    return GSSERRS(0, GSS_S_COMPLETE);
53
0
}
54
55
uint32_t gssntlm_verify_mic(uint32_t *minor_status,
56
                            gss_ctx_id_t context_handle,
57
                            gss_buffer_t message_buffer,
58
                            gss_buffer_t message_token,
59
                            gss_qop_t *qop_state)
60
0
{
61
0
    struct gssntlm_ctx *ctx;
62
0
    struct ntlm_buffer message;
63
0
    uint8_t token[16];
64
0
    struct ntlm_buffer signature = { token, NTLM_SIGNATURE_SIZE };
65
0
    uint32_t retmaj, retmin;
66
67
0
    ctx = (struct gssntlm_ctx *)context_handle;
68
0
    retmaj = gssntlm_context_is_valid(ctx, NULL);
69
0
    if (retmaj != GSS_S_COMPLETE) {
70
0
        return GSSERRS(ERR_BADCTX, retmaj);
71
0
    }
72
0
    if (!message_buffer->value || message_buffer->length == 0) {
73
0
        return GSSERRS(ERR_NOARG, GSS_S_CALL_INACCESSIBLE_READ);
74
0
    }
75
0
    if (qop_state) {
76
0
        *qop_state = GSS_C_QOP_DEFAULT;
77
0
    }
78
79
0
    message.data = message_buffer->value;
80
0
    message.length = message_buffer->length;
81
0
    retmin = ntlm_sign(ctx->neg_flags, NTLM_RECV,
82
0
                       &ctx->crypto_state,
83
0
                       &message, &signature);
84
0
    if (retmin) {
85
0
        return GSSERRS(retmin, GSS_S_FAILURE);
86
0
    }
87
88
0
    if (memcmp(signature.data,
89
0
               message_token->value, NTLM_SIGNATURE_SIZE) != 0) {
90
0
        return GSSERRS(0, GSS_S_BAD_SIG);
91
0
    }
92
93
0
    return GSSERRS(0, GSS_S_COMPLETE);
94
0
}
95
96
uint32_t gssntlm_wrap(uint32_t *minor_status,
97
                      gss_ctx_id_t context_handle,
98
                      int conf_req_flag,
99
                      gss_qop_t qop_req,
100
                      gss_buffer_t input_message_buffer,
101
                      int *conf_state,
102
                      gss_buffer_t output_message_buffer)
103
0
{
104
0
    struct gssntlm_ctx *ctx;
105
0
    struct ntlm_buffer message;
106
0
    struct ntlm_buffer output;
107
0
    struct ntlm_buffer signature;
108
0
    uint32_t retmaj, retmin;
109
110
0
    ctx = (struct gssntlm_ctx *)context_handle;
111
0
    retmaj = gssntlm_context_is_valid(ctx, NULL);
112
0
    if (retmaj != GSS_S_COMPLETE) {
113
0
        return GSSERRS(ERR_BADCTX, retmaj);
114
0
    }
115
0
    if (qop_req != GSS_C_QOP_DEFAULT) {
116
0
        return GSSERRS(ERR_BADARG, GSS_S_BAD_QOP);
117
0
    }
118
0
    if (!input_message_buffer->value || input_message_buffer->length == 0) {
119
0
        return GSSERRS(ERR_BADARG, GSS_S_CALL_INACCESSIBLE_READ);
120
0
    }
121
0
    if (conf_state) {
122
0
        *conf_state = 0;
123
0
    }
124
125
0
    if (conf_req_flag == 0) {
126
        /* ignore, always seal */
127
0
    }
128
129
0
    output_message_buffer->length =
130
0
        input_message_buffer->length + NTLM_SIGNATURE_SIZE;
131
0
    output_message_buffer->value = malloc(output_message_buffer->length);
132
0
    if (!output_message_buffer->value) {
133
0
        return GSSERRS(ENOMEM, GSS_S_FAILURE);
134
0
    }
135
136
0
    message.data = input_message_buffer->value;
137
0
    message.length = input_message_buffer->length;
138
0
    signature.data = output_message_buffer->value;
139
0
    signature.length = NTLM_SIGNATURE_SIZE;
140
0
    output.data = (uint8_t *)output_message_buffer->value + NTLM_SIGNATURE_SIZE;
141
0
    output.length = input_message_buffer->length;
142
0
    retmin = ntlm_seal(ctx->neg_flags, &ctx->crypto_state,
143
0
                       &message, &output, &signature);
144
0
    if (retmin) {
145
0
        safefree(output_message_buffer->value);
146
0
        return GSSERRS(retmin, GSS_S_FAILURE);
147
0
    }
148
149
0
    if (conf_state) {
150
0
        *conf_state = 1;
151
0
    }
152
0
    return GSSERRS(0, GSS_S_COMPLETE);
153
0
}
154
155
uint32_t gssntlm_unwrap(uint32_t *minor_status,
156
                        gss_ctx_id_t context_handle,
157
                        gss_buffer_t input_message_buffer,
158
                        gss_buffer_t output_message_buffer,
159
                        int *conf_state,
160
                        gss_qop_t *qop_state)
161
0
{
162
0
    struct gssntlm_ctx *ctx;
163
0
    struct ntlm_buffer message;
164
0
    struct ntlm_buffer output;
165
0
    uint8_t sig[16];
166
0
    struct ntlm_buffer signature = { sig, NTLM_SIGNATURE_SIZE };
167
0
    uint32_t retmaj, retmin;
168
169
0
    ctx = (struct gssntlm_ctx *)context_handle;
170
0
    retmaj = gssntlm_context_is_valid(ctx, NULL);
171
0
    if (retmaj != GSS_S_COMPLETE) {
172
0
        return GSSERRS(ERR_BADCTX, retmaj);
173
0
    }
174
0
    if (!input_message_buffer->value || input_message_buffer->length == 0) {
175
0
        return GSSERRS(ERR_BADARG, GSS_S_CALL_INACCESSIBLE_READ);
176
0
    }
177
0
    if (conf_state) {
178
0
        *conf_state = 0;
179
0
    }
180
0
    if (qop_state) {
181
0
        *qop_state = GSS_C_QOP_DEFAULT;
182
0
    }
183
184
0
    output_message_buffer->length =
185
0
        input_message_buffer->length - NTLM_SIGNATURE_SIZE;
186
0
    output_message_buffer->value = malloc(output_message_buffer->length);
187
0
    if (!output_message_buffer->value) {
188
0
        return GSSERRS(ENOMEM, GSS_S_FAILURE);
189
0
    }
190
191
0
    message.data = (uint8_t *)input_message_buffer->value + NTLM_SIGNATURE_SIZE;
192
0
    message.length = input_message_buffer->length - NTLM_SIGNATURE_SIZE;
193
0
    output.data = output_message_buffer->value;
194
0
    output.length = output_message_buffer->length;
195
0
    retmin = ntlm_unseal(ctx->neg_flags, &ctx->crypto_state,
196
0
                         &message, &output, &signature);
197
0
    if (retmin) {
198
0
        safefree(output_message_buffer->value);
199
0
        return GSSERRS(retmin, GSS_S_FAILURE);
200
0
    }
201
202
0
    if (memcmp(input_message_buffer->value,
203
0
               signature.data, NTLM_SIGNATURE_SIZE) != 0) {
204
0
        safefree(output_message_buffer->value);
205
0
        return GSSERRS(0, GSS_S_BAD_SIG);
206
0
    }
207
208
0
    if (conf_state) {
209
0
        *conf_state = 1;
210
0
    }
211
0
    return GSSERRS(0, GSS_S_COMPLETE);
212
0
}
213
214
uint32_t gssntlm_wrap_size_limit(uint32_t *minor_status,
215
                                 gss_ctx_id_t context_handle,
216
                                 int conf_req_flag,
217
                                 gss_qop_t qop_req,
218
                                 uint32_t req_output_size,
219
                                 uint32_t *max_input_size)
220
0
{
221
0
    struct gssntlm_ctx *ctx;
222
0
    uint32_t retmaj, retmin;
223
224
0
    ctx = (struct gssntlm_ctx *)context_handle;
225
0
    retmaj = gssntlm_context_is_valid(ctx, NULL);
226
0
    if (retmaj != GSS_S_COMPLETE) {
227
0
        return GSSERRS(ERR_BADCTX, retmaj);
228
0
    }
229
230
0
    if (qop_req != GSS_C_QOP_DEFAULT) {
231
0
        return GSSERRS(ERR_BADARG, GSS_S_BAD_QOP);
232
0
    }
233
234
0
    if (req_output_size < 16) {
235
0
        *max_input_size = 0;
236
0
    } else {
237
0
        *max_input_size = req_output_size - NTLM_SIGNATURE_SIZE;
238
0
    }
239
240
0
    return GSSERRS(0, GSS_S_COMPLETE);
241
0
}