コード例 #1
0
ファイル: import_sec_context.c プロジェクト: janetuk/mech_eap
static OM_uint32
importKerberosKey(OM_uint32 *minor,
                  unsigned char **pBuf,
                  size_t *pRemain,
                  krb5_cksumtype *checksumType,
                  krb5_enctype *pEncryptionType,
                  krb5_keyblock *pKey)
{
    unsigned char *p = *pBuf;
    size_t remain = *pRemain;
    OM_uint32 encryptionType;
    OM_uint32 length;
    krb5_context krbContext;
    krb5_keyblock key;
    krb5_error_code code;

    GSSEAP_KRB_INIT(&krbContext);

    KRB_KEY_INIT(pKey);

    if (remain < 12) {
        *minor = GSSEAP_TOK_TRUNC;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    *checksumType  = load_uint32_be(&p[0]);
    encryptionType = load_uint32_be(&p[4]);
    length         = load_uint32_be(&p[8]);

    if ((length != 0) != (encryptionType != ENCTYPE_NULL)) {
        *minor = GSSEAP_BAD_CONTEXT_TOKEN;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    if (remain - 12 < length) {
        *minor = GSSEAP_TOK_TRUNC;
        return GSS_S_DEFECTIVE_TOKEN;
    }

    if (encryptionType != ENCTYPE_NULL) {
        KRB_KEY_INIT(&key);

        KRB_KEY_TYPE(&key)   = encryptionType;
        KRB_KEY_LENGTH(&key) = length;
        KRB_KEY_DATA(&key)   = &p[12];

        code = krb5_copy_keyblock_contents(krbContext, &key, pKey);
        if (code != 0) {
            *minor = code;
            return GSS_S_FAILURE;
        }
    }

    *pBuf    += 12 + length;
    *pRemain -= 12 + length;
    *pEncryptionType = encryptionType;

    *minor = 0;
    return GSS_S_COMPLETE;
}
コード例 #2
0
static OM_uint32
inquireSessionKey(OM_uint32 *minor,
                  const gss_ctx_id_t ctx,
                  const gss_OID desired_object GSSEAP_UNUSED,
                  gss_buffer_set_t *dataSet)
{
    OM_uint32 major;
    gss_buffer_desc buf;

    if (ctx->encryptionType == ENCTYPE_NULL) {
        major = GSS_S_UNAVAILABLE;
        *minor = GSSEAP_KEY_UNAVAILABLE;
        goto cleanup;
    }

    buf.length = KRB_KEY_LENGTH(&ctx->rfc3961Key);
    buf.value = KRB_KEY_DATA(&ctx->rfc3961Key);

    major = gss_add_buffer_set_member(minor, &buf, dataSet);
    if (GSS_ERROR(major))
        goto cleanup;

    major = addEnctypeOidToBufferSet(minor, ctx->encryptionType, dataSet);
    if (GSS_ERROR(major))
        goto cleanup;

    major = GSS_S_COMPLETE;
    *minor = 0;

cleanup:
    if (GSS_ERROR(major))
        zeroAndReleaseBufferSet(dataSet);

    return major;
}
コード例 #3
0
OM_uint32
gssEapExportSecContext(OM_uint32 *minor,
                       gss_ctx_id_t ctx,
                       gss_buffer_t token)
{
    OM_uint32 major, tmpMinor;
    size_t length;
    gss_buffer_desc initiatorName = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc acceptorName = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc partialCtx = GSS_C_EMPTY_BUFFER;
    gss_buffer_desc key;
    unsigned char *p;

    if ((CTX_IS_INITIATOR(ctx) && !CTX_IS_ESTABLISHED(ctx)) ||
        ctx->mechanismUsed == GSS_C_NO_OID) {
        *minor = GSSEAP_CONTEXT_INCOMPLETE;
        return GSS_S_NO_CONTEXT;
    }

    key.length = KRB_KEY_LENGTH(&ctx->rfc3961Key);
    key.value  = KRB_KEY_DATA(&ctx->rfc3961Key);

    if (ctx->initiatorName != GSS_C_NO_NAME) {
        major = gssEapExportNameInternal(minor, ctx->initiatorName,
                                         &initiatorName,
                                         EXPORT_NAME_FLAG_COMPOSITE);
        if (GSS_ERROR(major))
            goto cleanup;
    }

    if (ctx->acceptorName != GSS_C_NO_NAME) {
        major = gssEapExportNameInternal(minor, ctx->acceptorName,
                                         &acceptorName,
                                         EXPORT_NAME_FLAG_COMPOSITE);
        if (GSS_ERROR(major))
            goto cleanup;
    }

#ifdef GSSEAP_ENABLE_ACCEPTOR
    /*
     * The partial context is only transmitted for unestablished acceptor
     * contexts.
     */
    if (!CTX_IS_INITIATOR(ctx) && !CTX_IS_ESTABLISHED(ctx) &&
        (ctx->flags & CTX_FLAG_KRB_REAUTH) == 0) {
        major = gssEapExportPartialContext(minor, ctx, &partialCtx);
        if (GSS_ERROR(major))
            goto cleanup;
    }
#endif

    length  = 16;                               /* version, state, flags, */
    length += 4 + ctx->mechanismUsed->length;   /* mechanismUsed */
    length += 12 + key.length;                  /* rfc3961Key.value */
    length += 4 + initiatorName.length;         /* initiatorName.value */
    length += 4 + acceptorName.length;          /* acceptorName.value */
    length += 24 + sequenceSize(ctx->seqState); /* seqState */

    if (partialCtx.value != NULL)
        length += 4 + partialCtx.length;        /* partialCtx.value */

    token->value = GSSEAP_MALLOC(length);
    if (token->value == NULL) {
        major = GSS_S_FAILURE;
        *minor = ENOMEM;
        goto cleanup;
    }
    token->length = length;

    p = (unsigned char *)token->value;

    store_uint32_be(EAP_EXPORT_CONTEXT_V1, &p[0]);        /* version */
    store_uint32_be(GSSEAP_SM_STATE(ctx),  &p[4]);
    store_uint32_be(ctx->flags,            &p[8]);
    store_uint32_be(ctx->gssFlags,         &p[12]);
    p = store_oid(ctx->mechanismUsed,      &p[16]);

    store_uint32_be(ctx->checksumType,     &p[0]);
    store_uint32_be(ctx->encryptionType,   &p[4]);
    p = store_buffer(&key,                 &p[8], FALSE);

    p = store_buffer(&initiatorName,       p, FALSE);
    p = store_buffer(&acceptorName,        p, FALSE);

    store_uint64_be(ctx->expiryTime,       &p[0]);
    store_uint64_be(ctx->sendSeq,          &p[8]);
    store_uint64_be(ctx->recvSeq,          &p[16]);
    p += 24;

    major = sequenceExternalize(minor, ctx->seqState, &p, &length);
    if (GSS_ERROR(major))
        goto cleanup;

    if (partialCtx.value != NULL)
        p = store_buffer(&partialCtx, p, FALSE);

    GSSEAP_ASSERT(p == (unsigned char *)token->value + token->length);

    major = GSS_S_COMPLETE;
    *minor = 0;

cleanup:
    if (GSS_ERROR(major))
        gss_release_buffer(&tmpMinor, token);
    gss_release_buffer(&tmpMinor, &initiatorName);
    gss_release_buffer(&tmpMinor, &acceptorName);
    gss_release_buffer(&tmpMinor, &partialCtx);

    return major;
}