Artifact f6b7a728d20f16b38dfa1d42620b089fee801575:
0000: 2f 2a 0a 20 2a 20 47 6f 6f 67 6c 65 27 73 20 50 /*. * Google's P
0010: 43 53 43 20 6c 69 62 72 61 72 79 20 72 65 71 75 CSC library requ
0020: 69 72 65 73 20 75 73 20 74 6f 20 77 72 69 74 65 ires us to write
0030: 20 6f 75 72 20 6d 6f 64 75 6c 65 20 69 6e 20 43 our module in C
0040: 2b 2b 20 28 74 68 61 6e 6b 73 2c 20 47 6f 6f 67 ++ (thanks, Goog
0050: 6c 65 29 0a 20 2a 20 54 68 69 73 20 6c 69 62 72 le). * This libr
0060: 61 72 79 20 77 72 61 70 73 20 74 68 65 20 61 63 ary wraps the ac
0070: 74 75 61 6c 20 6c 69 62 72 61 72 79 2c 20 77 72 tual library, wr
0080: 69 74 74 65 6e 20 69 6e 20 43 2e 0a 20 2a 2f 0a itten in C.. */.
0090: 0a 23 69 6e 63 6c 75 64 65 20 3c 74 68 72 65 61 .#include <threa
00a0: 64 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 70 61 d>.#include <ppa
00b0: 70 69 2f 63 70 70 2f 69 6e 73 74 61 6e 63 65 2e pi/cpp/instance.
00c0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 70 61 h>.#include <ppa
00d0: 70 69 2f 63 70 70 2f 6d 6f 64 75 6c 65 2e 68 3e pi/cpp/module.h>
00e0: 0a 23 69 6e 63 6c 75 64 65 20 3c 70 70 61 70 69 .#include <ppapi
00f0: 2f 63 70 70 2f 63 6f 72 65 2e 68 3e 0a 23 69 6e /cpp/core.h>.#in
0100: 63 6c 75 64 65 20 3c 70 70 61 70 69 2f 63 70 70 clude <ppapi/cpp
0110: 2f 76 61 72 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 /var.h>.#include
0120: 20 3c 70 70 61 70 69 2f 63 70 70 2f 76 61 72 5f <ppapi/cpp/var_
0130: 64 69 63 74 69 6f 6e 61 72 79 2e 68 3e 0a 23 69 dictionary.h>.#i
0140: 6e 63 6c 75 64 65 20 3c 70 70 61 70 69 2f 63 70 nclude <ppapi/cp
0150: 70 2f 76 61 72 5f 61 72 72 61 79 2e 68 3e 0a 23 p/var_array.h>.#
0160: 69 6e 63 6c 75 64 65 20 3c 70 70 61 70 69 2f 63 include <ppapi/c
0170: 70 70 2f 76 61 72 5f 61 72 72 61 79 5f 62 75 66 pp/var_array_buf
0180: 66 65 72 2e 68 3e 0a 0a 23 69 6e 63 6c 75 64 65 fer.h>..#include
0190: 20 3c 73 74 64 69 6f 2e 68 3e 0a 0a 23 69 6e 63 <stdio.h>..#inc
01a0: 6c 75 64 65 20 22 70 63 73 63 2d 6e 61 63 6c 2e lude "pcsc-nacl.
01b0: 68 22 0a 23 69 6e 63 6c 75 64 65 20 22 63 61 63 h".#include "cac
01c0: 6b 65 79 2d 63 68 72 6f 6d 65 2e 68 22 0a 0a 63 key-chrome.h"..c
01d0: 6c 61 73 73 20 43 41 43 4b 65 79 49 6e 73 74 61 lass CACKeyInsta
01e0: 6e 63 65 20 3a 20 70 75 62 6c 69 63 20 70 70 3a nce : public pp:
01f0: 3a 49 6e 73 74 61 6e 63 65 20 7b 0a 09 70 72 69 :Instance {..pri
0200: 76 61 74 65 3a 0a 09 09 76 6f 69 64 20 70 63 73 vate:...void pcs
0210: 63 4e 61 43 6c 49 6e 69 74 57 72 61 70 70 65 72 cNaClInitWrapper
0220: 28 70 70 3a 3a 43 6f 72 65 20 2a 63 6f 72 65 29 (pp::Core *core)
0230: 20 7b 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 {....fprintf(st
0240: 64 65 72 72 2c 20 22 43 61 6c 6c 69 6e 67 20 70 derr, "Calling p
0250: 63 73 63 4e 61 43 6c 49 6e 69 74 28 25 70 2c 20 cscNaClInit(%p,
0260: 25 70 29 5c 6e 22 2c 20 74 68 69 73 2c 20 63 6f %p)\n", this, co
0270: 72 65 29 3b 0a 0a 09 09 09 70 63 73 63 4e 61 43 re);.....pcscNaC
0280: 6c 49 6e 69 74 28 74 68 69 73 2c 20 63 6f 72 65 lInit(this, core
0290: 29 3b 0a 0a 09 09 09 66 70 72 69 6e 74 66 28 73 );.....fprintf(s
02a0: 74 64 65 72 72 2c 20 22 70 63 73 63 4e 61 43 6c tderr, "pcscNaCl
02b0: 49 6e 69 74 20 74 65 72 6d 69 6e 61 74 65 64 5c Init terminated\
02c0: 6e 22 29 3b 0a 09 09 7d 0a 09 70 75 62 6c 69 63 n");...}..public
02d0: 3a 0a 09 09 65 78 70 6c 69 63 69 74 20 43 41 43 :...explicit CAC
02e0: 4b 65 79 49 6e 73 74 61 6e 63 65 28 50 50 5f 49 KeyInstance(PP_I
02f0: 6e 73 74 61 6e 63 65 20 69 6e 73 74 61 6e 63 65 nstance instance
0300: 2c 20 70 70 3a 3a 43 6f 72 65 20 2a 63 6f 72 65 , pp::Core *core
0310: 29 20 3a 20 70 70 3a 3a 49 6e 73 74 61 6e 63 65 ) : pp::Instance
0320: 28 69 6e 73 74 61 6e 63 65 29 20 7b 0a 09 09 09 (instance) {....
0330: 73 74 64 3a 3a 74 68 72 65 61 64 28 26 43 41 43 std::thread(&CAC
0340: 4b 65 79 49 6e 73 74 61 6e 63 65 3a 3a 70 63 73 KeyInstance::pcs
0350: 63 4e 61 43 6c 49 6e 69 74 57 72 61 70 70 65 72 cNaClInitWrapper
0360: 2c 20 74 68 69 73 2c 20 63 6f 72 65 29 2e 64 65 , this, core).de
0370: 74 61 63 68 28 29 3b 0a 09 09 7d 0a 0a 09 09 76 tach();...}....v
0380: 69 72 74 75 61 6c 20 7e 43 41 43 4b 65 79 49 6e irtual ~CACKeyIn
0390: 73 74 61 6e 63 65 28 29 20 7b 7d 0a 0a 09 09 76 stance() {}....v
03a0: 69 72 74 75 61 6c 20 76 6f 69 64 20 48 61 6e 64 irtual void Hand
03b0: 6c 65 4d 65 73 73 61 67 65 28 63 6f 6e 73 74 20 leMessage(const
03c0: 70 70 3a 3a 56 61 72 26 20 6d 65 73 73 61 67 65 pp::Var& message
03d0: 50 6c 61 69 6e 29 20 7b 0a 09 09 09 69 6e 74 20 Plain) {....int
03e0: 6e 75 6d 43 65 72 74 69 66 69 63 61 74 65 73 2c numCertificates,
03f0: 20 69 3b 0a 09 09 09 73 74 72 75 63 74 20 63 61 i;....struct ca
0400: 63 6b 65 79 5f 63 65 72 74 69 66 69 63 61 74 65 ckey_certificate
0410: 20 2a 63 65 72 74 69 66 69 63 61 74 65 73 3b 0a *certificates;.
0420: 09 09 09 70 70 3a 3a 56 61 72 44 69 63 74 69 6f ...pp::VarDictio
0430: 6e 61 72 79 20 2a 6d 65 73 73 61 67 65 3b 0a 09 nary *message;..
0440: 09 09 70 70 3a 3a 56 61 72 44 69 63 74 69 6f 6e ..pp::VarDiction
0450: 61 72 79 20 2a 72 65 70 6c 79 3b 0a 09 09 09 70 ary *reply;....p
0460: 70 3a 3a 56 61 72 41 72 72 61 79 20 63 65 72 74 p::VarArray cert
0470: 69 66 69 63 61 74 65 73 50 50 41 72 72 61 79 3b ificatesPPArray;
0480: 0a 09 09 09 70 70 3a 3a 56 61 72 41 72 72 61 79 ....pp::VarArray
0490: 42 75 66 66 65 72 20 2a 63 65 72 74 69 66 69 63 Buffer *certific
04a0: 61 74 65 43 6f 6e 74 65 6e 74 73 3b 0a 09 09 09 ateContents;....
04b0: 70 70 3a 3a 56 61 72 20 63 6f 6d 6d 61 6e 64 2c pp::Var command,
04c0: 20 74 61 72 67 65 74 3b 0a 0a 09 09 09 2f 2a 0a target;...../*.
04d0: 09 09 09 20 2a 20 54 68 65 20 69 6e 63 6f 6d 69 ... * The incomi
04e0: 6e 67 20 6d 65 73 73 61 67 65 20 6d 75 73 74 20 ng message must
04f0: 62 65 20 61 20 64 69 63 74 69 6f 6e 61 72 79 0a be a dictionary.
0500: 09 09 09 20 2a 2f 0a 09 09 09 69 66 20 28 21 6d ... */....if (!m
0510: 65 73 73 61 67 65 50 6c 61 69 6e 2e 69 73 5f 64 essagePlain.is_d
0520: 69 63 74 69 6f 6e 61 72 79 28 29 29 20 7b 0a 09 ictionary()) {..
0530: 09 09 09 72 65 74 75 72 6e 3b 0a 09 09 09 7d 0a ...return;....}.
0540: 0a 09 09 09 2f 2a 0a 09 09 09 20 2a 20 50 72 6f ..../*.... * Pro
0550: 63 65 73 73 20 74 68 65 20 61 70 70 72 6f 70 72 cess the appropr
0560: 69 61 74 65 20 63 6f 6d 6d 61 6e 64 20 66 72 6f iate command fro
0570: 6d 20 74 68 65 20 69 6e 63 6f 6d 69 6e 67 20 6d m the incoming m
0580: 65 73 73 61 67 65 0a 09 09 09 20 2a 2f 0a 09 09 essage.... */...
0590: 09 6d 65 73 73 61 67 65 20 3d 20 6e 65 77 20 70 .message = new p
05a0: 70 3a 3a 56 61 72 44 69 63 74 69 6f 6e 61 72 79 p::VarDictionary
05b0: 28 6d 65 73 73 61 67 65 50 6c 61 69 6e 29 3b 0a (messagePlain);.
05c0: 0a 09 09 09 2f 2a 0a 09 09 09 20 2a 20 56 65 72 ..../*.... * Ver
05d0: 69 66 79 20 74 68 61 74 20 74 68 69 73 20 6d 65 ify that this me
05e0: 73 73 61 67 65 20 69 73 20 64 65 73 74 69 6e 65 ssage is destine
05f0: 64 20 66 6f 72 20 75 73 0a 09 09 09 20 2a 2f 0a d for us.... */.
0600: 09 09 09 69 66 20 28 21 6d 65 73 73 61 67 65 2d ...if (!message-
0610: 3e 48 61 73 4b 65 79 28 22 74 61 72 67 65 74 22 >HasKey("target"
0620: 29 29 20 7b 0a 09 09 09 09 72 65 74 75 72 6e 3b )) {.....return;
0630: 0a 09 09 09 7d 0a 0a 09 09 09 74 61 72 67 65 74 ....}.....target
0640: 20 3d 20 6d 65 73 73 61 67 65 2d 3e 47 65 74 28 = message->Get(
0650: 22 74 61 72 67 65 74 22 29 3b 0a 09 09 09 69 66 "target");....if
0660: 20 28 74 61 72 67 65 74 2e 41 73 53 74 72 69 6e (target.AsStrin
0670: 67 28 29 20 21 3d 20 22 63 61 63 6b 65 79 22 29 g() != "cackey")
0680: 20 7b 0a 09 09 09 09 72 65 74 75 72 6e 3b 0a 09 {.....return;..
0690: 09 09 7d 0a 0a 09 09 09 2f 2a 0a 09 09 09 20 2a ..}...../*.... *
06a0: 20 44 65 74 65 72 6d 69 6e 65 20 77 68 61 74 20 Determine what
06b0: 77 65 20 61 72 65 20 62 65 69 6e 67 20 61 73 6b we are being ask
06c0: 65 64 20 74 6f 20 64 6f 0a 09 09 09 20 2a 2f 0a ed to do.... */.
06d0: 09 09 09 69 66 20 28 21 6d 65 73 73 61 67 65 2d ...if (!message-
06e0: 3e 48 61 73 4b 65 79 28 22 63 6f 6d 6d 61 6e 64 >HasKey("command
06f0: 22 29 29 20 7b 0a 09 09 09 09 72 65 74 75 72 6e ")) {.....return
0700: 3b 0a 09 09 09 7d 0a 09 09 09 63 6f 6d 6d 61 6e ;....}....comman
0710: 64 20 3d 20 6d 65 73 73 61 67 65 2d 3e 47 65 74 d = message->Get
0720: 28 22 63 6f 6d 6d 61 6e 64 22 29 3b 0a 0a 09 09 ("command");....
0730: 09 2f 2a 0a 09 09 09 20 2a 20 44 6f 20 74 68 65 ./*.... * Do the
0740: 20 74 68 69 6e 67 20 77 65 20 61 72 65 20 62 65 thing we are be
0750: 69 6e 67 20 61 73 6b 65 64 20 74 6f 20 64 6f 0a ing asked to do.
0760: 09 09 09 20 2a 2f 0a 09 09 09 69 66 20 28 63 6f ... */....if (co
0770: 6d 6d 61 6e 64 2e 41 73 53 74 72 69 6e 67 28 29 mmand.AsString()
0780: 20 3d 3d 20 22 6c 69 73 74 63 65 72 74 69 66 69 == "listcertifi
0790: 63 61 74 65 73 22 29 20 7b 0a 09 09 09 09 6e 75 cates") {.....nu
07a0: 6d 43 65 72 74 69 66 69 63 61 74 65 73 20 3d 20 mCertificates =
07b0: 63 61 63 6b 65 79 5f 63 68 72 6f 6d 65 5f 6c 69 cackey_chrome_li
07c0: 73 74 43 65 72 74 69 66 69 63 61 74 65 73 28 26 stCertificates(&
07d0: 63 65 72 74 69 66 69 63 61 74 65 73 29 3b 0a 0a certificates);..
07e0: 09 09 09 09 72 65 70 6c 79 20 3d 20 6e 65 77 20 ....reply = new
07f0: 70 70 3a 3a 56 61 72 44 69 63 74 69 6f 6e 61 72 pp::VarDictionar
0800: 79 28 29 3b 0a 0a 09 09 09 09 63 65 72 74 69 66 y();......certif
0810: 69 63 61 74 65 73 50 50 41 72 72 61 79 2e 53 65 icatesPPArray.Se
0820: 74 4c 65 6e 67 74 68 28 6e 75 6d 43 65 72 74 69 tLength(numCerti
0830: 66 69 63 61 74 65 73 29 3b 0a 0a 09 09 09 09 66 ficates);......f
0840: 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20 6e or (i = 0; i < n
0850: 75 6d 43 65 72 74 69 66 69 63 61 74 65 73 3b 20 umCertificates;
0860: 69 2b 2b 29 20 7b 0a 09 09 09 09 09 63 65 72 74 i++) {......cert
0870: 69 66 69 63 61 74 65 43 6f 6e 74 65 6e 74 73 20 ificateContents
0880: 3d 20 6e 65 77 20 70 70 3a 3a 56 61 72 41 72 72 = new pp::VarArr
0890: 61 79 42 75 66 66 65 72 28 63 65 72 74 69 66 69 ayBuffer(certifi
08a0: 63 61 74 65 73 5b 69 5d 2e 63 65 72 74 69 66 69 cates[i].certifi
08b0: 63 61 74 65 5f 6c 65 6e 29 3b 0a 0a 09 09 09 09 cate_len);......
08c0: 09 6d 65 6d 63 70 79 28 63 65 72 74 69 66 69 63 .memcpy(certific
08d0: 61 74 65 43 6f 6e 74 65 6e 74 73 2d 3e 4d 61 70 ateContents->Map
08e0: 28 29 2c 20 63 65 72 74 69 66 69 63 61 74 65 73 (), certificates
08f0: 5b 69 5d 2e 63 65 72 74 69 66 69 63 61 74 65 2c [i].certificate,
0900: 20 63 65 72 74 69 66 69 63 61 74 65 73 5b 69 5d certificates[i]
0910: 2e 63 65 72 74 69 66 69 63 61 74 65 5f 6c 65 6e .certificate_len
0920: 29 3b 0a 0a 09 09 09 09 09 63 65 72 74 69 66 69 );.......certifi
0930: 63 61 74 65 43 6f 6e 74 65 6e 74 73 2d 3e 55 6e cateContents->Un
0940: 6d 61 70 28 29 3b 0a 0a 09 09 09 09 09 63 65 72 map();.......cer
0950: 74 69 66 69 63 61 74 65 73 50 50 41 72 72 61 79 tificatesPPArray
0960: 2e 53 65 74 28 69 2c 20 2a 63 65 72 74 69 66 69 .Set(i, *certifi
0970: 63 61 74 65 43 6f 6e 74 65 6e 74 73 29 3b 0a 09 cateContents);..
0980: 09 09 09 7d 0a 0a 09 09 09 09 72 65 70 6c 79 2d ...}......reply-
0990: 3e 53 65 74 28 22 73 74 61 74 75 73 22 2c 20 22 >Set("status", "
09a0: 73 75 63 63 65 73 73 22 29 3b 0a 09 09 09 09 72 success");.....r
09b0: 65 70 6c 79 2d 3e 53 65 74 28 22 63 65 72 74 69 eply->Set("certi
09c0: 66 69 63 61 74 65 73 22 2c 20 63 65 72 74 69 66 ficates", certif
09d0: 69 63 61 74 65 73 50 50 41 72 72 61 79 29 3b 0a icatesPPArray);.
09e0: 09 09 09 7d 20 65 6c 73 65 20 69 66 20 28 63 6f ...} else if (co
09f0: 6d 6d 61 6e 64 2e 41 73 53 74 72 69 6e 67 28 29 mmand.AsString()
0a00: 20 3d 3d 20 22 73 69 67 6e 22 29 20 7b 0a 09 09 == "sign") {...
0a10: 09 09 72 65 70 6c 79 20 3d 20 6e 65 77 20 70 70 ..reply = new pp
0a20: 3a 3a 56 61 72 44 69 63 74 69 6f 6e 61 72 79 28 ::VarDictionary(
0a30: 29 3b 0a 0a 09 09 09 09 72 65 70 6c 79 2d 3e 53 );......reply->S
0a40: 65 74 28 22 73 74 61 74 75 73 22 2c 20 22 73 75 et("status", "su
0a50: 63 63 65 73 73 22 29 3b 0a 09 09 09 7d 20 65 6c ccess");....} el
0a60: 73 65 20 7b 0a 09 09 09 09 72 65 70 6c 79 20 3d se {.....reply =
0a70: 20 6e 65 77 20 70 70 3a 3a 56 61 72 44 69 63 74 new pp::VarDict
0a80: 69 6f 6e 61 72 79 28 29 3b 0a 0a 09 09 09 09 72 ionary();......r
0a90: 65 70 6c 79 2d 3e 53 65 74 28 22 73 74 61 74 75 eply->Set("statu
0aa0: 73 22 2c 20 22 65 72 72 6f 72 22 29 3b 0a 09 09 s", "error");...
0ab0: 09 09 72 65 70 6c 79 2d 3e 53 65 74 28 22 65 72 ..reply->Set("er
0ac0: 72 6f 72 22 2c 20 22 49 6e 76 61 6c 69 64 20 63 ror", "Invalid c
0ad0: 6f 6d 6d 61 6e 64 22 29 3b 0a 09 09 09 7d 0a 0a ommand");....}..
0ae0: 09 09 09 2f 2a 0a 09 09 09 20 2a 20 49 66 20 61 .../*.... * If a
0af0: 20 6d 65 73 73 61 67 65 20 49 44 20 77 61 73 20 message ID was
0b00: 73 65 6e 74 20 69 6e 20 74 68 65 20 72 65 71 75 sent in the requ
0b10: 65 73 74 2c 20 69 6e 63 6c 75 64 65 20 69 74 20 est, include it
0b20: 69 6e 20 74 68 65 20 72 65 70 6c 79 0a 09 09 09 in the reply....
0b30: 20 2a 2f 0a 09 09 09 69 66 20 28 6d 65 73 73 61 */....if (messa
0b40: 67 65 2d 3e 48 61 73 4b 65 79 28 22 69 64 22 29 ge->HasKey("id")
0b50: 29 20 7b 0a 09 09 09 09 72 65 70 6c 79 2d 3e 53 ) {.....reply->S
0b60: 65 74 28 22 69 64 22 2c 20 6d 65 73 73 61 67 65 et("id", message
0b70: 2d 3e 47 65 74 28 22 69 64 22 29 29 3b 0a 09 09 ->Get("id"));...
0b80: 09 7d 0a 0a 09 09 09 2f 2a 0a 09 09 09 20 2a 20 .}...../*.... *
0b90: 53 65 6e 64 20 74 68 65 20 72 65 70 6c 79 20 62 Send the reply b
0ba0: 61 63 6b 20 74 6f 20 74 68 65 20 72 65 71 75 65 ack to the reque
0bb0: 73 74 6f 72 2c 20 68 6f 70 65 66 75 6c 6c 79 20 stor, hopefully
0bc0: 74 68 65 79 20 61 72 65 20 77 61 69 74 69 6e 67 they are waiting
0bd0: 20 66 6f 72 20 74 68 69 73 20 6d 65 73 73 61 67 for this messag
0be0: 65 0a 09 09 09 20 2a 2f 0a 09 09 09 50 6f 73 74 e.... */....Post
0bf0: 4d 65 73 73 61 67 65 28 2a 72 65 70 6c 79 29 3b Message(*reply);
0c00: 0a 0a 09 09 09 72 65 74 75 72 6e 3b 0a 09 09 7d .....return;...}
0c10: 0a 7d 3b 0a 0a 63 6c 61 73 73 20 43 41 43 4b 65 .};..class CACKe
0c20: 79 4d 6f 64 75 6c 65 20 3a 20 70 75 62 6c 69 63 yModule : public
0c30: 20 70 70 3a 3a 4d 6f 64 75 6c 65 20 7b 0a 09 70 pp::Module {..p
0c40: 75 62 6c 69 63 3a 0a 09 09 43 41 43 4b 65 79 4d ublic:...CACKeyM
0c50: 6f 64 75 6c 65 28 29 20 3a 20 70 70 3a 3a 4d 6f odule() : pp::Mo
0c60: 64 75 6c 65 28 29 20 7b 7d 0a 09 09 76 69 72 74 dule() {}...virt
0c70: 75 61 6c 20 7e 43 41 43 4b 65 79 4d 6f 64 75 6c ual ~CACKeyModul
0c80: 65 28 29 20 7b 7d 0a 0a 09 09 76 69 72 74 75 61 e() {}....virtua
0c90: 6c 20 70 70 3a 3a 49 6e 73 74 61 6e 63 65 20 2a l pp::Instance *
0ca0: 43 72 65 61 74 65 49 6e 73 74 61 6e 63 65 28 50 CreateInstance(P
0cb0: 50 5f 49 6e 73 74 61 6e 63 65 20 69 6e 73 74 61 P_Instance insta
0cc0: 6e 63 65 29 20 7b 0a 09 09 09 72 65 74 75 72 6e nce) {....return
0cd0: 28 6e 65 77 20 43 41 43 4b 65 79 49 6e 73 74 61 (new CACKeyInsta
0ce0: 6e 63 65 28 69 6e 73 74 61 6e 63 65 2c 20 63 6f nce(instance, co
0cf0: 72 65 28 29 29 29 3b 0a 09 09 7d 0a 7d 3b 0a 0a re()));...}.};..
0d00: 6e 61 6d 65 73 70 61 63 65 20 70 70 20 7b 0a 09 namespace pp {..
0d10: 4d 6f 64 75 6c 65 20 2a 43 72 65 61 74 65 4d 6f Module *CreateMo
0d20: 64 75 6c 65 28 29 20 7b 0a 09 09 72 65 74 75 72 dule() {...retur
0d30: 6e 28 6e 65 77 20 43 41 43 4b 65 79 4d 6f 64 75 n(new CACKeyModu
0d40: 6c 65 28 29 29 3b 0a 09 7d 0a 7d 0a le());..}.}.