@@ -65,15 +65,21 @@ int WPACKET_reserve_bytes(WPACKET *pkt, size_t len, unsigned char **allocbytes)
65
65
if (BUF_MEM_grow (pkt -> buf , newlen ) == 0 )
66
66
return 0 ;
67
67
}
68
- if (allocbytes != NULL )
68
+ if (allocbytes != NULL ) {
69
69
* allocbytes = WPACKET_get_curr (pkt );
70
+ if (pkt -> endfirst && * allocbytes != NULL )
71
+ * allocbytes -= len ;
72
+ }
70
73
71
74
return 1 ;
72
75
}
73
76
74
77
int WPACKET_sub_reserve_bytes__ (WPACKET * pkt , size_t len ,
75
78
unsigned char * * allocbytes , size_t lenbytes )
76
79
{
80
+ if (pkt -> endfirst && lenbytes > 0 )
81
+ return 0 ;
82
+
77
83
if (!WPACKET_reserve_bytes (pkt , lenbytes + len , allocbytes ))
78
84
return 0 ;
79
85
@@ -131,10 +137,25 @@ int WPACKET_init_static_len(WPACKET *pkt, unsigned char *buf, size_t len,
131
137
pkt -> staticbuf = buf ;
132
138
pkt -> buf = NULL ;
133
139
pkt -> maxsize = (max < len ) ? max : len ;
140
+ pkt -> endfirst = 0 ;
134
141
135
142
return wpacket_intern_init_len (pkt , lenbytes );
136
143
}
137
144
145
+ int WPACKET_init_der (WPACKET * pkt , unsigned char * buf , size_t len )
146
+ {
147
+ /* Internal API, so should not fail */
148
+ if (!ossl_assert (buf != NULL && len > 0 ))
149
+ return 0 ;
150
+
151
+ pkt -> staticbuf = buf ;
152
+ pkt -> buf = NULL ;
153
+ pkt -> maxsize = len ;
154
+ pkt -> endfirst = 1 ;
155
+
156
+ return wpacket_intern_init_len (pkt , 0 );
157
+ }
158
+
138
159
int WPACKET_init_len (WPACKET * pkt , BUF_MEM * buf , size_t lenbytes )
139
160
{
140
161
/* Internal API, so should not fail */
@@ -144,6 +165,7 @@ int WPACKET_init_len(WPACKET *pkt, BUF_MEM *buf, size_t lenbytes)
144
165
pkt -> staticbuf = NULL ;
145
166
pkt -> buf = buf ;
146
167
pkt -> maxsize = maxmaxsize (lenbytes );
168
+ pkt -> endfirst = 0 ;
147
169
148
170
return wpacket_intern_init_len (pkt , lenbytes );
149
171
}
@@ -158,6 +180,17 @@ int WPACKET_init_null(WPACKET *pkt, size_t lenbytes)
158
180
pkt -> staticbuf = NULL ;
159
181
pkt -> buf = NULL ;
160
182
pkt -> maxsize = maxmaxsize (lenbytes );
183
+ pkt -> endfirst = 0 ;
184
+
185
+ return wpacket_intern_init_len (pkt , 0 );
186
+ }
187
+
188
+ int WPACKET_init_null_der (WPACKET * pkt )
189
+ {
190
+ pkt -> staticbuf = NULL ;
191
+ pkt -> buf = NULL ;
192
+ pkt -> maxsize = SIZE_MAX ;
193
+ pkt -> endfirst = 1 ;
161
194
162
195
return wpacket_intern_init_len (pkt , 0 );
163
196
}
@@ -232,6 +265,19 @@ static int wpacket_intern_close(WPACKET *pkt, WPACKET_SUB *sub, int doclose)
232
265
&& !put_value (& buf [sub -> packet_len ], packlen ,
233
266
sub -> lenbytes ))
234
267
return 0 ;
268
+ } else if (pkt -> endfirst && sub -> parent != NULL ) {
269
+ size_t tmplen = packlen ;
270
+ size_t numlenbytes = 1 ;
271
+
272
+ while ((tmplen = tmplen >> 8 ) > 0 )
273
+ numlenbytes ++ ;
274
+ if (!WPACKET_put_bytes__ (pkt , packlen , numlenbytes ))
275
+ return 0 ;
276
+ if (packlen > 0x7f ) {
277
+ numlenbytes |= 0x80 ;
278
+ if (!WPACKET_put_bytes_u8 (pkt , numlenbytes ))
279
+ return 0 ;
280
+ }
235
281
}
236
282
237
283
if (doclose ) {
@@ -298,6 +344,10 @@ int WPACKET_start_sub_packet_len__(WPACKET *pkt, size_t lenbytes)
298
344
if (!ossl_assert (pkt -> subs != NULL ))
299
345
return 0 ;
300
346
347
+ /* We don't support lenbytes greater than 0 when doing endfirst writing */
348
+ if (lenbytes > 0 && pkt -> endfirst )
349
+ return 0 ;
350
+
301
351
if ((sub = OPENSSL_zalloc (sizeof (* sub ))) == NULL ) {
302
352
SSLerr (SSL_F_WPACKET_START_SUB_PACKET_LEN__ , ERR_R_MALLOC_FAILURE );
303
353
return 0 ;
@@ -436,6 +486,9 @@ unsigned char *WPACKET_get_curr(WPACKET *pkt)
436
486
if (buf == NULL )
437
487
return NULL ;
438
488
489
+ if (pkt -> endfirst )
490
+ return buf + pkt -> maxsize - pkt -> curr ;
491
+
439
492
return buf + pkt -> curr ;
440
493
}
441
494
0 commit comments