Imported Upstream version 1.20.1
[platform/upstream/krb5.git] / src / lib / krb5 / krb / ser_key.c
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/ser_key.c - Serialize krb5_keyblock structure */
3 /*
4  * Copyright 1995, 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 "int-proto.h"
29
30 krb5_error_code
31 k5_size_keyblock(krb5_keyblock *keyblock, size_t *sizep)
32 {
33     krb5_error_code     kret;
34
35     /*
36      * krb5_keyblock requires:
37      *  krb5_int32                      for KV5M_KEYBLOCK
38      *  krb5_int32                      for enctype
39      *  krb5_int32                      for length
40      *  keyblock->length                for contents
41      *  krb5_int32                      for KV5M_KEYBLOCK
42      */
43     kret = EINVAL;
44     if (keyblock != NULL) {
45         *sizep += 4 * sizeof(krb5_int32) + keyblock->length;
46         kret = 0;
47     }
48     return(kret);
49 }
50
51 krb5_error_code
52 k5_externalize_keyblock(krb5_keyblock *keyblock,
53                         krb5_octet **buffer, size_t *lenremain)
54 {
55     krb5_error_code     kret;
56     size_t              required;
57     krb5_octet          *bp;
58     size_t              remain;
59
60     required = 0;
61     bp = *buffer;
62     remain = *lenremain;
63     kret = EINVAL;
64     if (keyblock != NULL) {
65         kret = ENOMEM;
66         if (!k5_size_keyblock(keyblock, &required) && required <= remain) {
67             /* Our identifier */
68             (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain);
69
70             /* Our enctype */
71             (void) krb5_ser_pack_int32((krb5_int32) keyblock->enctype,
72                                        &bp, &remain);
73
74             /* Our length */
75             (void) krb5_ser_pack_int32((krb5_int32) keyblock->length,
76                                        &bp, &remain);
77
78             /* Our contents */
79             (void) krb5_ser_pack_bytes(keyblock->contents,
80                                        (size_t) keyblock->length,
81                                        &bp, &remain);
82
83             /* Finally, our trailer */
84             (void) krb5_ser_pack_int32(KV5M_KEYBLOCK, &bp, &remain);
85
86             kret = 0;
87             *buffer = bp;
88             *lenremain = remain;
89         }
90     }
91     return(kret);
92 }
93
94 krb5_error_code
95 k5_internalize_keyblock(krb5_keyblock **argp,
96                         krb5_octet **buffer, size_t *lenremain)
97 {
98     krb5_error_code     kret;
99     krb5_keyblock       *keyblock;
100     krb5_int32          ibuf;
101     krb5_octet          *bp;
102     size_t              remain;
103
104     bp = *buffer;
105     remain = *lenremain;
106     kret = EINVAL;
107     /* Read our magic number */
108     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain))
109         ibuf = 0;
110     if (ibuf == KV5M_KEYBLOCK) {
111         kret = ENOMEM;
112
113         /* Get a keyblock */
114         if ((remain >= (3*sizeof(krb5_int32))) &&
115             (keyblock = (krb5_keyblock *) calloc(1, sizeof(krb5_keyblock)))) {
116             /* Get the enctype */
117             (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
118             keyblock->enctype = (krb5_enctype) ibuf;
119
120             /* Get the length */
121             (void) krb5_ser_unpack_int32(&ibuf, &bp, &remain);
122             keyblock->length = (int) ibuf;
123
124             /* Get the string */
125             if ((keyblock->contents = (krb5_octet *) malloc((size_t) (ibuf)))&&
126                 !(kret = krb5_ser_unpack_bytes(keyblock->contents,
127                                                (size_t) ibuf,
128                                                &bp, &remain))) {
129                 kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
130                 if (!kret && (ibuf == KV5M_KEYBLOCK)) {
131                     kret = 0;
132                     *buffer = bp;
133                     *lenremain = remain;
134                     keyblock->magic = KV5M_KEYBLOCK;
135                     *argp = keyblock;
136                 }
137                 else
138                     kret = EINVAL;
139             }
140             if (kret) {
141                 if (keyblock->contents)
142                     free(keyblock->contents);
143                 free(keyblock);
144             }
145         }
146     }
147     return(kret);
148 }