char* decode(int kind, char *s, int *len) { char *t; int l; if(s == nil) return s; switch(kind){ case QuotedPrintable: case QuotedPrintableU: l = strlen(s)+1; t = emalloc(l); l = _decqp((uchar*)t, l, s, l-1, kind==QuotedPrintableU); *len = l; t[l] = 0; return t; case Base64: l = strlen(s)+1; t = emalloc(l); l = dec64((uchar*)t, l, s, l-1); *len = l; t[l] = 0; return t; default: *len = strlen(s); return estrdup(s); } }
uchar* decodePEM(char *s, char *type, int *len, char **new_s) { uchar *d; char *t, *e, *tt; int n; *len = 0; /* * find the correct section of the file, stripping garbage at the beginning and end. * the data is delimited by -----BEGIN <type>-----\n and -----END <type>-----\n */ n = strlen(type); e = strchr(s, '\0'); for(t = s; t != nil && t < e; ){ tt = t; t = strchr(tt, '\n'); if(t != nil) t++; if(strncmp(tt, "-----BEGIN ", STRLEN("-----BEGIN ")) == 0 && strncmp(&tt[STRLEN("-----BEGIN ")], type, n) == 0 && strncmp(&tt[STRLEN("-----BEGIN ")+n], "-----\n", STRLEN("-----\n")) == 0) break; } for(tt = t; tt != nil && tt < e; tt++){ if(strncmp(tt, "-----END ", STRLEN("-----END ")) == 0 && strncmp(&tt[STRLEN("-----END ")], type, n) == 0 && strncmp(&tt[STRLEN("-----END ")+n], "-----\n", STRLEN("-----\n")) == 0) break; tt = strchr(tt, '\n'); if(tt == nil) break; } if(tt == nil || tt == e){ werrstr("incorrect .pem file format: bad header or trailer"); return nil; } if(new_s) *new_s = tt+1; n = ((tt - t) * 6 + 7) / 8; d = malloc(n); if(d == nil){ werrstr("out of memory"); return nil; } n = dec64(d, n, t, tt - t); if(n < 0){ free(d); werrstr("incorrect .pem file format: bad base64 encoded data"); return nil; } *len = n; return d; }
/* * Init feePubKey from a public key string. * * See ByteRep.doc for info on the format of the public key string and blobs; * PLEASE UPDATE THIS DOCUMENT WHEN YOU MAKE CHANGES TO THE STRING FORMAT. */ feeReturn feePubKeyInitFromKeyString(feePubKey pubKey, const char *keyStr, unsigned keyStrLen) { unsigned char *blob = NULL; unsigned blobLen; feeReturn frtn; blob = dec64((unsigned char *)keyStr, keyStrLen, &blobLen); if(blob == NULL) { dbgLog(("Bad Public Key String (not enc64)\n")); return FR_BadPubKeyString; } frtn = feePubKeyInitFromKeyBlob(pubKey, blob, blobLen); ffree(blob); return frtn; }
MD5state* md5unpickle(char *p) { MD5state *s; s = malloc(sizeof(*s)); if(s == nil) return nil; s->len = strtoull(p, &p, 16); s->state[0] = strtoul(p, &p, 16); s->state[1] = strtoul(p, &p, 16); s->state[2] = strtoul(p, &p, 16); s->state[3] = strtoul(p, &p, 16); s->blen = dec64(s->buf, sizeof(s->buf), p, strlen(p)); s->malloced = 1; s->seeded = 1; return s; }
static char* authresp(void) { char *s, *t; int n; t = Brdline(&bin, '\n'); n = Blinelen(&bin); if(n < 2) return nil; n--; if(t[n-1] == '\r') n--; t[n] = '\0'; if(n == 0 || strcmp(t, "*") == 0) return nil; s = binalloc(&parseBin, n + 1, 0); n = dec64((uint8_t*)s, n, t, n); s[n] = '\0'; return s; }
String * s_dec64(String *sin) { int lin, lout; String *sout; lin = s_len(sin); /* * if the string is coming from smtpd.y, it will have no nl. * if it is coming from getcrnl below, it will have an nl. */ if (*(s_to_c(sin)+lin-1) == '\n') lin--; sout = s_newalloc(lin+1); lout = dec64((uchar *)s_to_c(sout), lin, s_to_c(sin), lin); if (lout < 0) { s_free(sout); return nil; } sout->ptr = sout->base + lout; s_terminate(sout); return sout; }
/* * Parse a cipherfile. * * sendPubKey only needed for cipherFileEncrType CFE_RandDES if signature * is present. If sendPubKey is present, it will be used for signature * validation rather than the embedded sender's public key. */ feeReturn parseCipherFile(feePubKey recvPrivKey, feePubKey sendPubKey, const unsigned char *cipherFileData, unsigned cipherFileDataLen, int doDec64, // 1 ==> perform dec64 cipherFileEncrType *encrType, // RETURNED unsigned char **plainText, // RETURNED unsigned *plainTextLen, // RETURNED feeSigStatus *sigStatus, // RETURNED unsigned *userData) // RETURNED { feeReturn frtn; unsigned char *cipherData = NULL; unsigned cipherDataLen; int freeCipherData = 0; feeCipherFile cipherFile = NULL; *plainText = NULL; *plainTextLen = 0; if(recvPrivKey == NULL) { // always required frtn = FR_BadPubKey; goto out; } /* * First, optional dec64() */ if(doDec64) { cipherData = dec64(cipherFileData, cipherFileDataLen, &cipherDataLen); if(cipherData == NULL) { frtn = FR_BadEnc64; goto out; } else { freeCipherData = 1; } } else { cipherData = (unsigned char *)cipherFileData; cipherDataLen = cipherFileDataLen; } /* * Cons up a feeCipherFile object. */ frtn = feeCFileNewFromDataRep(cipherData, cipherDataLen, &cipherFile); if(frtn) { goto out; } *encrType = feeCFileEncrType(cipherFile); *userData = feeCFileUserData(cipherFile); frtn = decryptCipherFile(cipherFile, recvPrivKey, sendPubKey, plainText, plainTextLen, sigStatus); out: /* free stuff */ if(cipherData && freeCipherData) { ffree(cipherData); } if(cipherFile) { feeCFileFree(cipherFile); } return frtn; }
int main() try { cybozu::Mmap xmlFile("EncryptionInfo"); cybozu::MiniXml xml(xmlFile.get() + 8, xmlFile.get() + xmlFile.size()); const cybozu::minixml::Node *keyData = xml.get().getFirstTagByName("keyData"); const std::string keyData_saltValue(dec64(keyData->attr["saltValue"])); const cybozu::minixml::Node *dataIntegrity = xml.get().getFirstTagByName("dataIntegrity"); const std::string encryptedHmacKey(dec64(dataIntegrity->attr["encryptedHmacKey"])); const std::string encryptedHmacValue(dec64(dataIntegrity->attr["encryptedHmacValue"])); // keyEncryptors const cybozu::minixml::Node *p_encryptedKey = xml.get().getFirstTagByName("p:encryptedKey"); const int spinCount = cybozu::atoi(p_encryptedKey->attr["spinCount"]); const std::string encryptedKey_saltValue(dec64(p_encryptedKey->attr["saltValue"])); const std::string encryptedVerifierHashInput(dec64(p_encryptedKey->attr["encryptedVerifierHashInput"])); const std::string encryptedVerifierHashValue(dec64(p_encryptedKey->attr["encryptedVerifierHashValue"])); const std::string encryptedKeyValue(dec64(p_encryptedKey->attr["encryptedKeyValue"])); std::string pass("t\x00""e\x00""s\x00""t\x00", 8); const std::string kV("\xfe" "\xa7" "\xd2" "\x76" "\x3b" "\x4b" "\x9e" "\x79", 8); const std::string kH("\xd7" "\xaa" "\x0f" "\x6d" "\x30" "\x61" "\x34" "\x4e", 8); const std::string kC("\x14" "\x6e" "\x0b" "\xe7" "\xab" "\xac" "\xd0" "\xd6", 8); puts("pass"); dump(pass); const std::string pwHash = hashPassword(encryptedKey_saltValue, pass, spinCount); const std::string iv = encryptedKey_saltValue; const std::string skey1 = generateKey(pwHash, kV); const std::string verifierHashInput = cipher(encryptedVerifierHashInput, skey1, iv); puts("verifierHashInput"); dump(verifierHashInput); const std::string hashedVerifier = hash(verifierHashInput); puts("hashedVerifier"); dump(hashedVerifier); const std::string skey2 = generateKey(pwHash, kH); const std::string verifierHash = cipher(encryptedVerifierHashValue, skey2, iv).substr(0, hashedVerifier.size()); puts("verifierHash"); dump(verifierHash); if (hashedVerifier != verifierHash) { puts("miss"); return 1; } const std::string skey3 = generateKey(pwHash, kC); std::string secretKey = cipher(encryptedKeyValue, skey3, iv); puts("secretKey"); dump(secretKey); cybozu::Mmap m("EncryptedPackage"); uint64_t fileSize = cybozu::Get64bitAsLE(m.get()); printf("fileSize=%d\n", (int)fileSize); std::string encData(m.get() + 8, (int)m.size() - 8); printf("encData.size=%d\n", (int)encData.size()); // decode std::string decData = decContent(encData, secretKey, keyData_saltValue); { std::ofstream ofs("dec.pptx", std::ios::binary); ofs.write(decData.c_str(), (int)fileSize); } // integrity { const std::string b1("\x5f" "\xb2" "\xad" "\x01" "\x0c" "\xb9" "\xe1" "\xf6", 8); const std::string iv1 = generateIv(keyData_saltValue, b1); const std::string salt = cipher(encryptedHmacKey, secretKey, iv1).substr(0, 20); printf("salt=%s\n", hex(salt).c_str()); } { const std::string b2("\xa0" "\x67" "\x7f" "\x02" "\xb2" "\x2c" "\x84" "\x33", 8); const std::string iv2 = generateIv(keyData_saltValue, b2); const std::string r2 = cipher(encryptedHmacValue, secretKey, iv2).substr(0, 20); printf(" r2=%s\n", hex(r2).c_str()); } } catch (cybozu::Exception& e) { printf("ERR %s\n", e.what()); }