~ubuntu-branches/ubuntu/maverick/krb5/maverick

« back to all changes in this revision

Viewing changes to src/lib/crypto/crypto_length.c

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2009-05-07 16:16:34 UTC
  • mfrom: (13.1.7 sid)
  • Revision ID: james.westby@ubuntu.com-20090507161634-xqyk0s9na0le4flj
Tags: 1.7dfsg~beta1-4
When  decrypting the TGS response fails with the subkey, try with the
session key to work around Heimdal bug, Closes: #527353 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lib/crypto/crypto_length.c
 
3
 *
 
4
 * Copyright 2008 by the Massachusetts Institute of Technology.
 
5
 * All Rights Reserved.
 
6
 *
 
7
 * Export of this software from the United States of America may
 
8
 *   require a specific license from the United States Government.
 
9
 *   It is the responsibility of any person or organization contemplating
 
10
 *   export to obtain such a license before exporting.
 
11
 * 
 
12
 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
 
13
 * distribute this software and its documentation for any purpose and
 
14
 * without fee is hereby granted, provided that the above copyright
 
15
 * notice appear in all copies and that both that copyright notice and
 
16
 * this permission notice appear in supporting documentation, and that
 
17
 * the name of M.I.T. not be used in advertising or publicity pertaining
 
18
 * to distribution of the software without specific, written prior
 
19
 * permission.  Furthermore if you modify this software you must label
 
20
 * your software as modified software and not distribute it in such a
 
21
 * fashion that it might be confused with the original M.I.T. software.
 
22
 * M.I.T. makes no representations about the suitability of
 
23
 * this software for any purpose.  It is provided "as is" without express
 
24
 * or implied warranty.
 
25
 */
 
26
 
 
27
#include "k5-int.h"
 
28
#include "etypes.h"
 
29
#include "aead.h"
 
30
 
 
31
krb5_error_code KRB5_CALLCONV
 
32
krb5_c_crypto_length(krb5_context context,
 
33
                     krb5_enctype enctype,
 
34
                     krb5_cryptotype type,
 
35
                     unsigned int *size)
 
36
{
 
37
    int i;
 
38
    const struct krb5_keytypes *ktp = NULL;
 
39
    krb5_error_code ret;
 
40
 
 
41
    for (i = 0; i < krb5_enctypes_length; i++) {
 
42
        if (krb5_enctypes_list[i].etype == enctype) {
 
43
            ktp = &krb5_enctypes_list[i];
 
44
            break;
 
45
        }
 
46
    }
 
47
 
 
48
    if (ktp == NULL || ktp->aead == NULL) {
 
49
        return KRB5_BAD_ENCTYPE;
 
50
    }
 
51
 
 
52
    switch (type) {
 
53
    case KRB5_CRYPTO_TYPE_EMPTY:
 
54
    case KRB5_CRYPTO_TYPE_SIGN_ONLY:
 
55
        *size = 0;
 
56
        ret = 0;
 
57
        break;
 
58
    case KRB5_CRYPTO_TYPE_DATA:
 
59
        *size = (size_t)~0; /* match Heimdal */
 
60
        ret = 0;
 
61
        break;
 
62
    case KRB5_CRYPTO_TYPE_HEADER:
 
63
    case KRB5_CRYPTO_TYPE_PADDING:
 
64
    case KRB5_CRYPTO_TYPE_TRAILER:
 
65
    case KRB5_CRYPTO_TYPE_CHECKSUM:
 
66
        ret = ktp->aead->crypto_length(ktp->aead, ktp->enc, ktp->hash, type, size);
 
67
        break;
 
68
    default:
 
69
        ret = EINVAL;
 
70
        break;
 
71
    }
 
72
 
 
73
    return ret;
 
74
}
 
75
 
 
76
krb5_error_code KRB5_CALLCONV
 
77
krb5_c_padding_length(krb5_context context,
 
78
                      krb5_enctype enctype,
 
79
                      size_t data_length,
 
80
                      unsigned int *pad_length)
 
81
{
 
82
    int i;
 
83
    const struct krb5_keytypes *ktp = NULL;
 
84
 
 
85
    for (i = 0; i < krb5_enctypes_length; i++) {
 
86
        if (krb5_enctypes_list[i].etype == enctype) {
 
87
            ktp = &krb5_enctypes_list[i];
 
88
            break;
 
89
        }
 
90
    }
 
91
 
 
92
    if (ktp == NULL || ktp->aead == NULL) {
 
93
        return KRB5_BAD_ENCTYPE;
 
94
    }
 
95
 
 
96
    return krb5int_c_padding_length(ktp->aead, ktp->enc, ktp->hash, data_length, pad_length);
 
97
}
 
98
 
 
99
krb5_error_code KRB5_CALLCONV
 
100
krb5_c_crypto_length_iov(krb5_context context,
 
101
                         krb5_enctype enctype,
 
102
                         krb5_crypto_iov *data,
 
103
                         size_t num_data)
 
104
{
 
105
    krb5_error_code ret = 0;
 
106
    size_t i;
 
107
    const struct krb5_keytypes *ktp = NULL;
 
108
    unsigned int data_length = 0, pad_length;
 
109
    krb5_crypto_iov *padding = NULL;
 
110
 
 
111
    /*
 
112
     * XXX need to rejig internal interface so we can accurately
 
113
     * report variable header lengths
 
114
     */
 
115
 
 
116
    for (i = 0; i < (size_t)krb5_enctypes_length; i++) {
 
117
        if (krb5_enctypes_list[i].etype == enctype) {
 
118
            ktp = &krb5_enctypes_list[i];
 
119
            break;
 
120
        }
 
121
    }
 
122
 
 
123
    if (ktp == NULL || ktp->aead == NULL) {
 
124
        return KRB5_BAD_ENCTYPE;
 
125
    }
 
126
 
 
127
    for (i = 0; i < num_data; i++) {
 
128
        krb5_crypto_iov *iov = &data[i];
 
129
 
 
130
        switch (iov->flags) {
 
131
        case KRB5_CRYPTO_TYPE_DATA:
 
132
            data_length += iov->data.length;
 
133
            break;
 
134
        case KRB5_CRYPTO_TYPE_PADDING:
 
135
            if (padding != NULL)
 
136
                return EINVAL;
 
137
 
 
138
            padding = iov;
 
139
            break;
 
140
        case KRB5_CRYPTO_TYPE_HEADER:
 
141
        case KRB5_CRYPTO_TYPE_TRAILER:
 
142
        case KRB5_CRYPTO_TYPE_CHECKSUM:
 
143
            ret = ktp->aead->crypto_length(ktp->aead, ktp->enc, ktp->hash, iov->flags, &iov->data.length);
 
144
            break;
 
145
        case KRB5_CRYPTO_TYPE_EMPTY:
 
146
        case KRB5_CRYPTO_TYPE_SIGN_ONLY:
 
147
        default:
 
148
            break;
 
149
        }
 
150
 
 
151
        if (ret != 0)
 
152
            break;
 
153
    }
 
154
 
 
155
    if (ret != 0)
 
156
        return ret;
 
157
 
 
158
    ret = krb5int_c_padding_length(ktp->aead, ktp->enc, ktp->hash, data_length, &pad_length);
 
159
    if (ret != 0)
 
160
        return ret;
 
161
 
 
162
    if (pad_length != 0 && padding == NULL)
 
163
        return EINVAL;
 
164
 
 
165
    if (padding != NULL)
 
166
        padding->data.length = pad_length;
 
167
 
 
168
    return 0;
 
169
}
 
170