summaryrefslogtreecommitdiff
path: root/doc/rst/legacy/nss_sample_code/nss_sample_code_sample3/index.rst
blob: 84e55b93d1e8994aad994e28551d4cd38f3e226c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
.. _mozilla_projects_nss_nss_sample_code_nss_sample_code_sample3:

NSS Sample Code sample3
=======================

.. _sample_code_3_hashing_mac:

`Sample Code 3: Hashing, MAC <#sample_code_3_hashing_mac>`__
------------------------------------------------------------

.. container::

   .. code:: notranslate

      /*
       * Demonstration program for hashing and MACs
       */

      #include <iostream.h>

      #include "pk11pub.h"
      #include "nss.h"

      static void
      printDigest(unsigned char *digest, unsigned int len)
      {
        int i;

        cout << "length: " << len << endl;
        for(i = 0;i < len;i++) printf("%02x ", digest[i]);
        cout << endl;
      }

      /*
       * main
       */
      int
      main(int argc, const char *argv[])
      {
        int status = 0;
        PK11SlotInfo *slot = 0;
        PK11SymKey *key = 0;
        PK11Context *context = 0;
        unsigned char data[80];
        unsigned char digest[20]; /*Is there a way to tell how large the output is?*/
        unsigned int len;
        SECStatus s;

        /* Initialize NSS
         * If your application code has already initialized NSS, you can skip it
         * here.
         * This code uses the simplest of the Init functions, which does not
         * require a NSS database to exist
         */
        NSS_NoDB_Init(".");

        /* Get a slot to use for the crypto operations */
        slot = PK11_GetInternalKeySlot();
        if (!slot)
        {
          cout << "GetInternalKeySlot failed" << endl;
          status = 1;
          goto done;
        }

        /*
         *  Part 1 - Simple hashing
         */
        cout << "Part 1 -- Simple hashing" << endl;

        /* Initialize data */
        memset(data, 0xbc, sizeof data);

        /* Create a context for hashing (digesting) */
        context = PK11_CreateDigestContext(SEC_OID_MD5);
        if (!context) { cout << "CreateDigestContext failed" << endl; goto done; }

        s = PK11_DigestBegin(context);
        if (s != SECSuccess) { cout << "DigestBegin failed" << endl; goto done; }

        s = PK11_DigestOp(context, data, sizeof data);
        if (s != SECSuccess) { cout << "DigestUpdate failed" << endl; goto done; }

        s = PK11_DigestFinal(context, digest, &len, sizeof digest);
        if (s != SECSuccess) { cout << "DigestFinal failed" << endl; goto done; }

        /* Print digest */
        printDigest(digest, len);

        PK11_DestroyContext(context, PR_TRUE);
        context = 0;

        /*
         *  Part 2 - Hashing with included secret key
         */
        cout << "Part 2 -- Hashing with included secret key" << endl;

        /* Initialize data */
        memset(data, 0xbc, sizeof data);

        /* Create a Key */
        key = PK11_KeyGen(slot, CKM_GENERIC_SECRET_KEY_GEN, 0, 128, 0);
        if (!key) { cout << "Create key failed" << endl; goto done; }

        cout << (void *)key << endl;

        /* Create parameters for crypto context */
        /* NOTE: params must be provided, but may be empty */
        SECItem noParams;
        noParams.type = siBuffer;
        noParams.data = 0;
        noParams.len = 0;

        /* Create context using the same slot as the key */
      //  context = PK11_CreateDigestContext(SEC_OID_MD5);
        context = PK11_CreateContextBySymKey(CKM_MD5, CKA_DIGEST, key, &noParams);
        if (!context) { cout << "CreateDigestContext failed" << endl; goto done; }

        s = PK11_DigestBegin(context);
        if (s != SECSuccess) { cout << "DigestBegin failed" << endl; goto done; }

        s = PK11_DigestKey(context, key);
        if (s != SECSuccess) { cout << "DigestKey failed" << endl; goto done; }

        s = PK11_DigestOp(context, data, sizeof data);
        if (s != SECSuccess) { cout << "DigestUpdate failed" << endl; goto done; }

        s = PK11_DigestFinal(context, digest, &len, sizeof digest);
        if (s != SECSuccess) { cout << "DigestFinal failed" << endl; goto done; }

        /* Print digest */
        printDigest(digest, len);

        PK11_DestroyContext(context, PR_TRUE);
        context = 0;

        /*
         *  Part 3 - MAC (with secret key)
         */
        cout << "Part 3 -- MAC (with secret key)" << endl;

        /* Initialize data */
        memset(data, 0xbc, sizeof data);

        context = PK11_CreateContextBySymKey(CKM_MD5_HMAC, CKA_SIGN, key, &noParams);
        if (!context) { cout << "CreateContextBySymKey failed" << endl; goto done; }

        s = PK11_DigestBegin(context);
        if (s != SECSuccess) { cout << "DigestBegin failed" << endl; goto done; }

        s = PK11_DigestOp(context, data, sizeof data);
        if (s != SECSuccess) { cout << "DigestOp failed" << endl; goto done; }

        s = PK11_DigestFinal(context, digest, &len, sizeof digest);
        if (s != SECSuccess) { cout << "DigestFinal failed" << endl; goto done; }

        /* Print digest */
        printDigest(digest, len);

        PK11_DestroyContext(context, PR_TRUE);
        context = 0;

      done:
        if (context) PK11_DestroyContext(context, PR_TRUE);  /* freeit ?? */
        if (key) PK11_FreeSymKey(key);
        if (slot) PK11_FreeSlot(slot);

        return status;
      }