2 * Copyright (c) 2008 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the Institute nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "gsskrb5_locl.h"
40 iov_allocate(OM_uint32
*minor_status
, gss_iov_buffer_desc
*iov
, int iov_count
)
44 for (i
= 0; i
< iov_count
; i
++) {
45 if (GSS_IOV_BUFFER_FLAGS(iov
[i
].type
) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE
){
46 void *ptr
= malloc(iov
[i
].buffer
.length
);
49 if (iov
[i
].buffer
.value
)
50 memcpy(ptr
, iov
[i
].buffer
.value
, iov
[i
].buffer
.length
);
51 iov
[i
].buffer
.value
= ptr
;
52 iov
[i
].type
|= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED
;
55 return GSS_S_COMPLETE
;
59 iov_map(OM_uint32
*minor_status
,
60 const gss_iov_buffer_desc
*iov
,
62 krb5_crypto_iov
*data
)
66 for (i
= 0; i
< iov_count
; i
++) {
67 switch(GSS_IOV_BUFFER_TYPE(iov
[i
].type
)) {
68 case GSS_IOV_BUFFER_TYPE_EMPTY
:
69 data
[i
].flags
= KRB5_CRYPTO_TYPE_EMPTY
;
71 case GSS_IOV_BUFFER_TYPE_DATA
:
72 data
[i
].flags
= KRB5_CRYPTO_TYPE_DATA
;
74 case GSS_IOV_BUFFER_TYPE_SIGN_ONLY
:
75 data
[i
].flags
= KRB5_CRYPTO_TYPE_SIGN_ONLY
;
77 case GSS_IOV_BUFFER_TYPE_HEADER
:
78 data
[i
].flags
= KRB5_CRYPTO_TYPE_HEADER
;
80 case GSS_IOV_BUFFER_TYPE_TRAILER
:
81 data
[i
].flags
= KRB5_CRYPTO_TYPE_TRAILER
;
83 case GSS_IOV_BUFFER_TYPE_PADDING
:
84 data
[i
].flags
= KRB5_CRYPTO_TYPE_PADDING
;
86 case GSS_IOV_BUFFER_TYPE_STREAM
:
90 *minor_status
= EINVAL
;
93 data
[i
].data
.data
= iov
[i
].buffer
.value
;
94 data
[i
].data
.length
= iov
[i
].buffer
.length
;
96 return GSS_S_COMPLETE
;
100 OM_uint32 GSSAPI_LIB_FUNCTION
101 _gk_wrap_iov(OM_uint32
* minor_status
,
102 gss_ctx_id_t context_handle
,
106 gss_iov_buffer_desc
*iov
,
110 return GSS_S_FAILURE
;
112 gsskrb5_ctx ctx
= (gsskrb5_ctx
) context_handle
;
113 krb5_context context
;
114 OM_uint32 major_status
, junk
;
115 krb5_crypto_iov
*data
;
119 GSSAPI_KRB5_INIT (&context
);
121 major_status
= iov_allocate(minor_status
, iov
, iov_count
);
122 if (major_status
!= GSS_S_COMPLETE
)
125 data
= calloc(iov_count
, sizeof(data
[0]));
127 gss_release_iov_buffer(&junk
, iov
, iov_count
);
128 *minor_status
= ENOMEM
;
129 return GSS_S_FAILURE
;
132 major_status
= iov_map(minor_status
, iov
, iov_count
, data
);
133 if (major_status
!= GSS_S_COMPLETE
) {
134 gss_release_iov_buffer(&junk
, iov
, iov_count
);
139 if (ctx
->more_flags
& LOCAL
) {
140 usage
= KRB5_KU_USAGE_ACCEPTOR_SIGN
;
142 usage
= KRB5_KU_USAGE_INITIATOR_SIGN
;
145 ret
= krb5_encrypt_iov_ivec(context
, ctx
->crypto
, usage
,
146 data
, iov_count
, NULL
);
149 gss_release_iov_buffer(&junk
, iov
, iov_count
);
151 return GSS_S_FAILURE
;
155 return GSS_S_COMPLETE
;
159 OM_uint32 GSSAPI_LIB_FUNCTION
160 _gk_unwrap_iov(OM_uint32
*minor_status
,
161 gss_ctx_id_t context_handle
,
163 gss_qop_t
*qop_state
,
164 gss_iov_buffer_desc
*iov
,
168 return GSS_S_FAILURE
;
170 gsskrb5_ctx ctx
= (gsskrb5_ctx
) context_handle
;
171 krb5_context context
;
173 OM_uint32 major_status
, junk
;
174 krb5_crypto_iov
*data
;
177 GSSAPI_KRB5_INIT (&context
);
179 major_status
= iov_allocate(minor_status
, iov
, iov_count
);
180 if (major_status
!= GSS_S_COMPLETE
)
183 data
= calloc(iov_count
, sizeof(data
[0]));
185 gss_release_iov_buffer(&junk
, iov
, iov_count
);
186 *minor_status
= ENOMEM
;
187 return GSS_S_FAILURE
;
190 major_status
= iov_map(minor_status
, iov
, iov_count
, data
);
191 if (major_status
!= GSS_S_COMPLETE
) {
192 gss_release_iov_buffer(&junk
, iov
, iov_count
);
197 if (ctx
->more_flags
& LOCAL
) {
198 usage
= KRB5_KU_USAGE_INITIATOR_SIGN
;
200 usage
= KRB5_KU_USAGE_ACCEPTOR_SIGN
;
203 ret
= krb5_decrypt_iov_ivec(context
, ctx
->crypto
, usage
,
204 data
, iov_count
, NULL
);
208 gss_release_iov_buffer(&junk
, iov
, iov_count
);
209 return GSS_S_FAILURE
;
213 return GSS_S_COMPLETE
;
217 OM_uint32 GSSAPI_LIB_FUNCTION
218 _gk_wrap_iov_length(OM_uint32
* minor_status
,
219 gss_ctx_id_t context_handle
,
223 gss_iov_buffer_desc
*iov
,
227 return GSS_S_FAILURE
;
229 gsskrb5_ctx ctx
= (gsskrb5_ctx
) context_handle
;
230 krb5_context context
;
233 size_t *padding
= NULL
;
235 GSSAPI_KRB5_INIT (&context
);
238 for (size
= 0, i
= 0; i
< iov_count
; i
++) {
239 switch(GSS_IOV_BUFFER_TYPE(iov
[i
].type
)) {
240 case GSS_IOV_BUFFER_TYPE_EMPTY
:
242 case GSS_IOV_BUFFER_TYPE_DATA
:
243 size
+= iov
[i
].buffer
.length
;
245 case GSS_IOV_BUFFER_TYPE_HEADER
:
246 iov
[i
].buffer
.length
=
247 krb5_crypto_length(context
, ctx
->crypto
, KRB5_CRYPTO_TYPE_HEADER
);
248 size
+= iov
[i
].buffer
.length
;
250 case GSS_IOV_BUFFER_TYPE_TRAILER
:
251 iov
[i
].buffer
.length
=
252 krb5_crypto_length(context
, ctx
->crypto
, KRB5_CRYPTO_TYPE_TRAILER
);
253 size
+= iov
[i
].buffer
.length
;
255 case GSS_IOV_BUFFER_TYPE_PADDING
:
256 if (padding
!= NULL
) {
258 return GSS_S_FAILURE
;
260 padding
= &iov
[i
].buffer
.length
;
262 case GSS_IOV_BUFFER_TYPE_STREAM
:
263 size
+= iov
[i
].buffer
.length
;
265 case GSS_IOV_BUFFER_TYPE_SIGN_ONLY
:
268 *minor_status
= EINVAL
;
269 return GSS_S_FAILURE
;
273 size_t pad
= krb5_crypto_length(context
, ctx
->crypto
,
274 KRB5_CRYPTO_TYPE_PADDING
);
276 *padding
= pad
- (size
% pad
);
283 return GSS_S_COMPLETE
;