~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/ssl/prelib.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
 
2
 
 
3
/*
 
4
 * Functions used by https servers to send (download) pre-encrypted files
 
5
 * over SSL connections that use Fortezza ciphersuites.
 
6
 *
 
7
 * The contents of this file are subject to the Mozilla Public
 
8
 * License Version 1.1 (the "License"); you may not use this file
 
9
 * except in compliance with the License. You may obtain a copy of
 
10
 * the License at http://www.mozilla.org/MPL/
 
11
 * 
 
12
 * Software distributed under the License is distributed on an "AS
 
13
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
14
 * implied. See the License for the specific language governing
 
15
 * rights and limitations under the License.
 
16
 * 
 
17
 * The Original Code is the Netscape security libraries.
 
18
 * 
 
19
 * The Initial Developer of the Original Code is Netscape
 
20
 * Communications Corporation.  Portions created by Netscape are 
 
21
 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 
22
 * Rights Reserved.
 
23
 * 
 
24
 * Contributor(s):
 
25
 * 
 
26
 * Alternatively, the contents of this file may be used under the
 
27
 * terms of the GNU General Public License Version 2 or later (the
 
28
 * "GPL"), in which case the provisions of the GPL are applicable 
 
29
 * instead of those above.  If you wish to allow use of your 
 
30
 * version of this file only under the terms of the GPL and not to
 
31
 * allow others to use your version of this file under the MPL,
 
32
 * indicate your decision by deleting the provisions above and
 
33
 * replace them with the notice and other provisions required by
 
34
 * the GPL.  If you do not delete the provisions above, a recipient
 
35
 * may use your version of this file under either the MPL or the
 
36
 * GPL.
 
37
 *
 
38
 * $Id: prelib.c,v 1.2 2001/02/09 02:11:30 nelsonb%netscape.com Exp $
 
39
 */
 
40
 
 
41
#include "cert.h"
 
42
#include "ssl.h"
 
43
#include "keyhi.h"
 
44
#include "secitem.h"
 
45
#include "sslimpl.h"
 
46
#include "pkcs11t.h"
 
47
#include "preenc.h"
 
48
#include "pk11func.h"
 
49
 
 
50
static unsigned char fromHex(char x) {
 
51
    if ((x >= '0') && (x <= '9')) return x-'0';
 
52
    if ((x >= 'a') && (x <= 'f')) return x-'a'+10;
 
53
    return x-'A'+10;
 
54
}
 
55
 
 
56
PEHeader *SSL_PreencryptedStreamToFile(PRFileDesc *fd, PEHeader *inHeader, 
 
57
                                                                int *headerSize)
 
58
{
 
59
    PK11SymKey *key, *tek, *Ks;
 
60
    sslSocket *ss;
 
61
    PK11SlotInfo *slot;
 
62
    CK_TOKEN_INFO info;
 
63
    int oldHeaderSize;
 
64
    PEHeader *header;
 
65
    SECStatus rv;
 
66
    SECItem item;
 
67
    int i;
 
68
    
 
69
    if (fd == NULL) {
 
70
        /* XXX set an error */
 
71
        return NULL;
 
72
    }
 
73
    
 
74
    ss = ssl_FindSocket(fd);
 
75
    if (ss == NULL) {
 
76
        return NULL;
 
77
    }
 
78
    
 
79
    PORT_Assert(ss->ssl3 != NULL);
 
80
    if (ss->ssl3 == NULL) {
 
81
        return NULL;
 
82
    }
 
83
 
 
84
    if (GetInt2(inHeader->magic) != PRE_MAGIC) {
 
85
        return NULL;
 
86
    }
 
87
 
 
88
    oldHeaderSize = GetInt2(inHeader->len);
 
89
    header = (PEHeader *) PORT_ZAlloc(oldHeaderSize);
 
90
    if (header == NULL) {
 
91
        return NULL;
 
92
    }
 
93
 
 
94
    switch (GetInt2(inHeader->type)) {
 
95
    case PRE_FORTEZZA_FILE:
 
96
    case PRE_FORTEZZA_GEN_STREAM:
 
97
    case PRE_FIXED_FILE:
 
98
    case PRE_RSA_FILE:
 
99
    default:
 
100
        *headerSize = oldHeaderSize;
 
101
        PORT_Memcpy(header,inHeader,oldHeaderSize);
 
102
        return header;
 
103
 
 
104
    case PRE_FORTEZZA_STREAM:
 
105
        *headerSize = PE_BASE_HEADER_LEN + sizeof(PEFortezzaHeader);
 
106
        PutInt2(header->magic,PRE_MAGIC);
 
107
        PutInt2(header->len,*headerSize);
 
108
        PutInt2(header->type, PRE_FORTEZZA_FILE);
 
109
        PORT_Memcpy(header->version,inHeader->version,sizeof(header->version));
 
110
        PORT_Memcpy(header->u.fortezza.hash,inHeader->u.fortezza.hash,
 
111
                                             sizeof(header->u.fortezza.hash));
 
112
        PORT_Memcpy(header->u.fortezza.iv,inHeader->u.fortezza.iv,
 
113
                                              sizeof(header->u.fortezza.iv));
 
114
 
 
115
        /* get the kea context from the session */
 
116
        tek = ss->ssl3->fortezza.tek;
 
117
        if (tek == NULL) {
 
118
            PORT_Free(header);
 
119
            return NULL;
 
120
        }
 
121
 
 
122
 
 
123
        /* get the slot and the serial number */
 
124
        slot = PK11_GetSlotFromKey(tek);
 
125
        if (slot == NULL) {
 
126
            PORT_Free(header);
 
127
            return NULL;
 
128
        }
 
129
        rv = PK11_GetTokenInfo(slot,&info);
 
130
        if (rv != SECSuccess) {
 
131
            PORT_Free(header);
 
132
            PK11_FreeSlot(slot);
 
133
            return NULL;
 
134
        }
 
135
 
 
136
        /* Look up the Token Fixed Key */
 
137
        Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, ss->pkcs11PinArg);
 
138
        PK11_FreeSlot(slot);
 
139
        if (Ks == NULL) {
 
140
            PORT_Free(header);
 
141
            return NULL;
 
142
        }
 
143
 
 
144
        /* unwrap the key with the TEK */
 
145
        item.data = inHeader->u.fortezza.key;
 
146
        item.len = sizeof(inHeader->u.fortezza.key);
 
147
        key = PK11_UnwrapSymKey(tek,CKM_SKIPJACK_WRAP,
 
148
                        NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
 
149
        if (key == NULL) {
 
150
            PORT_Free(header);
 
151
            PK11_FreeSymKey(Ks);
 
152
            return NULL;
 
153
        }
 
154
 
 
155
        /* rewrap with the local Ks */
 
156
        item.data = header->u.fortezza.key;
 
157
        item.len = sizeof(header->u.fortezza.key);
 
158
        rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, Ks, key, &item);
 
159
        PK11_FreeSymKey(Ks);
 
160
        PK11_FreeSymKey(key);
 
161
        if (rv != SECSuccess) {
 
162
            PORT_Free(header);
 
163
            return NULL;
 
164
        }
 
165
    
 
166
        /* copy our local serial number into header */
 
167
        for (i=0; i < sizeof(header->u.fortezza.serial); i++) {
 
168
            header->u.fortezza.serial[i] = 
 
169
                (fromHex(info.serialNumber[i*2]) << 4)  |
 
170
                                        fromHex(info.serialNumber[i*2 + 1]);
 
171
        }
 
172
        break;
 
173
    case PRE_FIXED_STREAM:
 
174
        /* not implemented yet */
 
175
        PORT_Free(header);
 
176
        return NULL;
 
177
    }
 
178
    
 
179
    return(header);
 
180
}
 
181
 
 
182
/*
 
183
 * this one needs to allocate space and work for RSA & FIXED key files as well
 
184
 */
 
185
PEHeader *SSL_PreencryptedFileToStream(PRFileDesc *fd, PEHeader *header, 
 
186
                                                        int *headerSize)
 
187
{
 
188
    PK11SymKey *key, *tek, *Ks;
 
189
    sslSocket *ss;
 
190
    PK11SlotInfo *slot;
 
191
    SECStatus rv;
 
192
    SECItem item;
 
193
    
 
194
    *headerSize = 0; /* hack */
 
195
 
 
196
    if (fd == NULL) {
 
197
        /* XXX set an error */
 
198
        return NULL;
 
199
    }
 
200
    
 
201
    ss = ssl_FindSocket(fd);
 
202
    if (ss == NULL) {
 
203
        return NULL;
 
204
    }
 
205
    
 
206
    PORT_Assert(ss->ssl3 != NULL);
 
207
    if (ss->ssl3 == NULL) {
 
208
        return NULL;
 
209
    }
 
210
 
 
211
    /* get the kea context from the session */
 
212
    tek = ss->ssl3->fortezza.tek;
 
213
    if (tek == NULL) {
 
214
        return NULL;
 
215
    }
 
216
 
 
217
    slot = PK11_GetSlotFromKey(tek);
 
218
    if (slot == NULL) return NULL;
 
219
    Ks = PK11_FindFixedKey(slot, CKM_SKIPJACK_WRAP, NULL, PK11_GetWindow(tek));
 
220
    PK11_FreeSlot(slot);
 
221
    if (Ks == NULL) return NULL;
 
222
 
 
223
 
 
224
    /* unwrap with the local Ks */
 
225
    item.data = header->u.fortezza.key;
 
226
    item.len = sizeof(header->u.fortezza.key);
 
227
    /* rewrap the key with the TEK */
 
228
    key = PK11_UnwrapSymKey(Ks,CKM_SKIPJACK_WRAP,
 
229
                        NULL, &item, CKM_SKIPJACK_CBC64, CKA_DECRYPT, 0);
 
230
    if (key == NULL) {
 
231
        PK11_FreeSymKey(Ks);
 
232
        return NULL;
 
233
    }
 
234
 
 
235
    rv = PK11_WrapSymKey(CKM_SKIPJACK_WRAP, NULL, tek, key, &item);
 
236
    PK11_FreeSymKey(Ks);
 
237
    PK11_FreeSymKey(key);
 
238
    if (rv != SECSuccess) {
 
239
        return NULL;
 
240
    }
 
241
    
 
242
    /* copy over our local serial number */
 
243
    PORT_Memset(header->u.fortezza.serial,0,sizeof(header->u.fortezza.serial));
 
244
    
 
245
    /* change type to stream */
 
246
    PutInt2(header->type, PRE_FORTEZZA_STREAM);
 
247
    
 
248
    return(header);
 
249
}
 
250
 
 
251