Skip to content

Commit d37837e

Browse files
committed
asn1: support opaque ASN1_STRING in OpenSSL 4.0
ASN1_STRING has been made opaque in OpenSSL's master branch. Use the new accessor functions instead of accessing fields directly.
1 parent 788b354 commit d37837e

3 files changed

Lines changed: 46 additions & 17 deletions

File tree

ext/openssl/extconf.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ def find_openssl_library
169169
# added in 3.5.0
170170
have_func("SSL_get0_peer_signature_name(NULL, NULL)", ssl_h)
171171

172+
# added in 4.0.0
173+
have_func("ASN1_BIT_STRING_set1(NULL, NULL, 0, 0)", "openssl/asn1.h")
174+
172175
Logging::message "=== Checking done. ===\n"
173176

174177
# Append flags from environment variables.

ext/openssl/openssl_missing.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,27 @@
2929
# define EVP_PKEY_eq(a, b) EVP_PKEY_cmp(a, b)
3030
#endif
3131

32+
/* added in 4.0.0 */
33+
#ifndef HAVE_ASN1_BIT_STRING_SET1
34+
static inline int
35+
ASN1_BIT_STRING_set1(ASN1_BIT_STRING *bitstr, const uint8_t *data,
36+
size_t length, int unused_bits)
37+
{
38+
if (length > INT_MAX || !ASN1_STRING_set(bitstr, data, (int)length))
39+
return 0;
40+
bitstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
41+
bitstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
42+
return 1;
43+
}
44+
45+
static inline int
46+
ASN1_BIT_STRING_get_length(const ASN1_BIT_STRING *bitstr, size_t *length,
47+
int *unused_bits)
48+
{
49+
*length = bs->length;
50+
*unused_bits = bs->flags & 0x07;
51+
return 1;
52+
}
53+
#endif
54+
3255
#endif /* _OSSL_OPENSSL_MISSING_H_ */

ext/openssl/ossl_asn1.c

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -226,19 +226,19 @@ obj_to_asn1int(VALUE obj)
226226
}
227227

228228
static ASN1_BIT_STRING*
229-
obj_to_asn1bstr(VALUE obj, long unused_bits)
229+
obj_to_asn1bstr(VALUE obj, int unused_bits)
230230
{
231231
ASN1_BIT_STRING *bstr;
232232

233233
if (unused_bits < 0 || unused_bits > 7)
234234
ossl_raise(eASN1Error, "unused_bits for a bitstring value must be in "\
235235
"the range 0 to 7");
236236
StringValue(obj);
237-
if(!(bstr = ASN1_BIT_STRING_new()))
238-
ossl_raise(eASN1Error, NULL);
239-
ASN1_BIT_STRING_set(bstr, (unsigned char *)RSTRING_PTR(obj), RSTRING_LENINT(obj));
240-
bstr->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
241-
bstr->flags |= ASN1_STRING_FLAG_BITS_LEFT | unused_bits;
237+
if (!(bstr = ASN1_BIT_STRING_new()))
238+
ossl_raise(eASN1Error, "ASN1_BIT_STRING_new");
239+
if (!ASN1_BIT_STRING_set1(bstr, (uint8_t *)RSTRING_PTR(obj),
240+
RSTRING_LEN(obj), unused_bits))
241+
ossl_raise(eASN1Error, "ASN1_BIT_STRING_set1");
242242

243243
return bstr;
244244
}
@@ -362,22 +362,25 @@ decode_int(unsigned char* der, long length)
362362
}
363363

364364
static VALUE
365-
decode_bstr(unsigned char* der, long length, long *unused_bits)
365+
decode_bstr(unsigned char* der, long length, int *unused_bits)
366366
{
367367
ASN1_BIT_STRING *bstr;
368368
const unsigned char *p;
369-
long len;
369+
size_t len;
370370
VALUE ret;
371+
int state;
371372

372373
p = der;
373-
if(!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
374-
ossl_raise(eASN1Error, NULL);
375-
len = bstr->length;
376-
*unused_bits = 0;
377-
if(bstr->flags & ASN1_STRING_FLAG_BITS_LEFT)
378-
*unused_bits = bstr->flags & 0x07;
379-
ret = rb_str_new((const char *)bstr->data, len);
374+
if (!(bstr = d2i_ASN1_BIT_STRING(NULL, &p, length)))
375+
ossl_raise(eASN1Error, "d2i_ASN1_BIT_STRING");
376+
if (!ASN1_BIT_STRING_get_length(bstr, &len, unused_bits)) {
377+
ASN1_BIT_STRING_free(bstr);
378+
ossl_raise(eASN1Error, "ASN1_BIT_STRING_get_length");
379+
}
380+
ret = ossl_str_new((const char *)ASN1_STRING_get0_data(bstr), len, &state);
380381
ASN1_BIT_STRING_free(bstr);
382+
if (state)
383+
rb_jump_tag(state);
381384

382385
return ret;
383386
}
@@ -761,7 +764,7 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
761764
{
762765
VALUE value, asn1data;
763766
unsigned char *p;
764-
long flag = 0;
767+
int flag = 0;
765768

766769
p = *pp;
767770

@@ -818,7 +821,7 @@ int_ossl_asn1_decode0_prim(unsigned char **pp, long length, long hlen, int tag,
818821
asn1data = rb_obj_alloc(klass);
819822
ossl_asn1_initialize(4, args, asn1data);
820823
if(tag == V_ASN1_BIT_STRING){
821-
rb_ivar_set(asn1data, sivUNUSED_BITS, LONG2NUM(flag));
824+
rb_ivar_set(asn1data, sivUNUSED_BITS, INT2NUM(flag));
822825
}
823826
}
824827
else {

0 commit comments

Comments
 (0)