It's not likely you'll ever find an accurate spec for a piece of legacy software that's been around for years. Even if there was a spec that completely defined the original behavior (which is doubtful), that spec probably won't reflect all the new features and other changes that were added over the years. You'd have to merge the original product spec with all the new feature and change specs and hope that you didn't miss anything. (In many cases, it takes a bug report to realize that an item in the spec was defined incorrectly, incompletely or ambiguously.)
In practice, I think that the only "spec" that's likely to capture the exact behavior of the code as it exists today is the code itself.
Also, the lack of a complete spec probably implies a lack of a complete acceptance test suite. Note that I said "acceptance test", not "unit test". Unit tests from the original code are useless for testing the re-written code, since they're specific to the particular implementation of the product you already have, which may have a completely different set of classes from the one you'll be replacing it with.
In practice, I think that the only "spec" that's likely to capture the exact behavior of the code as it exists today is the code itself.
Also, the lack of a complete spec probably implies a lack of a complete acceptance test suite. Note that I said "acceptance test", not "unit test". Unit tests from the original code are useless for testing the re-written code, since they're specific to the particular implementation of the product you already have, which may have a completely different set of classes from the one you'll be replacing it with.