1251876Speter/* $NetBSD: mk_safe.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */ 2251876Speter 3251876Speter/* 4251876Speter * Copyright (c) 1997 - 2003 Kungliga Tekniska H��gskolan 5251876Speter * (Royal Institute of Technology, Stockholm, Sweden). 6251876Speter * All rights reserved. 7251876Speter * 8251876Speter * Redistribution and use in source and binary forms, with or without 9251876Speter * modification, are permitted provided that the following conditions 10251876Speter * are met: 11251876Speter * 12251876Speter * 1. Redistributions of source code must retain the above copyright 13251876Speter * notice, this list of conditions and the following disclaimer. 14251876Speter * 15251876Speter * 2. Redistributions in binary form must reproduce the above copyright 16251876Speter * notice, this list of conditions and the following disclaimer in the 17251876Speter * documentation and/or other materials provided with the distribution. 18251876Speter * 19251876Speter * 3. Neither the name of the Institute nor the names of its contributors 20251876Speter * may be used to endorse or promote products derived from this software 21251876Speter * without specific prior written permission. 22251876Speter * 23251876Speter * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24251876Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25251876Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26251876Speter * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27251876Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28251876Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29251876Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30251876Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31251876Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32251876Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33251876Speter * SUCH DAMAGE. 34251876Speter */ 35251876Speter 36251876Speter#include "krb5_locl.h" 37251876Speter 38251876SpeterKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 39251876Speterkrb5_mk_safe(krb5_context context, 40251876Speter krb5_auth_context auth_context, 41251876Speter const krb5_data *userdata, 42251876Speter krb5_data *outbuf, 43251876Speter krb5_replay_data *outdata) 44251876Speter{ 45251876Speter krb5_error_code ret; 46251876Speter KRB_SAFE s; 47251876Speter u_char *buf = NULL; 48251876Speter size_t buf_size; 49251876Speter size_t len = 0; 50251876Speter krb5_crypto crypto; 51251876Speter krb5_keyblock *key; 52251876Speter krb5_replay_data rdata; 53251876Speter 54251876Speter if ((auth_context->flags & 55251876Speter (KRB5_AUTH_CONTEXT_RET_TIME | KRB5_AUTH_CONTEXT_RET_SEQUENCE)) && 56251876Speter outdata == NULL) 57251876Speter return KRB5_RC_REQUIRED; /* XXX better error, MIT returns this */ 58251876Speter 59251876Speter if (auth_context->local_subkey) 60251876Speter key = auth_context->local_subkey; 61251876Speter else if (auth_context->remote_subkey) 62251876Speter key = auth_context->remote_subkey; 63251876Speter else 64251876Speter key = auth_context->keyblock; 65251876Speter 66251876Speter s.pvno = 5; 67251876Speter s.msg_type = krb_safe; 68251876Speter 69251876Speter memset(&rdata, 0, sizeof(rdata)); 70251876Speter 71251876Speter s.safe_body.user_data = *userdata; 72251876Speter 73251876Speter krb5_us_timeofday (context, &rdata.timestamp, &rdata.usec); 74251876Speter 75251876Speter if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) { 76251876Speter s.safe_body.timestamp = &rdata.timestamp; 77251876Speter s.safe_body.usec = &rdata.usec; 78251876Speter } else { 79251876Speter s.safe_body.timestamp = NULL; 80251876Speter s.safe_body.usec = NULL; 81251876Speter } 82251876Speter 83251876Speter if (auth_context->flags & KRB5_AUTH_CONTEXT_RET_TIME) { 84251876Speter outdata->timestamp = rdata.timestamp; 85251876Speter outdata->usec = rdata.usec; 86251876Speter } 87251876Speter 88251876Speter if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) { 89251876Speter rdata.seq = auth_context->local_seqnumber; 90251876Speter s.safe_body.seq_number = &rdata.seq; 91251876Speter } else 92251876Speter s.safe_body.seq_number = NULL; 93251876Speter 94251876Speter if (auth_context->flags & KRB5_AUTH_CONTEXT_RET_SEQUENCE) 95251876Speter outdata->seq = auth_context->local_seqnumber; 96251876Speter 97251876Speter s.safe_body.s_address = auth_context->local_address; 98251876Speter s.safe_body.r_address = auth_context->remote_address; 99251876Speter 100251876Speter s.cksum.cksumtype = 0; 101251876Speter s.cksum.checksum.data = NULL; 102251876Speter s.cksum.checksum.length = 0; 103251876Speter 104251876Speter ASN1_MALLOC_ENCODE(KRB_SAFE, buf, buf_size, &s, &len, ret); 105251876Speter if (ret) 106251876Speter return ret; 107251876Speter if(buf_size != len) 108251876Speter krb5_abortx(context, "internal error in ASN.1 encoder"); 109251876Speter ret = krb5_crypto_init(context, key, 0, &crypto); 110251876Speter if (ret) { 111251876Speter free (buf); 112251876Speter return ret; 113251876Speter } 114251876Speter ret = krb5_create_checksum(context, 115251876Speter crypto, 116251876Speter KRB5_KU_KRB_SAFE_CKSUM, 117251876Speter 0, 118251876Speter buf, 119251876Speter len, 120251876Speter &s.cksum); 121251876Speter krb5_crypto_destroy(context, crypto); 122251876Speter if (ret) { 123251876Speter free (buf); 124251876Speter return ret; 125251876Speter } 126251876Speter 127251876Speter free(buf); 128251876Speter ASN1_MALLOC_ENCODE(KRB_SAFE, buf, buf_size, &s, &len, ret); 129251876Speter free_Checksum (&s.cksum); 130251876Speter if(ret) 131251876Speter return ret; 132251876Speter if(buf_size != len) 133251876Speter krb5_abortx(context, "internal error in ASN.1 encoder"); 134251876Speter 135251876Speter outbuf->length = len; 136251876Speter outbuf->data = buf; 137251876Speter if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_SEQUENCE) 138251876Speter auth_context->local_seqnumber = 139251876Speter (auth_context->local_seqnumber + 1) & 0xFFFFFFFF; 140251876Speter return 0; 141251876Speter} 142251876Speter