1/*
2 * Copyright 2019-2020 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License").  You may not use
5 * this file except in compliance with the License.  You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <string.h>
12
13#include <openssl/bn.h>
14#include "crypto/asn1_dsa.h"
15#include "testutil.h"
16
17static unsigned char t_dsa_sig[] = {
18    0x30, 0x06,                  /* SEQUENCE tag + length */
19    0x02, 0x01, 0x01,            /* INTEGER tag + length + content */
20    0x02, 0x01, 0x02             /* INTEGER tag + length + content */
21};
22
23static unsigned char t_dsa_sig_extra[] = {
24    0x30, 0x06,                  /* SEQUENCE tag + length */
25    0x02, 0x01, 0x01,            /* INTEGER tag + length + content */
26    0x02, 0x01, 0x02,            /* INTEGER tag + length + content */
27    0x05, 0x00                   /* NULL tag + length */
28};
29
30static unsigned char t_dsa_sig_msb[] = {
31    0x30, 0x08,                  /* SEQUENCE tag + length */
32    0x02, 0x02, 0x00, 0x81,      /* INTEGER tag + length + content */
33    0x02, 0x02, 0x00, 0x82       /* INTEGER tag + length + content */
34};
35
36static unsigned char t_dsa_sig_two[] = {
37    0x30, 0x08,                  /* SEQUENCE tag + length */
38    0x02, 0x02, 0x01, 0x00,      /* INTEGER tag + length + content */
39    0x02, 0x02, 0x02, 0x00       /* INTEGER tag + length + content */
40};
41
42/*
43 * Badly coded ASN.1 INTEGER zero wrapped in a sequence along with another
44 * (valid) INTEGER.
45 */
46static unsigned char t_invalid_int_zero[] = {
47    0x30, 0x05,                  /* SEQUENCE tag + length */
48    0x02, 0x00,                  /* INTEGER tag + length */
49    0x02, 0x01, 0x2a             /* INTEGER tag + length */
50};
51
52/*
53 * Badly coded ASN.1 INTEGER (with leading zeros) wrapped in a sequence along
54 * with another (valid) INTEGER.
55 */
56static unsigned char t_invalid_int[] = {
57    0x30, 0x07,                  /* SEQUENCE tag + length */
58    0x02, 0x02, 0x00, 0x7f,      /* INTEGER tag + length */
59    0x02, 0x01, 0x2a             /* INTEGER tag + length */
60};
61
62/*
63 * Negative ASN.1 INTEGER wrapped in a sequence along with another
64 * (valid) INTEGER.
65 */
66static unsigned char t_neg_int[] = {
67    0x30, 0x06,                  /* SEQUENCE tag + length */
68    0x02, 0x01, 0xaa,            /* INTEGER tag + length */
69    0x02, 0x01, 0x2a             /* INTEGER tag + length */
70};
71
72static unsigned char t_trunc_der[] = {
73    0x30, 0x08,                  /* SEQUENCE tag + length */
74    0x02, 0x02, 0x00, 0x81,      /* INTEGER tag + length */
75    0x02, 0x02, 0x00             /* INTEGER tag + length */
76};
77
78static unsigned char t_trunc_seq[] = {
79    0x30, 0x07,                  /* SEQUENCE tag + length */
80    0x02, 0x02, 0x00, 0x81,      /* INTEGER tag + length */
81    0x02, 0x02, 0x00, 0x82       /* INTEGER tag + length */
82};
83
84static int test_decode(void)
85{
86    int rv = 0;
87    BIGNUM *r;
88    BIGNUM *s;
89    const unsigned char *pder;
90
91    r = BN_new();
92    s = BN_new();
93
94    /* Positive tests */
95    pder = t_dsa_sig;
96    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig)) == 0
97            || !TEST_ptr_eq(pder, (t_dsa_sig + sizeof(t_dsa_sig)))
98            || !TEST_BN_eq_word(r, 1) || !TEST_BN_eq_word(s, 2)) {
99        TEST_info("asn1_dsa test_decode: t_dsa_sig failed");
100        goto fail;
101    }
102
103    BN_clear(r);
104    BN_clear(s);
105    pder = t_dsa_sig_extra;
106    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig_extra)) == 0
107            || !TEST_ptr_eq(pder,
108                            (t_dsa_sig_extra + sizeof(t_dsa_sig_extra) - 2))
109            || !TEST_BN_eq_word(r, 1) || !TEST_BN_eq_word(s, 2)) {
110        TEST_info("asn1_dsa test_decode: t_dsa_sig_extra failed");
111        goto fail;
112    }
113
114    BN_clear(r);
115    BN_clear(s);
116    pder = t_dsa_sig_msb;
117    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig_msb)) == 0
118            || !TEST_ptr_eq(pder, (t_dsa_sig_msb + sizeof(t_dsa_sig_msb)))
119            || !TEST_BN_eq_word(r, 0x81) || !TEST_BN_eq_word(s, 0x82)) {
120        TEST_info("asn1_dsa test_decode: t_dsa_sig_msb failed");
121        goto fail;
122    }
123
124    BN_clear(r);
125    BN_clear(s);
126    pder = t_dsa_sig_two;
127    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_dsa_sig_two)) == 0
128            || !TEST_ptr_eq(pder, (t_dsa_sig_two + sizeof(t_dsa_sig_two)))
129            || !TEST_BN_eq_word(r, 0x100) || !TEST_BN_eq_word(s, 0x200)) {
130        TEST_info("asn1_dsa test_decode: t_dsa_sig_two failed");
131        goto fail;
132    }
133
134    /* Negative tests */
135    pder = t_invalid_int_zero;
136    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_invalid_int_zero)) != 0) {
137        TEST_info("asn1_dsa test_decode: Expected t_invalid_int_zero to fail");
138        goto fail;
139    }
140
141    BN_clear(r);
142    BN_clear(s);
143    pder = t_invalid_int;
144    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_invalid_int)) != 0) {
145        TEST_info("asn1_dsa test_decode: Expected t_invalid_int to fail");
146        goto fail;
147    }
148
149    BN_clear(r);
150    BN_clear(s);
151    pder = t_neg_int;
152    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_neg_int)) != 0) {
153        TEST_info("asn1_dsa test_decode: Expected t_neg_int to fail");
154        goto fail;
155    }
156
157    BN_clear(r);
158    BN_clear(s);
159    pder = t_trunc_der;
160    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_trunc_der)) != 0) {
161        TEST_info("asn1_dsa test_decode: Expected fail t_trunc_der");
162        goto fail;
163    }
164
165    BN_clear(r);
166    BN_clear(s);
167    pder = t_trunc_seq;
168    if (ossl_decode_der_dsa_sig(r, s, &pder, sizeof(t_trunc_seq)) != 0) {
169        TEST_info("asn1_dsa test_decode: Expected fail t_trunc_seq");
170        goto fail;
171    }
172
173    rv = 1;
174fail:
175    BN_free(r);
176    BN_free(s);
177    return rv;
178}
179
180int setup_tests(void)
181{
182    ADD_TEST(test_decode);
183    return 1;
184}
185