1 /*!
2 * Copyrights
3 *
4 * Portions created or assigned to Cisco Systems, Inc. are
5 * Copyright (c) 2014-2016 Cisco Systems, Inc. All Rights Reserved.
6 */
7
8 #include <stdlib.h>
9 #include <jansson.h>
10 #include "cjose/header.h"
11 #include "include/header_int.h"
12
13 const char *CJOSE_HDR_ALG = "alg";
14 const char *CJOSE_HDR_ALG_NONE = "none";
15 const char *CJOSE_HDR_ALG_ECDH_ES = "ECDH-ES";
16 const char *CJOSE_HDR_ALG_RSA_OAEP = "RSA-OAEP";
17 const char *CJOSE_HDR_ALG_RSA1_5 = "RSA1_5";
18 const char *CJOSE_HDR_ALG_A128KW = "A128KW";
19 const char *CJOSE_HDR_ALG_A192KW = "A192KW";
20 const char *CJOSE_HDR_ALG_A256KW = "A256KW";
21 const char *CJOSE_HDR_ALG_DIR = "dir";
22 const char *CJOSE_HDR_ALG_PS256 = "PS256";
23 const char *CJOSE_HDR_ALG_PS384 = "PS384";
24 const char *CJOSE_HDR_ALG_PS512 = "PS512";
25 const char *CJOSE_HDR_ALG_RS256 = "RS256";
26 const char *CJOSE_HDR_ALG_RS384 = "RS384";
27 const char *CJOSE_HDR_ALG_RS512 = "RS512";
28 const char *CJOSE_HDR_ALG_HS256 = "HS256";
29 const char *CJOSE_HDR_ALG_HS384 = "HS384";
30 const char *CJOSE_HDR_ALG_HS512 = "HS512";
31 const char *CJOSE_HDR_ALG_ES256 = "ES256";
32 const char *CJOSE_HDR_ALG_ES384 = "ES384";
33 const char *CJOSE_HDR_ALG_ES512 = "ES512";
34
35 const char *CJOSE_HDR_ENC = "enc";
36 const char *CJOSE_HDR_ENC_A256GCM = "A256GCM";
37 const char *CJOSE_HDR_ENC_A128CBC_HS256 = "A128CBC-HS256";
38 const char *CJOSE_HDR_ENC_A192CBC_HS384 = "A192CBC-HS384";
39 const char *CJOSE_HDR_ENC_A256CBC_HS512 = "A256CBC-HS512";
40
41 const char *CJOSE_HDR_CTY = "cty";
42
43 const char *CJOSE_HDR_KID = "kid";
44
45 const char *CJOSE_HDR_EPK = "epk";
46
47 const char *CJOSE_HDR_APU = "apu";
48 const char *CJOSE_HDR_APV = "apv";
49
50 ////////////////////////////////////////////////////////////////////////////////
cjose_header_new(cjose_err * err)51 cjose_header_t *cjose_header_new(cjose_err *err)
52 {
53 cjose_header_t *retval = (cjose_header_t *)json_object();
54 if (NULL == retval)
55 {
56 CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
57 }
58 return retval;
59 }
60
61 ////////////////////////////////////////////////////////////////////////////////
cjose_header_retain(cjose_header_t * header)62 cjose_header_t *cjose_header_retain(cjose_header_t *header)
63 {
64 if (NULL != header)
65 {
66 header = (cjose_header_t *)json_incref((json_t *)header);
67 }
68 return header;
69 }
70
71 ////////////////////////////////////////////////////////////////////////////////
cjose_header_release(cjose_header_t * header)72 void cjose_header_release(cjose_header_t *header)
73 {
74 if (NULL != header)
75 {
76 json_decref((json_t *)header);
77 }
78 }
79
80 ////////////////////////////////////////////////////////////////////////////////
cjose_header_set(cjose_header_t * header,const char * attr,const char * value,cjose_err * err)81 bool cjose_header_set(cjose_header_t *header, const char *attr, const char *value, cjose_err *err)
82 {
83 if (NULL == header || NULL == attr || NULL == value)
84 {
85 CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
86 return false;
87 }
88
89 json_t *value_obj = json_string(value);
90 if (NULL == value_obj)
91 {
92 CJOSE_ERROR(err, CJOSE_ERR_NO_MEMORY);
93 return false;
94 }
95
96 json_object_set_new((json_t *)header, attr, value_obj);
97
98 return true;
99 }
100
101 ////////////////////////////////////////////////////////////////////////////////
cjose_header_get(cjose_header_t * header,const char * attr,cjose_err * err)102 const char *cjose_header_get(cjose_header_t *header, const char *attr, cjose_err *err)
103 {
104 if (NULL == header || NULL == attr)
105 {
106 CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
107 return NULL;
108 }
109
110 json_t *value_obj = json_object_get((json_t *)header, attr);
111 if (NULL == value_obj)
112 {
113 return NULL;
114 }
115
116 return json_string_value(value_obj);
117 }
118
119 ////////////////////////////////////////////////////////////////////////////////
cjose_header_set_raw(cjose_header_t * header,const char * attr,const char * value,cjose_err * err)120 bool cjose_header_set_raw(cjose_header_t *header, const char *attr, const char *value, cjose_err *err)
121 {
122 if (NULL == header || NULL == attr || NULL == value)
123 {
124 CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
125 return false;
126 }
127
128 json_error_t j_err;
129 json_t *value_obj = json_loads(value, 0, &j_err);
130 if (NULL == value_obj)
131 {
132 // unfortunately, it's not possible to tell whether the error is due
133 // to syntax, or memory shortage. See https://github.com/akheron/jansson/issues/352
134 CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
135 return false;
136 }
137
138 json_object_set_new((json_t *)header, attr, value_obj);
139
140 return true;
141 }
142
143 ////////////////////////////////////////////////////////////////////////////////
cjose_header_get_raw(cjose_header_t * header,const char * attr,cjose_err * err)144 char *cjose_header_get_raw(cjose_header_t *header, const char *attr, cjose_err *err)
145 {
146 if (NULL == header || NULL == attr)
147 {
148 CJOSE_ERROR(err, CJOSE_ERR_INVALID_ARG);
149 return NULL;
150 }
151
152 json_t *value_obj = json_object_get((json_t *)header, attr);
153 if (NULL == value_obj)
154 {
155 return NULL;
156 }
157
158 return json_dumps(value_obj, JSON_COMPACT);
159 }
160