2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
19 * $Id: gssapi_link.c,v 1.7.2.1 2004/03/09 06:11:41 marka Exp $
26 #include <isc/buffer.h>
28 #include <isc/string.h>
31 #include <dst/result.h>
33 #include "dst_internal.h"
34 #include "dst_parse.h"
36 #include <gssapi/gssapi.h>
38 #define INITIAL_BUFFER_SIZE 1024
39 #define BUFFER_EXTRA 1024
41 #define REGION_TO_GBUFFER(r, gb) \
43 (gb).length = (r).length; \
44 (gb).value = (r).base; \
47 typedef struct gssapi_ctx {
49 gss_ctx_id_t *context_id;
54 gssapi_createctx(dst_key_t *key, dst_context_t *dctx) {
60 ctx = isc_mem_get(dctx->mctx, sizeof(gssapi_ctx_t));
62 return (ISC_R_NOMEMORY);
64 result = isc_buffer_allocate(dctx->mctx, &ctx->buffer,
66 if (result != ISC_R_SUCCESS) {
67 isc_mem_put(dctx->mctx, ctx, sizeof(gssapi_ctx_t));
70 ctx->context_id = key->opaque;
72 return (ISC_R_SUCCESS);
76 gssapi_destroyctx(dst_context_t *dctx) {
77 gssapi_ctx_t *ctx = dctx->opaque;
80 if (ctx->buffer != NULL)
81 isc_buffer_free(&ctx->buffer);
82 isc_mem_put(dctx->mctx, ctx, sizeof(gssapi_ctx_t));
88 gssapi_adddata(dst_context_t *dctx, const isc_region_t *data) {
89 gssapi_ctx_t *ctx = dctx->opaque;
90 isc_buffer_t *newbuffer = NULL;
95 result = isc_buffer_copyregion(ctx->buffer, data);
96 if (result == ISC_R_SUCCESS)
97 return (ISC_R_SUCCESS);
99 length = isc_buffer_length(ctx->buffer) + data->length + BUFFER_EXTRA;
101 result = isc_buffer_allocate(dctx->mctx, &newbuffer, length);
102 if (result != ISC_R_SUCCESS)
105 isc_buffer_usedregion(ctx->buffer, &r);
106 (void) isc_buffer_copyregion(newbuffer, &r);
107 (void) isc_buffer_copyregion(newbuffer, data);
109 isc_buffer_free(&ctx->buffer);
110 ctx->buffer = newbuffer;
112 return (ISC_R_SUCCESS);
116 gssapi_sign(dst_context_t *dctx, isc_buffer_t *sig) {
117 gssapi_ctx_t *ctx = dctx->opaque;
118 isc_region_t message;
119 gss_buffer_desc gmessage, gsig;
120 OM_uint32 minor, gret;
122 isc_buffer_usedregion(ctx->buffer, &message);
123 REGION_TO_GBUFFER(message, gmessage);
125 gret = gss_get_mic(&minor, ctx->context_id,
126 GSS_C_QOP_DEFAULT, &gmessage, &gsig);
128 return (ISC_R_FAILURE);
130 if (gsig.length > isc_buffer_availablelength(sig)) {
131 gss_release_buffer(&minor, &gsig);
132 return (ISC_R_NOSPACE);
135 isc_buffer_putmem(sig, gsig.value, gsig.length);
137 gss_release_buffer(&minor, &gsig);
139 return (ISC_R_SUCCESS);
143 gssapi_verify(dst_context_t *dctx, const isc_region_t *sig) {
144 gssapi_ctx_t *ctx = dctx->opaque;
145 isc_region_t message;
146 gss_buffer_desc gmessage, gsig;
147 OM_uint32 minor, gret;
149 isc_buffer_usedregion(ctx->buffer, &message);
150 REGION_TO_GBUFFER(message, gmessage);
152 REGION_TO_GBUFFER(*sig, gsig);
154 gret = gss_verify_mic(&minor, ctx->context_id, &gmessage, &gsig, NULL);
156 return (ISC_R_FAILURE);
158 return (ISC_R_SUCCESS);
162 gssapi_compare(const dst_key_t *key1, const dst_key_t *key2) {
163 gss_ctx_id_t gsskey1 = key1->opaque;
164 gss_ctx_id_t gsskey2 = key2->opaque;
167 return (ISC_TF(gsskey1 == gsskey2));
171 gssapi_generate(dst_key_t *key, int unused) {
176 return (ISC_R_FAILURE);
180 gssapi_isprivate(const dst_key_t *key) {
186 gssapi_issymmetric(const dst_key_t *key) {
192 gssapi_destroy(dst_key_t *key) {
197 static dst_func_t gssapi_functions = {
203 NULL, /* computesecret */
205 NULL, /* paramcompare */
217 dst__gssapi_init(dst_func_t **funcp) {
218 REQUIRE(funcp != NULL && *funcp == NULL);
219 *funcp = &gssapi_functions;
220 return (ISC_R_SUCCESS);
224 dst__gssapi_destroy(void) {
228 int gssapi_link_unneeded = 1;