int sha_test() { SHA sha; byte hash[SHA::DIGEST_SIZE]; testVector test_sha[] = { testVector("abc", "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E\x25\x71\x78\x50\xC2" "\x6C\x9C\xD0\xD8\x9D"), testVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE\x4A\xA1\xF9\x51\x29" "\xE5\xE5\x46\x70\xF1"), testVector("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaa", "\x00\x98\xBA\x82\x4B\x5C\x16\x42\x7B\xD7\xA1\x12\x2A\x5A\x44" "\x2A\x25\xEC\x64\x4D"), testVector("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaa", "\xAD\x5B\x3F\xDB\xCB\x52\x67\x78\xC2\x83\x9D\x2F\x15\x1E\xA7" "\x53\x99\x5E\x26\xA0") }; int times( sizeof(test_sha) / sizeof(testVector) ); for (int i = 0; i < times; ++i) { sha.Update(test_sha[i].input_, test_sha[i].inLen_); sha.Final(hash); if (memcmp(hash, test_sha[i].output_, SHA::DIGEST_SIZE) != 0) return -1 - i; } return 0; }
int dsa_test() { Source source; FileSource("../certs/dsa512.der", source); if (source.size() == 0) { FileSource("../../certs/dsa512.der", source); // for testsuite if (source.size() == 0) { FileSource("../../../certs/dsa512.der", source); // win32 Debug dir if (source.size() == 0) err_sys("where's your certs dir?", -89); } } const char msg[] = "this is the message"; byte signature[40]; DSA_PrivateKey priv(source); DSA_Signer signer(priv); SHA sha; byte digest[SHA::DIGEST_SIZE]; sha.Update((byte*)msg, sizeof(msg)); sha.Final(digest); signer.Sign(digest, signature, rng); byte encoded[sizeof(signature) + 6]; byte decoded[40]; word32 encSz = EncodeDSA_Signature(signer.GetR(), signer.GetS(), encoded); DecodeDSA_Signature(decoded, encoded, encSz); DSA_PublicKey pub(priv); DSA_Verifier verifier(pub); if (!verifier.Verify(digest, decoded)) return -90; return 0; }
// process NAME, either issuer or subject void CertDecoder::GetName(NameType nt) { if (source_.GetError().What()) return; SHA sha; word32 length = GetSequence(); // length of all distinguished names if (length >= ASN_NAME_MAX) goto err; length += source_.get_index(); char *ptr, *buf_end; if (nt == ISSUER) { ptr= issuer_; buf_end= ptr + sizeof(issuer_) - 1; // 1 byte for trailing 0 } else { ptr= subject_; buf_end= ptr + sizeof(subject_) - 1; // 1 byte for trailing 0 } while (source_.get_index() < length) { GetSet(); GetSequence(); byte b = source_.next(); if (b != OBJECT_IDENTIFIER) { source_.SetError(OBJECT_ID_E); return; } word32 oidSz = GetLength(source_); byte joint[2]; memcpy(joint, source_.get_current(), sizeof(joint)); // v1 name types if (joint[0] == 0x55 && joint[1] == 0x04) { source_.advance(2); byte id = source_.next(); b = source_.next(); // strType word32 strLen = GetLength(source_); switch (id) { case COMMON_NAME: if (!(ptr= AddTag(ptr, buf_end, "/CN=", 4, strLen))) goto err; break; case SUR_NAME: if (!(ptr= AddTag(ptr, buf_end, "/SN=", 4, strLen))) goto err; break; case COUNTRY_NAME: if (!(ptr= AddTag(ptr, buf_end, "/C=", 3, strLen))) goto err; break; case LOCALITY_NAME: if (!(ptr= AddTag(ptr, buf_end, "/L=", 3, strLen))) goto err; break; case STATE_NAME: if (!(ptr= AddTag(ptr, buf_end, "/ST=", 4, strLen))) goto err; break; case ORG_NAME: if (!(ptr= AddTag(ptr, buf_end, "/O=", 3, strLen))) goto err; break; case ORGUNIT_NAME: if (!(ptr= AddTag(ptr, buf_end, "/OU=", 4, strLen))) goto err; break; } sha.Update(source_.get_current(), strLen); source_.advance(strLen); } else { bool email = false; if (joint[0] == 0x2a && joint[1] == 0x86) // email id hdr email = true; source_.advance(oidSz + 1); word32 length = GetLength(source_); if (email && !(ptr= AddTag(ptr, buf_end, "/emailAddress=", 14, length))) goto err; source_.advance(length); } } *ptr= 0; sha.Final(nt == ISSUER ? issuerHash_ : subjectHash_); return; err: source_.SetError(CONTENT_E); }
// process NAME, either issuer or subject void CertDecoder::GetName(NameType nt) { if (source_.GetError().What()) return; SHA sha; word32 length = GetSequence(); // length of all distinguished names if (length >= ASN_NAME_MAX) return; if (source_.IsLeft(length) == false) return; length += source_.get_index(); char* ptr; char* buf_end; if (nt == ISSUER) { ptr = issuer_; buf_end = ptr + sizeof(issuer_) - 1; // 1 byte for trailing 0 } else { ptr = subject_; buf_end = ptr + sizeof(subject_) - 1; // 1 byte for trailing 0 } while (source_.get_index() < length) { GetSet(); if (source_.GetError().What() == SET_E) { source_.SetError(NO_ERROR_E); // extensions may only have sequence source_.prev(); } GetSequence(); byte b = source_.next(); if (b != OBJECT_IDENTIFIER) { source_.SetError(OBJECT_ID_E); return; } word32 oidSz = GetLength(source_); if (source_.IsLeft(oidSz) == false) return; byte joint[2]; if (source_.IsLeft(sizeof(joint)) == false) return; memcpy(joint, source_.get_current(), sizeof(joint)); // v1 name types if (joint[0] == 0x55 && joint[1] == 0x04) { source_.advance(2); byte id = source_.next(); b = source_.next(); // strType word32 strLen = GetLength(source_); if (source_.IsLeft(strLen) == false) return; switch (id) { case COMMON_NAME: if (!(ptr = AddTag(ptr, buf_end, "/CN=", 4, strLen))) return; if (nt == ISSUER) { issCnPos_ = (int)(ptr - strLen - issuer_); issCnLen_ = (int)strLen; } else { subCnPos_ = (int)(ptr - strLen - subject_); subCnLen_ = (int)strLen; } break; case SUR_NAME: if (!(ptr = AddTag(ptr, buf_end, "/SN=", 4, strLen))) return; break; case COUNTRY_NAME: if (!(ptr = AddTag(ptr, buf_end, "/C=", 3, strLen))) return; break; case LOCALITY_NAME: if (!(ptr = AddTag(ptr, buf_end, "/L=", 3, strLen))) return; break; case STATE_NAME: if (!(ptr = AddTag(ptr, buf_end, "/ST=", 4, strLen))) return; break; case ORG_NAME: if (!(ptr = AddTag(ptr, buf_end, "/O=", 3, strLen))) return; break; case ORGUNIT_NAME: if (!(ptr = AddTag(ptr, buf_end, "/OU=", 4, strLen))) return; break; } sha.Update(source_.get_current(), strLen); source_.advance(strLen); } else { bool email = false; if (joint[0] == 0x2a && joint[1] == 0x86) // email id hdr email = true; source_.advance(oidSz + 1); word32 length = GetLength(source_); if (source_.IsLeft(length) == false) return; if (email) { if (!(ptr = AddTag(ptr, buf_end, "/emailAddress=", 14, length))) return; } source_.advance(length); } } *ptr = 0; if (nt == ISSUER) sha.Final(issuerHash_); else sha.Final(subjectHash_); }