OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [net/] [snmp/] [lib/] [v2_0/] [src/] [keytools.c] - Blame information for rev 201

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      ./lib/current/src/keytools.c
4
//
5
//
6
//==========================================================================
7
//####ECOSGPLCOPYRIGHTBEGIN####
8
// -------------------------------------------
9
// This file is part of eCos, the Embedded Configurable Operating System.
10
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
11
//
12
// eCos is free software; you can redistribute it and/or modify it under
13
// the terms of the GNU General Public License as published by the Free
14
// Software Foundation; either version 2 or (at your option) any later version.
15
//
16
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
17
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
18
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
19
// for more details.
20
//
21
// You should have received a copy of the GNU General Public License along
22
// with eCos; if not, write to the Free Software Foundation, Inc.,
23
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
24
//
25
// As a special exception, if other files instantiate templates or use macros
26
// or inline functions from this file, or you compile this file and link it
27
// with other works to produce a work based on this file, this file does not
28
// by itself cause the resulting work to be covered by the GNU General Public
29
// License. However the source code for this file must still be made available
30
// in accordance with section (3) of the GNU General Public License.
31
//
32
// This exception does not invalidate any other reasons why a work based on
33
// this file might be covered by the GNU General Public License.
34
//
35
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
36
// at http://sources.redhat.com/ecos/ecos-license/
37
// -------------------------------------------
38
//####ECOSGPLCOPYRIGHTEND####
39
//####UCDSNMPCOPYRIGHTBEGIN####
40
//
41
// -------------------------------------------
42
//
43
// Portions of this software may have been derived from the UCD-SNMP
44
// project,  <http://ucd-snmp.ucdavis.edu/>  from the University of
45
// California at Davis, which was originally based on the Carnegie Mellon
46
// University SNMP implementation.  Portions of this software are therefore
47
// covered by the appropriate copyright disclaimers included herein.
48
//
49
// The release used was version 4.1.2 of May 2000.  "ucd-snmp-4.1.2"
50
// -------------------------------------------
51
//
52
//####UCDSNMPCOPYRIGHTEND####
53
//==========================================================================
54
//#####DESCRIPTIONBEGIN####
55
//
56
// Author(s):    hmt
57
// Contributors: hmt
58
// Date:         2000-05-30
59
// Purpose:      Port of UCD-SNMP distribution to eCos.
60
// Description:  
61
//              
62
//
63
//####DESCRIPTIONEND####
64
//
65
//==========================================================================
66
/********************************************************************
67
       Copyright 1989, 1991, 1992 by Carnegie Mellon University
68
 
69
                          Derivative Work -
70
Copyright 1996, 1998, 1999, 2000 The Regents of the University of California
71
 
72
                         All Rights Reserved
73
 
74
Permission to use, copy, modify and distribute this software and its
75
documentation for any purpose and without fee is hereby granted,
76
provided that the above copyright notice appears in all copies and
77
that both that copyright notice and this permission notice appear in
78
supporting documentation, and that the name of CMU and The Regents of
79
the University of California not be used in advertising or publicity
80
pertaining to distribution of the software without specific written
81
permission.
82
 
83
CMU AND THE REGENTS OF THE UNIVERSITY OF CALIFORNIA DISCLAIM ALL
84
WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED
85
WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL CMU OR
86
THE REGENTS OF THE UNIVERSITY OF CALIFORNIA BE LIABLE FOR ANY SPECIAL,
87
INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
88
FROM THE LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
89
CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
90
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
91
*********************************************************************/
92
/*
93
 * keytools.c
94
 */
95
 
96
#include <config.h>
97
 
98
#ifdef CYGPKG_SNMPAGENT_V3_SUPPORT
99
#include <stdio.h>
100
#include <sys/types.h>
101
#if HAVE_WINSOCK_H
102
#include <winsock.h>
103
#endif
104
#ifdef HAVE_NETINET_IN_H
105
#include <netinet/in.h>
106
#endif
107
#ifdef HAVE_STDLIB_H
108
#include <stdlib.h>
109
#endif
110
#if HAVE_STRING_H
111
#include <string.h>
112
#else
113
#include <strings.h>
114
#endif
115
 
116
#if HAVE_DMALLOC_H
117
#include <dmalloc.h>
118
#endif
119
 
120
#include "asn1.h"
121
#include "snmp_api.h"
122
#ifdef USE_OPENSSL
123
#       include <openssl/hmac.h>
124
#else 
125
#ifdef USE_INTERNAL_MD5
126
#include "md5.h"
127
#endif
128
#endif
129
 
130
#include "scapi.h"
131
#include "keytools.h"
132
#include "tools.h"
133
#include "snmp_debug.h"
134
#include "snmp_logging.h"
135
 
136
#include "transform_oids.h"
137
 
138
/*******************************************************************-o-******
139
 * generate_Ku
140
 *
141
 * Parameters:
142
 *      *hashtype       MIB OID for the transform type for hashing.
143
 *       hashtype_len   Length of OID value.
144
 *      *P              Pre-allocated bytes of passpharase.
145
 *       pplen          Length of passphrase.
146
 *      *Ku             Buffer to contain Ku.
147
 *      *kulen          Length of Ku buffer.
148
 *
149
 * Returns:
150
 *      SNMPERR_SUCCESS                 Success.
151
 *      SNMPERR_GENERR                  All errors.
152
 *
153
 *
154
 * Convert a passphrase into a master user key, Ku, according to the
155
 * algorithm given in RFC 2274 concerning the SNMPv3 User Security Model (USM)
156
 * as follows:
157
 *
158
 * Expand the passphrase to fill the passphrase buffer space, if necessary,
159
 * concatenation as many duplicates as possible of P to itself.  If P is
160
 * larger than the buffer space, truncate it to fit.
161
 *
162
 * Then hash the result with the given hashtype transform.  Return
163
 * the result as Ku.
164
 *
165
 * If successful, kulen contains the size of the hash written to Ku.
166
 *
167
 * NOTE  Passphrases less than USM_LENGTH_P_MIN characters in length
168
 *       cause an error to be returned.
169
 *       (Punt this check to the cmdline apps?  XXX)
170
 */
171
int
172
generate_Ku(    oid     *hashtype,      u_int  hashtype_len,
173
                u_char  *P,             size_t  pplen,
174
                u_char  *Ku,            size_t *kulen)
175
#if defined(USE_INTERNAL_MD5) || defined(USE_OPENSSL)
176
{
177
        int              rval   = SNMPERR_SUCCESS,
178
                         nbytes = USM_LENGTH_EXPANDED_PASSPHRASE;
179
 
180
        u_int            i, pindex = 0;
181
 
182
        u_char           buf[USM_LENGTH_KU_HASHBLOCK],
183
                        *bufp;
184
 
185
#ifdef USE_OPENSSL
186
        EVP_MD_CTX      *ctx = malloc(sizeof(EVP_MD_CTX));
187
#else
188
        MDstruct         MD;
189
#endif
190
        /*
191
         * Sanity check.
192
         */
193
        if ( !hashtype || !P || !Ku || !kulen
194
                || (*kulen<=0)
195
                || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
196
        {
197
                QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
198
        }
199
 
200
        if (pplen < USM_LENGTH_P_MIN) {
201
#ifdef SNMP_TESTING_CODE
202
          snmp_log(LOG_WARNING, "Warning: passphrase chosen is below the length requiremnts of the USM.\n");
203
#else
204
          snmp_set_detail("Password length too short.");
205
          QUITFUN(SNMPERR_GENERR, generate_Ku_quit);
206
#endif
207
        }
208
 
209
 
210
        /*
211
         * Setup for the transform type.
212
         */
213
#ifdef USE_OPENSSL
214
 
215
        if (ISTRANSFORM(hashtype, HMACMD5Auth))
216
          EVP_DigestInit(ctx, EVP_md5());
217
        else if (ISTRANSFORM(hashtype, HMACSHA1Auth))
218
          EVP_DigestInit(ctx, EVP_sha1());
219
        else  {
220
          free(ctx);
221
          return (SNMPERR_GENERR);
222
        }
223
#else 
224
        MDbegin(&MD);
225
#endif /* USE_OPENSSL */
226
 
227
        while (nbytes > 0) {
228
                bufp = buf;
229
                for (i = 0; i < USM_LENGTH_KU_HASHBLOCK; i++) {
230
                        *bufp++ = P[pindex++ % pplen];
231
                }
232
#ifdef USE_OPENSSL
233
                EVP_DigestUpdate(ctx, buf, USM_LENGTH_KU_HASHBLOCK);
234
#else
235
                if (MDupdate(&MD, buf, USM_LENGTH_KU_HASHBLOCK*8)) {
236
                    rval = SNMPERR_USM_ENCRYPTIONERROR;
237
                    goto md5_fin;
238
                }
239
#endif /* USE_OPENSSL */
240
 
241
                nbytes -= USM_LENGTH_KU_HASHBLOCK;
242
        }
243
 
244
#ifdef USE_OPENSSL
245
        EVP_DigestFinal(ctx, (unsigned char *) Ku, (unsigned int *) kulen);
246
        /* what about free() */
247
#else
248
        if (MDupdate(&MD, buf, 0)) {
249
            rval = SNMPERR_USM_ENCRYPTIONERROR;
250
            goto md5_fin;
251
        }
252
        *kulen = sc_get_properlength(hashtype, hashtype_len);
253
        MDget(&MD, Ku, *kulen);
254
md5_fin:
255
        memset(&MD, 0, sizeof(MD));
256
#endif /* USE_OPENSSL */
257
 
258
 
259
#ifdef SNMP_TESTING_CODE
260
        DEBUGMSGTL(("generate_Ku", "generating Ku (from %s): ", P));
261
        for(i=0; i < *kulen; i++)
262
          DEBUGMSG(("generate_Ku", "%02x",Ku[i]));
263
        DEBUGMSG(("generate_Ku","\n"));
264
#endif /* SNMP_TESTING_CODE */
265
 
266
 
267
generate_Ku_quit:
268
        memset(buf, 0, sizeof(buf));
269
#ifdef USE_OPENSSL
270
        free(ctx);
271
#endif
272
        return rval;
273
 
274
}  /* end generate_Ku() */
275
 
276
#else
277
_KEYTOOLS_NOT_AVAILABLE
278
#endif                                          /* internal or openssl */
279
 
280
 
281
 
282
 
283
/*******************************************************************-o-******
284
 * generate_kul
285
 *
286
 * Parameters:
287
 *      *hashtype
288
 *       hashtype_len
289
 *      *engineID
290
 *       engineID_len
291
 *      *Ku             Master key for a given user.
292
 *       ku_len         Length of Ku in bytes.
293
 *      *Kul            Localized key for a given user at engineID.
294
 *      *kul_len        Length of Kul buffer (IN); Length of Kul key (OUT).
295
 *
296
 * Returns:
297
 *      SNMPERR_SUCCESS                 Success.
298
 *      SNMPERR_GENERR                  All errors.
299
 *
300
 *
301
 * Ku MUST be the proper length (currently fixed) for the given hashtype.
302
 *
303
 * Upon successful return, Kul contains the localized form of Ku at
304
 * engineID, and the length of the key is stored in kul_len.
305
 *
306
 * The localized key method is defined in RFC2274, Sections 2.6 and A.2, and
307
 * originally documented in:
308
 *      U. Blumenthal, N. C. Hien, B. Wijnen,
309
 *      "Key Derivation for Network Management Applications",
310
 *      IEEE Network Magazine, April/May issue, 1997.
311
 *
312
 *
313
 * ASSUMES  SNMP_MAXBUF >= sizeof(Ku + engineID + Ku).
314
 *
315
 * NOTE  Localized keys for privacy transforms are generated via
316
 *       the authentication transform held by the same usmUser.
317
 *
318
 * XXX  An engineID of any length is accepted, even if larger than
319
 *      what is spec'ed for the textual convention.
320
 */
321
int
322
generate_kul(   oid     *hashtype,      u_int  hashtype_len,
323
                u_char  *engineID,      size_t  engineID_len,
324
                u_char  *Ku,            size_t  ku_len,
325
                u_char  *Kul,           size_t *kul_len)
326
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5)
327
{
328
        int              rval    = SNMPERR_SUCCESS;
329
        u_int            nbytes  = 0;
330
        size_t           properlength;
331
 
332
        u_char           buf[SNMP_MAXBUF];
333
        void            *context = NULL;
334
#ifdef SNMP_TESTING_CODE
335
        int              i;
336
#endif
337
 
338
 
339
        /*
340
         * Sanity check.
341
         */
342
        if ( !hashtype || !engineID || !Ku || !Kul || !kul_len
343
                || (engineID_len<=0) || (ku_len<=0) || (*kul_len<=0)
344
                || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
345
        {
346
                QUITFUN(SNMPERR_GENERR, generate_kul_quit);
347
        }
348
 
349
 
350
        properlength = sc_get_properlength(hashtype, hashtype_len);
351
        if (properlength == SNMPERR_GENERR)
352
          QUITFUN(SNMPERR_GENERR, generate_kul_quit);
353
 
354
 
355
        if (((int)*kul_len < properlength) || ((int)ku_len < properlength) ) {
356
                QUITFUN(SNMPERR_GENERR, generate_kul_quit);
357
        }
358
 
359
        /*
360
         * Concatenate Ku and engineID properly, then hash the result.
361
         * Store it in Kul.
362
         */
363
        nbytes = 0;
364
        memcpy(buf,        Ku,          properlength); nbytes += properlength;
365
        memcpy(buf+nbytes, engineID,    engineID_len); nbytes += engineID_len;
366
        memcpy(buf+nbytes, Ku,          properlength); nbytes += properlength;
367
 
368
        rval = sc_hash(hashtype, hashtype_len, buf, nbytes, Kul, kul_len);
369
 
370
#ifdef SNMP_TESTING_CODE
371
        DEBUGMSGTL(("generate_kul", "generating Kul (from Ku): "));
372
        for(i=0; i < *kul_len; i++)
373
          DEBUGMSG(("generate_kul", "%02x",Kul[i]));
374
        DEBUGMSG(("generate_kul", "keytools\n"));
375
#endif /* SNMP_TESTING_CODE */
376
 
377
        QUITFUN(rval, generate_kul_quit);
378
 
379
 
380
generate_kul_quit:
381
        SNMP_FREE(context);
382
        return rval;
383
 
384
}  /* end generate_kul() */
385
 
386
#else
387
_KEYTOOLS_NOT_AVAILABLE
388
#endif                                          /* internal or openssl */
389
 
390
 
391
 
392
 
393
/*******************************************************************-o-******
394
 * encode_keychange
395
 *
396
 * Parameters:
397
 *      *hashtype       MIB OID for the hash transform type.
398
 *       hashtype_len   Length of the MIB OID hash transform type.
399
 *      *oldkey         Old key that is used to encodes the new key.
400
 *       oldkey_len     Length of oldkey in bytes.
401
 *      *newkey         New key that is encoded using the old key.
402
 *       newkey_len     Length of new key in bytes.
403
 *      *kcstring       Buffer to contain the KeyChange TC string.
404
 *      *kcstring_len   Length of kcstring buffer.
405
 *
406
 * Returns:
407
 *      SNMPERR_SUCCESS                 Success.
408
 *      SNMPERR_GENERR                  All errors.
409
 *
410
 *
411
 * Uses oldkey and acquired random bytes to encode newkey into kcstring
412
 * according to the rules of the KeyChange TC described in RFC 2274, Section 5.
413
 *
414
 * Upon successful return, *kcstring_len contains the length of the
415
 * encoded string.
416
 *
417
 * ASSUMES      Old and new key are always equal to each other, although
418
 *              this may be less than the transform type hash output
419
 *              output length (eg, using KeyChange for a DESPriv key when
420
 *              the user also uses SHA1Auth).  This also implies that the
421
 *              hash placed in the second 1/2 of the key change string
422
 *              will be truncated before the XOR'ing when the hash output is
423
 *              larger than that 1/2 of the key change string.
424
 *
425
 *              *kcstring_len will be returned as exactly twice that same
426
 *              length though the input buffer may be larger.
427
 *
428
 * XXX FIX:     Does not handle varibable length keys.
429
 * XXX FIX:     Does not handle keys larger than the hash algorithm used.
430
 */
431
int
432
encode_keychange(       oid     *hashtype,      u_int  hashtype_len,
433
                        u_char  *oldkey,        size_t  oldkey_len,
434
                        u_char  *newkey,        size_t  newkey_len,
435
                        u_char  *kcstring,      size_t *kcstring_len)
436
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5)
437
{
438
        int              rval    = SNMPERR_SUCCESS;
439
        size_t           properlength;
440
        size_t            nbytes  = 0;
441
 
442
        u_char          *tmpbuf = NULL;
443
        void            *context = NULL;
444
 
445
 
446
        /*
447
         * Sanity check.
448
         */
449
        if ( !hashtype || !oldkey || !newkey || !kcstring || !kcstring_len
450
                || (oldkey_len<=0) || (newkey_len<=0) || (*kcstring_len<=0)
451
                || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
452
        {
453
                QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
454
        }
455
 
456
        /*
457
         * Setup for the transform type.
458
         */
459
        properlength = sc_get_properlength(hashtype, hashtype_len);
460
        if (properlength == SNMPERR_GENERR)
461
          QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
462
 
463
        if ( (oldkey_len != newkey_len) || (*kcstring_len < (2*oldkey_len)) )
464
        {
465
                QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
466
        }
467
 
468
        properlength = SNMP_MIN((int)oldkey_len, properlength);
469
 
470
        /*
471
         * Use the old key and some random bytes to encode the new key
472
         * in the KeyChange TC format:
473
         *      . Get random bytes (store in first half of kcstring),
474
         *      . Hash (oldkey | random_bytes) (into second half of kcstring),
475
         *      . XOR hash and newkey (into second half of kcstring).
476
         *
477
         * Getting the wrong number of random bytes is considered an error.
478
         */
479
        nbytes = properlength;
480
 
481
#if defined(SNMP_TESTING_CODE) && defined(RANDOMZEROS)
482
                memset(kcstring, 0, nbytes);
483
                DEBUGMSG(("encode_keychange",
484
                          "** Using all zero bits for \"random\" delta of )"
485
                          "the keychange string! **\n"));
486
#else /* !SNMP_TESTING_CODE */
487
                rval = sc_random(kcstring, &nbytes);
488
                QUITFUN(rval, encode_keychange_quit);
489
                if ((int)nbytes != properlength) {
490
                        QUITFUN(SNMPERR_GENERR, encode_keychange_quit);
491
                }
492
#endif /* !SNMP_TESTING_CODE */
493
 
494
        tmpbuf = (u_char *)malloc(properlength*2);
495
        if (tmpbuf) {
496
            memcpy(tmpbuf, oldkey, properlength);
497
            memcpy(tmpbuf+properlength, kcstring, properlength);
498
 
499
            *kcstring_len -= properlength;
500
            rval = sc_hash(hashtype, hashtype_len, tmpbuf, properlength*2,
501
                           kcstring+properlength, kcstring_len);
502
 
503
            QUITFUN(rval, encode_keychange_quit);
504
 
505
            *kcstring_len = (properlength*2);
506
 
507
            kcstring += properlength;
508
            nbytes    = 0;
509
            while ((int)(nbytes++) < properlength) {
510
                u_char kcs = *kcstring;
511
                *kcstring++ = kcs ^ *newkey++;
512
            }
513
        }
514
 
515
encode_keychange_quit:
516
        if (rval != SNMPERR_SUCCESS) memset(kcstring, 0, *kcstring_len);
517
        SNMP_FREE(tmpbuf);
518
        SNMP_FREE(context);
519
 
520
        return rval;
521
 
522
}  /* end encode_keychange() */
523
 
524
#else
525
_KEYTOOLS_NOT_AVAILABLE
526
#endif                                          /* internal or openssl */
527
 
528
 
529
 
530
 
531
/*******************************************************************-o-******
532
 * decode_keychange
533
 *
534
 * Parameters:
535
 *      *hashtype       MIB OID of the hash transform to use.
536
 *       hashtype_len   Length of the hash transform MIB OID.
537
 *      *oldkey         Old key that is used to encode the new key.
538
 *       oldkey_len     Length of oldkey in bytes.
539
 *      *kcstring       Encoded KeyString buffer containing the new key.
540
 *       kcstring_len   Length of kcstring in bytes.
541
 *      *newkey         Buffer to hold the extracted new key.
542
 *      *newkey_len     Length of newkey in bytes.
543
 *
544
 * Returns:
545
 *      SNMPERR_SUCCESS                 Success.
546
 *      SNMPERR_GENERR                  All errors.
547
 *
548
 *
549
 * Decodes a string of bits encoded according to the KeyChange TC described
550
 * in RFC 2274, Section 5.  The new key is extracted from *kcstring with
551
 * the aid of the old key.
552
 *
553
 * Upon successful return, *newkey_len contains the length of the new key.
554
 *
555
 *
556
 * ASSUMES      Old key is exactly 1/2 the length of the KeyChange buffer,
557
 *              although this length may be less than the hash transform
558
 *              output.  Thus the new key length will be equal to the old
559
 *              key length.
560
 */
561
 
562
/* XXX:  if the newkey is not long enough, it should be freed and remalloced */
563
int
564
decode_keychange(       oid     *hashtype,      u_int  hashtype_len,
565
                        u_char  *oldkey,        size_t  oldkey_len,
566
                        u_char  *kcstring,      size_t  kcstring_len,
567
                        u_char  *newkey,        size_t *newkey_len)
568
#if defined(USE_OPENSSL) || defined(USE_INTERNAL_MD5)
569
{
570
        int              rval    = SNMPERR_SUCCESS;
571
        size_t           properlength = 0;
572
        u_int            nbytes  = 0;
573
 
574
        u_char          *bufp,
575
                         tmp_buf[SNMP_MAXBUF];
576
        size_t           tmp_buf_len = SNMP_MAXBUF;
577
        void            *context = NULL;
578
        u_char          *tmpbuf = NULL;
579
 
580
 
581
 
582
        /*
583
         * Sanity check.
584
         */
585
        if ( !hashtype || !oldkey || !kcstring || !newkey || !newkey_len
586
                || (oldkey_len<=0) || (kcstring_len<=0) || (*newkey_len<=0)
587
                || (hashtype_len != USM_LENGTH_OID_TRANSFORM) )
588
        {
589
                QUITFUN(SNMPERR_GENERR, decode_keychange_quit);
590
        }
591
 
592
 
593
        /*
594
         * Setup for the transform type.
595
         */
596
        properlength = sc_get_properlength(hashtype, hashtype_len);
597
        if (properlength == SNMPERR_GENERR)
598
          QUITFUN(SNMPERR_GENERR, decode_keychange_quit);
599
 
600
 
601
        if ( ((oldkey_len*2) != kcstring_len) || (*newkey_len < oldkey_len) )
602
        {
603
                QUITFUN(SNMPERR_GENERR, decode_keychange_quit);
604
        }
605
 
606
        properlength = oldkey_len;
607
        *newkey_len = properlength;
608
 
609
        /*
610
         * Use the old key and the given KeyChange TC string to recover
611
         * the new key:
612
         *      . Hash (oldkey | random_bytes) (into newkey),
613
         *      . XOR hash and encoded (second) half of kcstring (into newkey).
614
         */
615
        tmpbuf = (u_char *)malloc(properlength*2);
616
        if (tmpbuf) {
617
            memcpy(tmpbuf, oldkey, properlength);
618
            memcpy(tmpbuf+properlength, kcstring, properlength);
619
 
620
            rval = sc_hash(hashtype, hashtype_len, tmpbuf, properlength*2,
621
                           tmp_buf, &tmp_buf_len);
622
            QUITFUN(rval, decode_keychange_quit);
623
 
624
            memcpy(newkey, tmp_buf, properlength);
625
            bufp   = kcstring+properlength;
626
            nbytes = 0;
627
            while ((int)(nbytes++) < properlength) {
628
                    u_char nk = *newkey;
629
                    *newkey++ = nk ^ *bufp++;
630
            }
631
        }
632
 
633
decode_keychange_quit:
634
        if (rval != SNMPERR_SUCCESS) {
635
                memset(newkey, 0, properlength);
636
        }
637
        memset(tmp_buf, 0, SNMP_MAXBUF);
638
        SNMP_FREE(context);
639
        if (tmpbuf != NULL) SNMP_FREE(tmpbuf);
640
 
641
        return rval;
642
 
643
}  /* end decode_keychange() */
644
 
645
#else
646
_KEYTOOLS_NOT_AVAILABLE
647
#endif                                          /* internal or openssl */
648
 
649
#endif /* CYGPKG_SNMPAGENT_V3_SUPPORT */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.