xref: /freebsd/crypto/krb5/src/lib/krb5/krb/ser_princ.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/ser_princ.c - Serialize krb5_principal structure */
3 /*
4  * Copyright 1995 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
k5_size_principal(krb5_principal principal,size_t * sizep)31 k5_size_principal(krb5_principal principal, size_t *sizep)
32 {
33     krb5_error_code     kret;
34     char                *fname;
35 
36     /*
37      * krb5_principal requires:
38      *  krb5_int32                      for KV5M_PRINCIPAL
39      *  krb5_int32                      for flattened name size
40      *  strlen(name)                    for name.
41      *  krb5_int32                      for KV5M_PRINCIPAL
42      */
43     kret = EINVAL;
44     if (principal != NULL &&
45         !(kret = krb5_unparse_name(NULL, principal, &fname))) {
46         *sizep += (3*sizeof(krb5_int32)) + strlen(fname);
47         free(fname);
48     }
49     return(kret);
50 }
51 
52 krb5_error_code
k5_externalize_principal(krb5_principal principal,krb5_octet ** buffer,size_t * lenremain)53 k5_externalize_principal(krb5_principal principal,
54                          krb5_octet **buffer, size_t *lenremain)
55 {
56     krb5_error_code     kret;
57     size_t              required;
58     krb5_octet          *bp;
59     size_t              remain;
60     char                *fname;
61 
62     required = 0;
63     bp = *buffer;
64     remain = *lenremain;
65     kret = EINVAL;
66     if (principal != NULL) {
67         kret = ENOMEM;
68         if (!k5_size_principal(principal, &required) && required <= remain) {
69             if (!(kret = krb5_unparse_name(NULL, principal, &fname))) {
70 
71                 (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
72                 (void) krb5_ser_pack_int32((krb5_int32) strlen(fname),
73                                            &bp, &remain);
74                 (void) krb5_ser_pack_bytes((krb5_octet *) fname,
75                                            strlen(fname), &bp, &remain);
76                 (void) krb5_ser_pack_int32(KV5M_PRINCIPAL, &bp, &remain);
77                 *buffer = bp;
78                 *lenremain = remain;
79 
80                 free(fname);
81             }
82         }
83     }
84     return(kret);
85 }
86 
87 krb5_error_code
k5_internalize_principal(krb5_principal * argp,krb5_octet ** buffer,size_t * lenremain)88 k5_internalize_principal(krb5_principal *argp,
89                          krb5_octet **buffer, size_t *lenremain)
90 {
91     krb5_error_code     kret;
92     krb5_principal      principal = NULL;
93     krb5_int32          ibuf;
94     krb5_octet          *bp;
95     size_t              remain;
96     char                *tmpname = NULL;
97 
98     *argp = NULL;
99     bp = *buffer;
100     remain = *lenremain;
101 
102     /* Read our magic number */
103     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain) || ibuf != KV5M_PRINCIPAL)
104         return EINVAL;
105 
106     /* Read the principal name */
107     kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain);
108     if (kret)
109         return kret;
110     tmpname = malloc(ibuf + 1);
111     kret = krb5_ser_unpack_bytes((krb5_octet *) tmpname, (size_t) ibuf,
112                                  &bp, &remain);
113     if (kret)
114         goto cleanup;
115     tmpname[ibuf] = '\0';
116 
117     /* Parse the name to a principal structure */
118     kret = krb5_parse_name_flags(NULL, tmpname,
119                                  KRB5_PRINCIPAL_PARSE_REQUIRE_REALM,
120                                  &principal);
121     if (kret)
122         goto cleanup;
123 
124     /* Read the trailing magic number */
125     if (krb5_ser_unpack_int32(&ibuf, &bp, &remain) || ibuf != KV5M_PRINCIPAL) {
126         kret = EINVAL;
127         goto cleanup;
128     }
129 
130     *buffer = bp;
131     *lenremain = remain;
132     *argp = principal;
133 cleanup:
134     if (kret)
135         krb5_free_principal(NULL, principal);
136     free(tmpname);
137     return kret;
138 }
139