2 * Copyright (c) 2010 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Portions Copyright (c) 2010 Apple Inc. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the Institute nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 static uint8_t zeros
[4];
41 _netlogon_encode_sequence_number(uint64_t SequenceNumber
, uint8_t *p
,
44 uint32_t LowPart
, HighPart
;
46 LowPart
= (SequenceNumber
>> 0 ) & 0xFFFFFFFF;
47 HighPart
= (SequenceNumber
>> 32) & 0xFFFFFFFF;
49 _gss_mg_encode_be_uint32(LowPart
, &p
[0]);
50 _gss_mg_encode_be_uint32(HighPart
, &p
[4]);
57 _netlogon_decode_sequence_number(void *ptr
, uint64_t *n
,
61 uint32_t LowPart
, HighPart
;
64 gotInitiatorFlag
= (p
[4] & 0x80) != 0;
65 if (gotInitiatorFlag
!= initiatorFlag
)
68 p
[4] &= 0x7F; /* clear initiator bit */
70 _gss_mg_decode_be_uint32(&p
[0], &LowPart
);
71 _gss_mg_decode_be_uint32(&p
[4], &HighPart
);
73 *n
= (LowPart
<< 0) | ((uint64_t)HighPart
<< 32);
79 _netlogon_checksum_length(NL_AUTH_SIGNATURE
*sig
)
82 return (sig
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
) ? 32 : 8;
84 /* Owing to a bug in Windows it always uses the old value */
90 _netlogon_signature_length(uint16_t alg
, int conf_req_flag
)
92 return NL_AUTH_SIGNATURE_COMMON_LENGTH
+
93 (alg
== NL_SIGN_ALG_SHA256
? 32 : 8) +
94 (conf_req_flag
? 8 : 0);
97 static inline uint8_t *
98 _netlogon_confounder(NL_AUTH_SIGNATURE
*sig
)
100 size_t cksumlen
= _netlogon_checksum_length(sig
);
102 return &sig
->Checksum
[cksumlen
];
106 _netlogon_encode_NL_AUTH_SIGNATURE(NL_AUTH_SIGNATURE
*sig
,
107 uint8_t *p
, size_t len
)
109 *p
++ = (sig
->SignatureAlgorithm
>> 0) & 0xFF;
110 *p
++ = (sig
->SignatureAlgorithm
>> 8) & 0xFF;
111 *p
++ = (sig
->SealAlgorithm
>> 0) & 0xFF;
112 *p
++ = (sig
->SealAlgorithm
>> 8) & 0xFF;
113 *p
++ = (sig
->Pad
>> 0) & 0xFF;
114 *p
++ = (sig
->Pad
>> 8) & 0xFF;
115 *p
++ = (sig
->Flags
>> 0) & 0xFF;
116 *p
++ = (sig
->Flags
>> 8) & 0xFF;
118 if (len
> NL_AUTH_SIGNATURE_HEADER_LENGTH
) {
119 memcpy(p
, sig
->SequenceNumber
, 8);
123 if (len
> NL_AUTH_SIGNATURE_COMMON_LENGTH
) {
124 size_t cksumlen
= _netlogon_checksum_length(sig
);
126 memcpy(p
, sig
->Checksum
, cksumlen
);
129 /* Confounder, if present, is immediately after checksum */
130 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
) {
131 memcpy(p
, &sig
->Checksum
[cksumlen
], 8);
139 _netlogon_decode_NL_AUTH_SIGNATURE(const uint8_t *ptr
,
141 NL_AUTH_SIGNATURE
*sig
)
143 const uint8_t *p
= ptr
;
146 if (len
< NL_AUTH_SIGNATURE_COMMON_LENGTH
)
147 return KRB5_BAD_MSIZE
;
149 sig
->SignatureAlgorithm
= (p
[0] << 0) | (p
[1] << 8);
150 sig
->SealAlgorithm
= (p
[2] << 0) | (p
[3] << 8);
151 sig
->Pad
= (p
[4] << 0) | (p
[5] << 8);
152 sig
->Flags
= (p
[6] << 0) | (p
[7] << 8);
155 memcpy(sig
->SequenceNumber
, p
, 8);
158 /* Validate signature algorithm is known and matches enctype */
159 switch (sig
->SignatureAlgorithm
) {
160 case NL_SIGN_ALG_HMAC_MD5
:
161 cksumlen
= NL_AUTH_SIGNATURE_LENGTH
;
163 case NL_SIGN_ALG_SHA256
:
164 cksumlen
= NL_AUTH_SHA2_SIGNATURE_LENGTH
;
171 if (sig
->SealAlgorithm
== NL_SEAL_ALG_NONE
)
172 cksumlen
-= 8; /* confounder is optional if no sealing */
175 return KRB5_BAD_MSIZE
;
177 /* Copy variable length checksum */
178 cksumlen
= _netlogon_checksum_length(sig
);
179 memcpy(sig
->Checksum
, p
, cksumlen
);
182 /* Copy confounder in past checksum */
183 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
)
184 memcpy(&sig
->Checksum
[cksumlen
], p
, 8);
190 _netlogon_derive_rc4_hmac_key(uint8_t key
[16],
193 EVP_CIPHER_CTX
*rc4Key
,
196 uint8_t tmpData
[MD5_DIGEST_LENGTH
];
197 uint8_t derivedKey
[MD5_DIGEST_LENGTH
];
198 unsigned int len
= MD5_DIGEST_LENGTH
;
200 HMAC(EVP_md5(), key
, 16, zeros
, sizeof(zeros
), tmpData
, &len
);
201 HMAC(EVP_md5(), tmpData
, MD5_DIGEST_LENGTH
,
202 salt
, saltLength
, derivedKey
, &len
);
204 assert(len
== MD5_DIGEST_LENGTH
);
206 EVP_CipherInit_ex(rc4Key
, EVP_rc4(), NULL
, derivedKey
, NULL
, enc
);
208 memset(derivedKey
, 0, sizeof(derivedKey
));
212 _netlogon_derive_rc4_seal_key(gssnetlogon_ctx ctx
,
213 NL_AUTH_SIGNATURE
*sig
,
214 EVP_CIPHER_CTX
*sealkey
,
220 for (i
= 0; i
< sizeof(xorKey
); i
++) {
221 xorKey
[i
] = ctx
->SessionKey
[i
] ^ 0xF0;
224 _netlogon_derive_rc4_hmac_key(xorKey
,
225 sig
->SequenceNumber
, sizeof(sig
->SequenceNumber
), sealkey
, enc
);
227 memset(xorKey
, 0, sizeof(xorKey
));
231 _netlogon_derive_rc4_seq_key(gssnetlogon_ctx ctx
,
232 NL_AUTH_SIGNATURE
*sig
,
233 EVP_CIPHER_CTX
*seqkey
,
236 _netlogon_derive_rc4_hmac_key(ctx
->SessionKey
,
237 sig
->Checksum
, sizeof(sig
->Checksum
), seqkey
, enc
);
241 _netlogon_derive_aes_seal_key(gssnetlogon_ctx ctx
,
242 NL_AUTH_SIGNATURE
*sig
,
243 EVP_CIPHER_CTX
*sealkey
,
246 uint8_t encryptionKey
[16];
250 for (i
= 0; i
< sizeof(encryptionKey
); i
++) {
251 encryptionKey
[i
] = ctx
->SessionKey
[i
] ^ 0xF0;
254 memcpy(&ivec
[0], sig
->SequenceNumber
, 8);
255 memcpy(&ivec
[8], sig
->SequenceNumber
, 8);
257 EVP_CipherInit_ex(sealkey
, EVP_aes_128_cfb8(),
258 NULL
, encryptionKey
, ivec
, enc
);
260 memset(encryptionKey
, 0, sizeof(encryptionKey
));
264 _netlogon_derive_aes_seq_key(gssnetlogon_ctx ctx
,
265 NL_AUTH_SIGNATURE
*sig
,
266 EVP_CIPHER_CTX
*seqkey
,
271 memcpy(&ivec
[0], sig
->Checksum
, 8);
272 memcpy(&ivec
[8], sig
->Checksum
, 8);
274 EVP_CipherInit_ex(seqkey
, EVP_aes_128_cfb8(),
275 NULL
, ctx
->SessionKey
, ivec
, enc
);
279 _netlogon_seal(gssnetlogon_ctx ctx
,
280 NL_AUTH_SIGNATURE
*sig
,
281 gss_iov_buffer_desc
*iov
,
285 EVP_CIPHER_CTX sealkey
;
287 uint8_t *confounder
= _netlogon_confounder(sig
);
289 EVP_CIPHER_CTX_init(&sealkey
);
291 if (sig
->SealAlgorithm
== NL_SEAL_ALG_AES128
)
292 _netlogon_derive_aes_seal_key(ctx
, sig
, &sealkey
, enc
);
294 _netlogon_derive_rc4_seal_key(ctx
, sig
, &sealkey
, enc
);
296 EVP_Cipher(&sealkey
, confounder
, confounder
, 8);
299 * For RC4, Windows resets the cipherstate after encrypting
300 * the confounder, thus defeating the purpose of the confounder
302 if (sig
->SealAlgorithm
== NL_SEAL_ALG_RC4
) {
303 EVP_CipherFinal_ex(&sealkey
, NULL
, &i
);
304 _netlogon_derive_rc4_seal_key(ctx
, sig
, &sealkey
, enc
);
307 for (i
= 0; i
< iov_count
; i
++) {
308 gss_iov_buffer_t iovp
= &iov
[i
];
310 switch (GSS_IOV_BUFFER_TYPE(iovp
->type
)) {
311 case GSS_IOV_BUFFER_TYPE_DATA
:
312 case GSS_IOV_BUFFER_TYPE_PADDING
:
313 EVP_Cipher(&sealkey
, iovp
->buffer
.value
, iovp
->buffer
.value
,
314 iovp
->buffer
.length
);
321 EVP_CipherFinal_ex(&sealkey
, NULL
, &i
);
322 EVP_CIPHER_CTX_cleanup(&sealkey
);
326 _netlogon_seq(gssnetlogon_ctx ctx
,
327 NL_AUTH_SIGNATURE
*sig
,
330 EVP_CIPHER_CTX seqkey
;
332 EVP_CIPHER_CTX_init(&seqkey
);
334 if (sig
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
)
335 _netlogon_derive_aes_seq_key(ctx
, sig
, &seqkey
, enc
);
337 _netlogon_derive_rc4_seq_key(ctx
, sig
, &seqkey
, enc
);
339 EVP_Cipher(&seqkey
, sig
->SequenceNumber
, sig
->SequenceNumber
, 8);
341 EVP_CIPHER_CTX_cleanup(&seqkey
);
345 _netlogon_digest_md5(gssnetlogon_ctx ctx
,
346 NL_AUTH_SIGNATURE
*sig
,
347 gss_iov_buffer_desc
*iov
,
352 uint8_t header
[NL_AUTH_SIGNATURE_HEADER_LENGTH
];
353 uint8_t digest
[MD5_DIGEST_LENGTH
];
354 unsigned int md_len
= MD5_DIGEST_LENGTH
;
357 _netlogon_encode_NL_AUTH_SIGNATURE(sig
, header
, sizeof(header
));
359 md5
= EVP_MD_CTX_create();
360 EVP_DigestInit_ex(md5
, EVP_md5(), NULL
);
361 EVP_DigestUpdate(md5
, zeros
, sizeof(zeros
));
362 EVP_DigestUpdate(md5
, header
, sizeof(header
));
364 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
) {
365 EVP_DigestUpdate(md5
, sig
->Confounder
, sizeof(sig
->Confounder
));
368 for (i
= 0; i
< iov_count
; i
++) {
369 gss_iov_buffer_t iovp
= &iov
[i
];
371 switch (GSS_IOV_BUFFER_TYPE(iovp
->type
)) {
372 case GSS_IOV_BUFFER_TYPE_DATA
:
373 case GSS_IOV_BUFFER_TYPE_PADDING
:
374 case GSS_IOV_BUFFER_TYPE_SIGN_ONLY
:
375 EVP_DigestUpdate(md5
, iovp
->buffer
.value
, iovp
->buffer
.length
);
382 EVP_DigestFinal_ex(md5
, digest
, NULL
);
383 EVP_MD_CTX_destroy(md5
);
385 HMAC(EVP_md5(), ctx
->SessionKey
, sizeof(ctx
->SessionKey
),
386 digest
, sizeof(digest
), digest
, &md_len
);
387 memcpy(md
, digest
, 8);
391 _netlogon_digest_sha256(gssnetlogon_ctx ctx
,
392 NL_AUTH_SIGNATURE
*sig
,
393 gss_iov_buffer_desc
*iov
,
398 uint8_t header
[NL_AUTH_SIGNATURE_HEADER_LENGTH
];
399 uint8_t digest
[SHA256_DIGEST_LENGTH
];
400 unsigned int md_len
= SHA256_DIGEST_LENGTH
;
403 /* Encode first 8 bytes of signature into header */
404 _netlogon_encode_NL_AUTH_SIGNATURE(sig
, header
, sizeof(header
));
406 HMAC_CTX_init(&hmac
);
407 HMAC_Init_ex(&hmac
, ctx
->SessionKey
, sizeof(ctx
->SessionKey
),
409 HMAC_Update(&hmac
, header
, sizeof(header
));
411 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
) {
413 * If the checksum length bug is ever fixed, then be sure to
414 * update this code to point to &sig->Checksum[32] as that is
415 * where the confounder is supposed to be.
417 HMAC_Update(&hmac
, sig
->Confounder
, 8);
420 for (i
= 0; i
< iov_count
; i
++) {
421 gss_iov_buffer_t iovp
= &iov
[i
];
423 switch (GSS_IOV_BUFFER_TYPE(iovp
->type
)) {
424 case GSS_IOV_BUFFER_TYPE_DATA
:
425 case GSS_IOV_BUFFER_TYPE_PADDING
:
426 case GSS_IOV_BUFFER_TYPE_SIGN_ONLY
:
427 HMAC_Update(&hmac
, iovp
->buffer
.value
, iovp
->buffer
.length
);
434 HMAC_Final(&hmac
, digest
, &md_len
);
435 HMAC_CTX_cleanup(&hmac
);
436 memcpy(md
, digest
, 8);
440 _netlogon_digest(gssnetlogon_ctx ctx
,
441 NL_AUTH_SIGNATURE
*sig
,
442 gss_iov_buffer_desc
*iov
,
446 if (sig
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
)
447 _netlogon_digest_sha256(ctx
, sig
, iov
, iov_count
, md
);
449 _netlogon_digest_md5(ctx
, sig
, iov
, iov_count
, md
);
453 _netlogon_wrap_iov(OM_uint32
* minor_status
,
454 gss_ctx_id_t context_handle
,
458 gss_iov_buffer_desc
*iov
,
462 gss_iov_buffer_t header
;
463 NL_AUTH_SIGNATURE_U sigbuf
= { { 0 } };
464 NL_AUTH_SIGNATURE
*sig
= NL_AUTH_SIGNATURE_P(&sigbuf
);
465 gssnetlogon_ctx ctx
= (gssnetlogon_ctx
)context_handle
;
469 if (ctx
->State
!= NL_AUTH_ESTABLISHED
) {
470 *minor_status
= EINVAL
;
471 return GSS_S_FAILURE
;
474 header
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_HEADER
);
475 if (header
== NULL
) {
476 *minor_status
= EINVAL
;
477 return GSS_S_FAILURE
;
480 size
= _netlogon_signature_length(ctx
->SignatureAlgorithm
, conf_req_flag
);
482 if (GSS_IOV_BUFFER_FLAGS(header
->type
) & GSS_IOV_BUFFER_FLAG_ALLOCATE
) {
483 ret
= _gss_mg_allocate_buffer(minor_status
, header
, size
);
486 } else if (header
->buffer
.length
< size
) {
487 *minor_status
= KRB5_BAD_MSIZE
;
488 return GSS_S_FAILURE
;
490 header
->buffer
.length
= size
;
493 memset(header
->buffer
.value
, 0, header
->buffer
.length
);
495 sig
->SignatureAlgorithm
= ctx
->SignatureAlgorithm
;
496 sig
->SealAlgorithm
= conf_req_flag
? ctx
->SealAlgorithm
: NL_SEAL_ALG_NONE
;
499 krb5_generate_random_block(_netlogon_confounder(sig
), 8);
501 sig
->Pad
= 0xFFFF; /* [MS-NRPC] 3.3.4.2.1.3 */
502 sig
->Flags
= 0; /* [MS-NRPC] 3.3.4.2.1.4 */
503 HEIMDAL_MUTEX_lock(&ctx
->Mutex
);
504 _netlogon_encode_sequence_number(ctx
->SequenceNumber
, sig
->SequenceNumber
,
505 ctx
->LocallyInitiated
);
506 ctx
->SequenceNumber
++;
507 HEIMDAL_MUTEX_unlock(&ctx
->Mutex
);
509 /* [MS-NRPC] 3.3.4.2.1.7: sign header, optional confounder and data */
510 _netlogon_digest(ctx
, sig
, iov
, iov_count
, sig
->Checksum
);
512 /* [MS-NRPC] 3.3.4.2.1.8: optionally encrypt confounder and data */
514 _netlogon_seal(ctx
, sig
, iov
, iov_count
, 1);
516 /* [MS-NRPC] 3.3.4.2.1.9: encrypt sequence number */
517 _netlogon_seq(ctx
, sig
, 1);
519 _netlogon_encode_NL_AUTH_SIGNATURE(sig
, header
->buffer
.value
,
520 header
->buffer
.length
);
522 if (conf_state
!= NULL
)
523 *conf_state
= conf_req_flag
;
526 return GSS_S_COMPLETE
;
530 _netlogon_unwrap_iov(OM_uint32
*minor_status
,
531 gss_ctx_id_t context_handle
,
533 gss_qop_t
*qop_state
,
534 gss_iov_buffer_desc
*iov
,
538 gss_iov_buffer_t header
;
539 NL_AUTH_SIGNATURE_U sigbuf
;
540 NL_AUTH_SIGNATURE
*sig
= NL_AUTH_SIGNATURE_P(&sigbuf
);
541 gssnetlogon_ctx ctx
= (gssnetlogon_ctx
)context_handle
;
542 uint8_t checksum
[SHA256_DIGEST_LENGTH
];
543 uint64_t SequenceNumber
;
545 if (ctx
->State
!= NL_AUTH_ESTABLISHED
) {
546 *minor_status
= EINVAL
;
547 return GSS_S_FAILURE
;
550 header
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_HEADER
);
551 if (header
== NULL
) {
552 *minor_status
= EINVAL
;
553 return GSS_S_FAILURE
;
556 ret
= _netlogon_decode_NL_AUTH_SIGNATURE(header
->buffer
.value
,
557 header
->buffer
.length
,
561 return GSS_S_DEFECTIVE_TOKEN
;
564 /* [MS-NRPC] 3.3.4.2.2.1: verify signature algorithm selection */
565 if (sig
->SignatureAlgorithm
!= ctx
->SignatureAlgorithm
)
566 return GSS_S_BAD_SIG
;
568 /* [MS-NRPC] 3.3.4.2.2.2: verify encryption algorithm selection */
569 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
&&
570 sig
->SealAlgorithm
!= ctx
->SealAlgorithm
)
571 return GSS_S_DEFECTIVE_TOKEN
;
573 /* [MS-NRPC] 3.3.4.2.2.3: verify Pad bytes */
574 if (sig
->Pad
!= 0xFFFF)
575 return GSS_S_DEFECTIVE_TOKEN
;
577 /* [MS-NRPC] 3.3.4.2.2.5: decrypt sequence number */
578 _netlogon_seq(ctx
, sig
, 0);
580 /* [MS-NRPC] 3.3.4.2.2.6: decode sequence number */
581 if (_netlogon_decode_sequence_number(sig
->SequenceNumber
, &SequenceNumber
,
582 !ctx
->LocallyInitiated
) != 0)
583 return GSS_S_UNSEQ_TOKEN
;
585 /* [MS-NRPC] 3.3.4.2.2.9: decrypt confounder and data */
586 if (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
)
587 _netlogon_seal(ctx
, sig
, iov
, iov_count
, 0);
589 /* [MS-NRPC] 3.3.4.2.2.10: verify signature */
590 _netlogon_digest(ctx
, sig
, iov
, iov_count
, checksum
);
591 if (memcmp(sig
->Checksum
, checksum
, _netlogon_checksum_length(sig
)) != 0)
592 return GSS_S_BAD_SIG
;
594 HEIMDAL_MUTEX_lock(&ctx
->Mutex
);
595 if (SequenceNumber
!= ctx
->SequenceNumber
) {
596 /* [MS-NRPC] 3.3.4.2.2.7: check sequence number */
597 ret
= GSS_S_UNSEQ_TOKEN
;
599 /* [MS-NRPC] 3.3.4.2.2.8: increment sequence number */
600 ctx
->SequenceNumber
++;
601 ret
= GSS_S_COMPLETE
;
603 HEIMDAL_MUTEX_unlock(&ctx
->Mutex
);
605 if (conf_state
!= NULL
)
606 *conf_state
= (sig
->SealAlgorithm
!= NL_SEAL_ALG_NONE
);
607 if (qop_state
!= NULL
)
608 *qop_state
= GSS_C_QOP_DEFAULT
;
615 _netlogon_wrap_iov_length(OM_uint32
* minor_status
,
616 gss_ctx_id_t context_handle
,
620 gss_iov_buffer_desc
*iov
,
624 gss_iov_buffer_t iovp
;
625 gssnetlogon_ctx ctx
= (gssnetlogon_ctx
)context_handle
;
628 iovp
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_HEADER
);
630 *minor_status
= EINVAL
;
631 return GSS_S_FAILURE
;
634 len
= NL_AUTH_SIGNATURE_COMMON_LENGTH
;
635 if (ctx
->SignatureAlgorithm
== NL_SIGN_ALG_SHA256
)
636 len
+= 32; /* SHA2 checksum size */
638 len
+= 8; /* HMAC checksum size */
640 len
+= 8; /* counfounder */
642 iovp
->buffer
.length
= len
;
644 iovp
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_PADDING
);
646 iovp
->buffer
.length
= 0;
648 iovp
= _gss_mg_find_buffer(iov
, iov_count
, GSS_IOV_BUFFER_TYPE_TRAILER
);
650 iovp
->buffer
.length
= 0;
652 if (conf_state
!= NULL
)
653 *conf_state
= conf_req_flag
;
656 return GSS_S_COMPLETE
;
659 OM_uint32 _netlogon_get_mic
660 (OM_uint32
* minor_status
,
661 gss_const_ctx_id_t context_handle
,
663 const gss_buffer_t message_buffer
,
664 gss_buffer_t message_token
667 gss_iov_buffer_desc iov
[2];
670 iov
[0].type
= GSS_IOV_BUFFER_TYPE_DATA
;
671 iov
[0].buffer
= *message_buffer
;
672 iov
[1].type
= GSS_IOV_BUFFER_TYPE_HEADER
| GSS_IOV_BUFFER_FLAG_ALLOCATE
;
673 iov
[1].buffer
.length
= 0;
674 iov
[1].buffer
.value
= NULL
;
676 ret
= _netlogon_wrap_iov(minor_status
, context_handle
, 0,
677 qop_req
, NULL
, iov
, 2);
678 if (ret
== GSS_S_COMPLETE
)
679 *message_token
= iov
[1].buffer
;
686 (OM_uint32
* minor_status
,
687 gss_const_ctx_id_t context_handle
,
688 const gss_buffer_t message_buffer
,
689 const gss_buffer_t token_buffer
,
690 gss_qop_t
* qop_state
693 gss_iov_buffer_desc iov
[2];
695 iov
[0].type
= GSS_IOV_BUFFER_TYPE_DATA
;
696 iov
[0].buffer
= *message_buffer
;
697 iov
[1].type
= GSS_IOV_BUFFER_TYPE_HEADER
;
698 iov
[1].buffer
= *token_buffer
;
700 return _netlogon_unwrap_iov(minor_status
, context_handle
,
701 NULL
, qop_state
, iov
, 2);
705 _netlogon_wrap_size_limit (
706 OM_uint32
* minor_status
,
707 gss_const_ctx_id_t context_handle
,
710 OM_uint32 req_output_size
,
711 OM_uint32
*max_input_size
714 gss_iov_buffer_desc iov
[1];
717 iov
[0].type
= GSS_IOV_BUFFER_TYPE_HEADER
;
718 iov
[0].buffer
.length
= 0;
720 ret
= _netlogon_wrap_iov_length(minor_status
, context_handle
,
721 conf_req_flag
, qop_req
, NULL
,
722 iov
, sizeof(iov
)/sizeof(iov
[0]));
726 if (req_output_size
< iov
[0].buffer
.length
)
729 *max_input_size
= req_output_size
- iov
[0].buffer
.length
;
731 return GSS_S_COMPLETE
;