LCOV - code coverage report
Current view: top level - src/edhoc - retrieve_cred.c (source / functions) Coverage Total Hit
Test: lcov.info Lines: 52.9 % 70 37
Test Date: 2026-03-12 12:01:18 Functions: 100.0 % 3 3
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 31.3 % 67 21

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :    Copyright (c) 2021 Fraunhofer AISEC. See the COPYRIGHT
       3                 :             :    file at the top-level directory of this distribution.
       4                 :             : 
       5                 :             :    Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
       6                 :             :    http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
       7                 :             :    <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
       8                 :             :    option. This file may not be copied, modified, or distributed
       9                 :             :    except according to those terms.
      10                 :             : */
      11                 :             : 
      12                 :             : #include <string.h>
      13                 :             : 
      14                 :             : #include "edhoc/cert.h"
      15                 :             : #include "edhoc/bstr_encode_decode.h"
      16                 :             : #include "edhoc/retrieve_cred.h"
      17                 :             : 
      18                 :             : #include "common/crypto_wrapper.h"
      19                 :             : #include "common/oscore_edhoc_error.h"
      20                 :             : #include "common/print_util.h"
      21                 :             : #include "common/memcpy_s.h"
      22                 :             : 
      23                 :             : #include "cbor/edhoc_decode_id_cred_x.h"
      24                 :             : 
      25                 :             : /**
      26                 :             :  * @brief                       Verifies a certificate and copies it to the cred 
      27                 :             :  *                              buffer. It also extracts the public key
      28                 :             :  *                              contained in the certificate. 
      29                 :             :  * 
      30                 :             :  * @param static_dh_auth        Type of the key contained in the certificate -- 
      31                 :             :  *                              signature key or static DH key.
      32                 :             :  * @param cred_array            array containing credentials.
      33                 :             :  * @param label                 CBOR map label of id_cred_x.
      34                 :             :  * @param[in] cert              The certificate.
      35                 :             :  * @param[in] cred              Cred buffer.
      36                 :             :  * @param[in] pk                Public key.
      37                 :             :  * @param[in] g                 Static DH public key.
      38                 :             :  * @return                      Ok or error code
      39                 :             :  */
      40                 :             : static inline enum err
      41                 :           2 : verify_cert2cred(bool static_dh_auth, struct cred_array *cred_array,
      42                 :             :                  enum id_cred_x_label label, struct const_byte_array *cert,
      43                 :             :                  struct byte_array *cred, struct byte_array *pk,
      44                 :             :                  struct byte_array *g)
      45                 :             : {
      46                 :           2 :         PRINT_ARRAY("ID_CRED_x contains a certificate", cert->ptr, cert->len);
      47         [ -  + ]:           2 :         TRY(encode_bstr((struct byte_array *)cert, cred));
      48                 :             : 
      49                 :           2 :         bool verified = false;
      50      [ +  -  - ]:           2 :         switch (label) {
      51                 :             :         /* for now we transfer a single certificate, therefore bag and chain are the same */
      52                 :           2 :         case x5bag:
      53                 :             :         case x5chain:
      54         [ -  + ]:           2 :                 if (static_dh_auth) {
      55                 :           0 :                         pk->len = 0;
      56         [ #  # ]:           0 :                         TRY(cert_x509_verify(cert, cred_array, g, &verified));
      57                 :             :                 } else {
      58                 :           2 :                         g->len = 0;
      59         [ -  + ]:           2 :                         TRY(cert_x509_verify(cert, cred_array, pk, &verified));
      60                 :             :                 }
      61                 :           2 :                 break;
      62                 :           0 :         case c5b:
      63                 :             :         case c5c:
      64         [ #  # ]:           0 :                 if (static_dh_auth) {
      65                 :           0 :                         pk->len = 0;
      66         [ #  # ]:           0 :                         TRY(cert_c509_verify(cert, cred_array, g, &verified));
      67                 :             :                 } else {
      68                 :           0 :                         g->len = 0;
      69         [ #  # ]:           0 :                         TRY(cert_c509_verify(cert, cred_array, pk, &verified));
      70                 :             :                 }
      71                 :           0 :                 break;
      72                 :             :                 break;
      73                 :             : 
      74                 :           0 :         default:
      75                 :           0 :                 break;
      76                 :             :         }
      77                 :             : 
      78         [ +  - ]:           2 :         if (verified) {
      79                 :           2 :                 PRINT_MSG("Certificate verification successful!\n");
      80                 :           2 :                 return ok;
      81                 :             :         } else {
      82                 :           0 :                 return certificate_authentication_failed;
      83                 :             :         }
      84                 :             :         return ok;
      85                 :             : }
      86                 :             : 
      87                 :             : /**
      88                 :             :  * @brief                       Get the local cred object.
      89                 :             :  * 
      90                 :             :  * @param static_dh_auth        True if static DH is used for authentication.
      91                 :             :  * @param[in] cred_array        An array of trust anchors
      92                 :             :  * @param[in] ID_cred           The ID of the actual credential.
      93                 :             :  * @param[out] cred             The retrievd credentials        
      94                 :             :  * @param[out] pk               The retrievd signature authentication public key
      95                 :             :  * @param[out] g                The retrievd static DH authentication public key
      96                 :             :  * @return                      Ok or error code
      97                 :             :  */
      98                 :           4 : static enum err get_local_cred(bool static_dh_auth,
      99                 :             :                                struct cred_array *cred_array,
     100                 :             :                                struct byte_array *ID_cred,
     101                 :             :                                struct byte_array *cred, struct byte_array *pk,
     102                 :             :                                struct byte_array *g)
     103                 :             : {
     104         [ +  - ]:           4 :         for (uint32_t i = 0; i < cred_array->len; i++) {
     105         [ +  - ]:           4 :                 if ((cred_array->ptr[i].id_cred.len == ID_cred->len) &&
     106         [ +  - ]:           4 :                     (0 == memcmp(cred_array->ptr[i].id_cred.ptr, ID_cred->ptr,
     107                 :             :                                  ID_cred->len))) {
     108                 :             :                         /*retrieve CRED_x*/
     109         [ -  + ]:           4 :                         TRY(_memcpy_s(cred->ptr, cred->len,
     110                 :             :                                       cred_array->ptr[i].cred.ptr,
     111                 :             :                                       cred_array->ptr[i].cred.len));
     112                 :           4 :                         cred->len = cred_array->ptr[i].cred.len;
     113                 :             : 
     114                 :             :                         /*retrieve PK*/
     115         [ -  + ]:           4 :                         if (static_dh_auth) {
     116                 :           0 :                                 pk->len = 0;
     117         [ #  # ]:           0 :                                 if (cred_array->ptr[i].g.len == 65) {
     118                 :             :                                         /*decompressed P256 DH pk*/
     119                 :           0 :                                         g->ptr[0] = 0x2;
     120         [ #  # ]:           0 :                                         TRY(_memcpy_s(
     121                 :             :                                                 &g->ptr[1], g->len - 1,
     122                 :             :                                                 &cred_array->ptr[i].g.ptr[1],
     123                 :             :                                                 32));
     124                 :           0 :                                         g->len = 33;
     125                 :             : 
     126                 :             :                                 } else {
     127         [ #  # ]:           0 :                                         TRY(_memcpy_s(g->ptr, g->len,
     128                 :             :                                                       cred_array->ptr[i].g.ptr,
     129                 :             :                                                       cred_array->ptr[i].g.len));
     130                 :           0 :                                         g->len = cred_array->ptr[i].g.len;
     131                 :             :                                 }
     132                 :             : 
     133                 :             :                         } else {
     134                 :           4 :                                 g->len = 0;
     135         [ -  + ]:           4 :                                 TRY(_memcpy_s(pk->ptr, pk->len,
     136                 :             :                                               cred_array->ptr[i].pk.ptr,
     137                 :             :                                               cred_array->ptr[i].pk.len));
     138                 :           4 :                                 pk->len = cred_array->ptr[i].pk.len;
     139                 :             :                         }
     140                 :           4 :                         return ok;
     141                 :             :                 }
     142                 :             :         }
     143                 :             : 
     144                 :           0 :         return credential_not_found;
     145                 :             : }
     146                 :             : 
     147                 :           6 : enum err retrieve_cred(bool static_dh_auth, struct cred_array *cred_array,
     148                 :             :                        struct byte_array *id_cred, struct byte_array *cred,
     149                 :             :                        struct byte_array *pk, struct byte_array *g)
     150                 :             : {
     151                 :           6 :         size_t decode_len = 0;
     152                 :           6 :         struct id_cred_x_map map = { 0 };
     153                 :             : 
     154         [ -  + ]:           6 :         TRY_EXPECT(cbor_decode_id_cred_x_map(id_cred->ptr, id_cred->len, &map,
     155                 :             :                                              &decode_len),
     156                 :             :                    0);
     157                 :             :         /*the cred should be locally available on the device if 
     158                 :             :         kid, x5u, x5t, c5u, c5t is used*/
     159   [ +  -  +  - ]:           6 :         if (map.id_cred_x_map_kid_present || map.id_cred_x_map_x5u_present ||
     160   [ +  +  +  - ]:           6 :             map.id_cred_x_map_x5t_present || map.id_cred_x_map_c5u_present ||
     161         [ -  + ]:           2 :             map.id_cred_x_map_c5t_present) {
     162         [ -  + ]:           4 :                 TRY(get_local_cred(static_dh_auth, cred_array, id_cred, cred,
     163                 :             :                                    pk, g));
     164                 :           4 :                 return ok;
     165                 :             :         }
     166                 :             :         /*x5chain*/
     167         [ +  - ]:           2 :         else if (map.id_cred_x_map_x5chain_present) {
     168                 :           2 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     169                 :             :                         map.id_cred_x_map_x5chain.id_cred_x_map_x5chain.value,
     170                 :             :                         (uint32_t)map.id_cred_x_map_x5chain
     171                 :             :                                 .id_cred_x_map_x5chain.len);
     172                 :             : 
     173         [ -  + ]:           2 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, x5chain, &cert,
     174                 :             :                                      cred, pk, g));
     175                 :           2 :                 return ok;
     176                 :             :         }
     177                 :             :         /*x5bag*/
     178         [ #  # ]:           0 :         else if (map.id_cred_x_map_x5bag_present) {
     179                 :           0 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     180                 :             :                         map.id_cred_x_map_x5bag.id_cred_x_map_x5bag.value,
     181                 :             :                         (uint32_t)map.id_cred_x_map_x5bag.id_cred_x_map_x5bag
     182                 :             :                                 .len);
     183         [ #  # ]:           0 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, x5bag, &cert,
     184                 :             :                                      cred, pk, g));
     185                 :           0 :                 return ok;
     186                 :             :         }
     187                 :             :         /*c5c*/
     188         [ #  # ]:           0 :         else if (map.id_cred_x_map_c5c_present) {
     189                 :           0 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     190                 :             :                         map.id_cred_x_map_c5c.id_cred_x_map_c5c.value,
     191                 :             :                         (uint32_t)map.id_cred_x_map_c5c.id_cred_x_map_c5c.len);
     192         [ #  # ]:           0 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, c5c, &cert,
     193                 :             :                                      cred, pk, g));
     194                 :           0 :                 return ok;
     195                 :             :         }
     196                 :             :         /*c5b*/
     197         [ #  # ]:           0 :         else if (map.id_cred_x_map_c5b_present) {
     198                 :           0 :                 struct const_byte_array cert = BYTE_ARRAY_INIT(
     199                 :             :                         map.id_cred_x_map_c5b.id_cred_x_map_c5b.value,
     200                 :             :                         (uint32_t)map.id_cred_x_map_c5b.id_cred_x_map_c5b.len);
     201         [ #  # ]:           0 :                 TRY(verify_cert2cred(static_dh_auth, cred_array, c5b, &cert,
     202                 :             :                                      cred, pk, g));
     203                 :           0 :                 return ok;
     204                 :             :         }
     205                 :             : 
     206                 :           0 :         return credential_not_found;
     207                 :             : }
        

Generated by: LCOV version 2.0-1