@@ -857,6 +857,14 @@ static ssize_t fr_der_decode_sequence(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_d
857857 child = fr_dict_attr_unknown_raw_afrom_num (decode_ctx -> tmp_ctx , parent , current_tag );
858858 if (!child ) return -1 ;
859859 }
860+
861+ /*
862+ * Options always have to have the context field set.
863+ */
864+ if ((tag_byte & DER_TAG_CLASS_MASK ) != FR_DER_CLASS_CONTEXT ) {
865+ fr_strerror_printf ("Tag has unexpected class %20x" , tag_byte & DER_TAG_CLASS_MASK );
866+ return -1 ;
867+ }
860868 }
861869
862870 FR_PROTO_TRACE ("decode context %s -> %s" , parent -> name , child -> name );
@@ -1644,6 +1652,53 @@ static ssize_t fr_der_decode_ipv6_prefix(TALLOC_CTX *ctx, fr_pair_list_t *out, f
16441652 return fr_dbuff_set (in , & our_in );
16451653}
16461654
1655+ static ssize_t fr_der_decode_combo_ip_addr (TALLOC_CTX * ctx , fr_pair_list_t * out , fr_dict_attr_t const * parent ,
1656+ fr_dbuff_t * in , UNUSED fr_der_decode_ctx_t * decode_ctx )
1657+ {
1658+ fr_pair_t * vp ;
1659+ fr_dbuff_t our_in = FR_DBUFF (in );
1660+ size_t len = fr_dbuff_remaining (& our_in );
1661+
1662+ /*
1663+ * RFC5280 Section 4.2.1.6
1664+ *
1665+ * When the subjectAltName extension contains an iPAddress, the address
1666+ * MUST be stored in the octet string in "network byte order", as
1667+ * specified in [RFC791]. The least significant bit (LSB) of each octet
1668+ * is the LSB of the corresponding byte in the network address. For IP
1669+ * version 4, as specified in [RFC791], the octet string MUST contain
1670+ * exactly four octets. For IP version 6, as specified in
1671+ * [RFC2460], the octet string MUST contain exactly sixteen octets.
1672+ */
1673+ if ((len != 4 ) && (len != 16 )) {
1674+ fr_strerror_printf ("Invalid combo_ip_addr size. Expected 4 or 16, got %zu" ,
1675+ len );
1676+ return -1 ;
1677+ }
1678+
1679+ vp = fr_pair_afrom_da (ctx , parent );
1680+ if (unlikely (!vp )) {
1681+ fr_strerror_const ("Out of memory" );
1682+ return -1 ;
1683+ }
1684+
1685+ if (len == 4 ) {
1686+ vp -> vp_ip .af = AF_INET ;
1687+ vp -> vp_ip .prefix = 32 ;
1688+ FR_DBUFF_OUT_MEMCPY_RETURN ((uint8_t * ) & vp -> vp_ipv4addr , & our_in , sizeof (vp -> vp_ipv4addr ));
1689+
1690+ } else {
1691+ vp -> vp_ip .af = AF_INET6 ;
1692+ vp -> vp_ip .prefix = 128 ;
1693+ FR_DBUFF_OUT_MEMCPY_RETURN ((uint8_t * ) & vp -> vp_ipv6addr , & our_in , sizeof (vp -> vp_ipv6addr ));
1694+ }
1695+
1696+ fr_pair_append (out , vp );
1697+
1698+ return fr_dbuff_set (in , & our_in );
1699+ }
1700+
1701+
16471702static const fr_der_tag_decode_t tag_funcs [FR_DER_TAG_MAX ] = {
16481703 [FR_DER_TAG_BOOLEAN ] = { .constructed = FR_DER_TAG_PRIMITIVE , .decode = fr_der_decode_boolean },
16491704 [FR_DER_TAG_INTEGER ] = { .constructed = FR_DER_TAG_PRIMITIVE , .decode = fr_der_decode_integer },
@@ -1672,6 +1727,8 @@ static const fr_der_tag_decode_t type_funcs[FR_TYPE_MAX] = {
16721727 [FR_TYPE_IPV4_PREFIX ] = { .constructed = FR_DER_TAG_PRIMITIVE , .decode = fr_der_decode_ipv4_prefix },
16731728 [FR_TYPE_IPV6_ADDR ] = { .constructed = FR_DER_TAG_PRIMITIVE , .decode = fr_der_decode_ipv6_addr },
16741729 [FR_TYPE_IPV6_PREFIX ] = { .constructed = FR_DER_TAG_PRIMITIVE , .decode = fr_der_decode_ipv6_prefix },
1730+
1731+ [FR_TYPE_COMBO_IP_ADDR ] = { .constructed = FR_DER_TAG_PRIMITIVE , .decode = fr_der_decode_combo_ip_addr },
16751732};
16761733
16771734/** Decode the tag and length fields of a DER encoded structure
0 commit comments