token.c revision 2
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License, Version 1.0 only 2N/A * (the "License"). You may not use this file except in compliance 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 1997, by Sun Microsystems, Inc. 2N/A * All rights reserved. 2N/A#
pragma ident "%Z%%M% %I% %E% SMI" 2N/A#
define MSO_BIT (
8*(
sizeof (
int) -
1))
/* Most significant octet bit */ 2N/A * get_qop: For a Diffie-Hellman token_t, return the associate QOP 2N/A /* Should never get here */ 2N/A * __make_ap_token: This routine generates a Diffie-Hellman serialized 2N/A * token which has an ASN.1 application 0 header prepended. The unserialized 2N/A * token supplied should be of type DH_INIT_CNTX. 2N/A * The ASN.1 applicationtion prefix is encoded as follows: 2N/A * | 0x60 | 1 TAG for APPLICATION 0 2N/A * ~ ~ app_size DER encoded length of oid_size + token_size 2N/A * | 0x06 | 1 TAG for OID 2N/A * | | der_length_size 2N/A * ~ ~ (mech->length) DER encoded length of mech->length 2N/A * ~ ~ mech->length OID elements (mech->elements) 2N/A * | 0x00 | 0-3 XDR padding 2N/A * ~ ~ Serialized DH token 2N/A * | 0x00 | 0-3 Left over XDR padding 2N/A * We will define the token_size to be the sizeof the serialize token plus 2N/A * 3 the maximum XDR paddinging that will be needed. Thus the XDR padding 2N/A * plus the left over XDR padding will alway equal 3. 2N/A /* Allocate the signature for the input token */ 2N/A * We will first determine the size of the output token in 2N/A * a bottom up fashion. 2N/A /* Fetch the size of a serialized DH token */ 2N/A * The token itself needs to be pasted on to the ASN.1 2N/A * application header on BYTES_PER_XDR_UNIT boundry. So we may 2N/A * need upto BYTES_PER_XDR_UNIT - 1 extra bytes. 2N/A /* bytes to store the length */ 2N/A hsize +=
1;
/* tag 0x60 for application 0 */ 2N/A /* Allocate a buffer to serialize into */ 2N/A /* ASN.1 application 0 header */ 2N/A /* Encode the tag */ 2N/A /* Encode the app length */ 2N/A /* Encode the OID tag */ 2N/A /* Encode the OID length */ 2N/A /* Encode the OID elemeents */ 2N/A /* Encode the Diffie-Hellmam token */ 2N/A * Token has to be on BYTES_PER_XDR_UNIT boundry. (RNDUP is 2N/A /* Buffer for xdrmem_create to use */ 2N/A /* Paste the DH token on */ 2N/A /* We're done with the signature, the token has been serialized */ 2N/A * __make_token: Given an unserialized DH token, serialize it puting the 2N/A * serialized output in result. If this token has a type of DH_MIC, then 2N/A * the optional message, msg, should be supplied. The mic caluclated will be 2N/A * over the message as well as the serialized token. 2N/A /* Allocate a signature for this token */ 2N/A /* Get the output token size to know how much to allocate */ 2N/A /* Allocate the buffer to hold the serialized token */ 2N/A /* Set the result */ 2N/A /* Create the xdr stream using the allocated buffer */ 2N/A /* Encode the token */ 2N/A /* Release the signature */ 2N/A * __get_ap_token: This routine deserializes a Diffie-Hellman serialized 2N/A * token which has an ASN.1 application 0 header prepended. The resulting 2N/A * unserialized token supplied should be of type DH_INIT_CNTX.. 2N/A * The ASN.1 applicationtion prefix and token is encoded as follows: 2N/A * | 0x60 | 1 TAG for APPLICATION 0 2N/A * ~ ~ app_size DER encoded length of oid_size + token_size 2N/A * | 0x06 | 1 TAG for OID 2N/A * | | der_length_size 2N/A * ~ ~ (mech->length) DER encoded length of mech->length 2N/A * ~ ~ mech->length OID elements (mech->elements) 2N/A * | 0x00 | 0-3 XDR padding 2N/A * ~ ~ Serialized DH token 2N/A * | 0x00 | 0-3 Left over XDR padding 2N/A * We will define the token_size to be the sizeof the serialize token plus 2N/A * 3 the maximum XDR paddinging that will be needed. Thus the XDR padding 2N/A * plus the left over XDR padding will alway equal 3. 2N/A /* Set p and buf to point to the beginning of the token */ 2N/A /* Check that this is an ASN.1 APPLICATION 0 token */ 2N/A /* Determine the length for the DER encoding of the packet length */ 2N/A * See if the number of bytes specified by the 2N/A * encoded length is all there 2N/A * Running total of the APPLICATION 0 prefix so far. One for the 2N/A * tag (0x60) and the bytes necessary to encode the length of the 2N/A /* Check that we're now looking at an OID */ 2N/A /* Get OID length and the number of bytes that to encode it */ 2N/A * Now add the byte for the OID tag, plus the bytes for the oid 2N/A * length, plus the oid length its self. That is, add the size 2N/A * of the encoding of the OID to the running total of the 2N/A * APPLICATION 0 header. The result is the total size of the header. 2N/A * The DH token length is the application length minus the length 2N/A * of the OID encoding. 2N/A /* Sanity check the token length */ 2N/A /* Check that this token is for this OID */ 2N/A /* Round up the header size to XDR boundry */ 2N/A /* Get the start of XDR encoded token */ 2N/A /* Create and XDR stream to decode from */ 2N/A * Clear the deserialized token (we'll have the xdr routines 2N/A * do the the allocations). 2N/A /* Zero out the signature */ 2N/A * Decode the DH_INIT_CNTX token. Note that at this point we have no 2N/A * session keys established, so that keys is null. The unencrypted 2N/A * signature will be made available to the caller in sig. The 2N/A * caller can then attempt to decrypt the session keys in token 2N/A * and encrypt the returned sig with those keys to check the 2N/A * integrity of the token. 2N/A * __get_token: Deserialize a supplied Diffie-Hellman token. Note the 2N/A * session keys should always be supplied to this routine. The message 2N/A * should only be supplied if the token is of DH_MIC type. 2N/A /* Create a an XDR stream out of the input token */ 2N/A /* Clear the token_desc and signature. */ 2N/A /* Decode the token */ 2N/A /* If we fail release the deserialized token */ 2N/A /* We always free the signature */ 2N/A * Warning these routines assumes that xdrs was created with xdrmem_create! 2N/A * __xdr_encode_token: Given an allocated xdrs stream serialize the supplied 2N/A * token_desc pointed to by objp, using keys to encrypt the signature. If 2N/A * msg is non null then calculate the signature over msg as well as the 2N/A * serialized token. Note this protocol is designed with the signature as 2N/A * the last part of any token. In this way the signature that is calculated is 2N/A * always done over the entire token. All fields in any token are thus 2N/A * protected from tampering 2N/A /* Check that xdrs is valid */ 2N/A /* Encode the protocol versioned body */ 2N/A /* Calculate the signature */ 2N/A /* Encode the signature */ 2N/A * __xdr_decode_token: Decode a token from an XDR stream into a token_desc 2N/A * pointed to by objp. We will calculate a signature over the serialized 2N/A * token and an optional message. The calculated signature will be 2N/A * returned to the caller in sig. If the supplied keys are available this 2N/A * routine will compare that the verifier in the deserialized token is 2N/A * the same as the calculated signature over the input stream. This is 2N/A * the usual case. However if the supplied serialized token is DH_INIT_CNTX, 2N/A * the keys have not yet been established. So we just give the caller back 2N/A * our raw signature (Non encrypted) and the deserialized token. Higher in 2N/A * the food chain (currently __dh_gss_accept_sec_context), we will attempt 2N/A * to decrypt the session keys and call __verify_sig with the decrypted 2N/A * session keys the signature returned from this routine and the deserialized 2N/A * Note it is assumed that sig does point to a valid uninitialized signature. 2N/A /* Check that we are decoding */ 2N/A /* Decode the protocol versioned body */ 2N/A /* Allocate the signature for this tokens QOP */ 2N/A * Call __mk_sig in crypto.c to calculate the signature based on 2N/A * the decoded QOP. __mk_sig will encrypt the signature with the 2N/A * supplied keys if they are available. If keys is null the signature 2N/A * will be just the unencrypted check sum. 2N/A /* Now decode the supplied signature */ 2N/A * If we have keys then we can check that the signatures