aboutsummaryrefslogtreecommitdiffstats
path: root/doc/porting.txt
diff options
context:
space:
mode:
Diffstat (limited to 'doc/porting.txt')
-rw-r--r--doc/porting.txt144
1 files changed, 144 insertions, 0 deletions
diff --git a/doc/porting.txt b/doc/porting.txt
new file mode 100644
index 000000000..48c095837
--- /dev/null
+++ b/doc/porting.txt
@@ -0,0 +1,144 @@
+* Botan Porting Guide, 1.2.x -> 1.4.x
+
+This is a guide for how to port your code from 1.2.x to 1.4.x. For the most
+part, they are compatible, but there are a few cases that might cause
+problems. The externally visible changes are much smaller than 1.0->1.2 changes
+were. If you run into something that used to work that doesn't now and isn't
+mentioned here, let me know so I can either fix it, or document it here.
+
+If you can provide a solid reason for 1.4.x to supply backwards-compatible
+behavior with something that's mentioned here, I'll consider it, but no
+promises.
+
+* Memory Containers
+
+The memory containers (SecureBuffer, SecureVector) have been changed to
+subclass another object, MemoryRegion (a third subclass, MemoryVector, is just
+like SecureVector, except it never locks memory - though it will clear it when
+freeing). On it's own, this shouldn't cause any problems, but there are some
+cases to be aware of.
+
+The ptr() function was renamed begin() to match the STL. This is probably the
+change most likely to cause problems.
+
+Various other functions (such as compare) were removed or renamed. The ones
+that were removed can be replaced with STL algorithms (for example, compare ->
+lexicographical_compare) and the renamed ones were typically renamed to match
+the STL.
+
+SecureBuffer can now be resized, so the second template parameter shouldn't be
+considered to be the same as the actual size; it is instead the *initial* size
+of the buffer. You can get the current size by calling the size() member
+function. While it's possible to modify the size of a SecureBuffer now, don't
+do it: it's really confusing, and you should just use a SecureVector instead.
+
+Second (optional, but a good idea): convert any functions taking a "const
+SecureVector<T>&" to "const MemoryRegion<T>&"; this will let them work with
+arbitrary memory types; in particular, it will work with a MemoryVector, which
+doesn't lock. In fact, the compiler will convert it for you, but this will slow
+things down quite a bit (since copying it requires an allocation and a memcpy),
+so it's a good idea to do the change.
+
+* OctetString / SymmetricKey / InitializationVector
+
+This probably wins the 'most likely to cause compile errors' award. There are
+two changes:
+
+1) copy() was renamed bits_of()
+
+2) The implicit conversion to byte* was removed. If you were passing it to
+ another library function as a byte*/u32bit pair, there is probably a version
+ taking the object directly; use that instead.
+
+ If you were using it for something else, do the following: 1) call bits_of()
+ and use the returned SecureVector<byte> to get the byte* value, and 2) email
+ me so I can figure out if what you're doing it worth supporting in the
+ library (obviously strike this last part if what you're doing is so totally
+ one-off that nobody would ever need it elsewhere).
+
+* BigInt::zero() / BigInt::one()
+
+They were removed. Just use integer constants (0/1) instead; the performance
+gain was extremely questionable, and there was lots of special glue to make
+sure they worked correctly.
+
+* ASN.1 decoding
+
+If something took an X509_Encoding flag before, it probably doesn't
+anymore. Some magical heuristics (BER::maybe_BER and PEM_Code::matches) have
+been added which can successfully tell if something is PEM or BER/DER encoded
+by looking at the data. The heuristics are not perfect (that's why I'm calling
+them heuristics), but they work pretty well, and for the most part you would
+have to go quite out of your way to fool them (you will be rewarded for your
+hard work with an exception, when the decoding fails).
+
+The places that took it for encoding still do, as the library has no way to
+guess which format you want it in.
+
+* General PK
+
+PK_Key::check_params() was renamed check_key() to better reflect what
+operations are performed.
+
+* X.509
+
+The first two arguments of X509_CA::update_crl (the list of new entries and the
+CRL) have been swapped. Now the CRL is the first argument, and the list of
+entires is the second. This just seemed a lot more natural.
+
+CRL_Usage was moved from being a global enumeration to a member of X509_Store,
+which makes more sense as that is the only class that uses it. Just replace
+CRL_Usage with X509_Store::CRL_Usage, and similarly for any elements of
+CRL_Usage (ie, instead of TLS_SERVER, use X509_Store::TLS_SERVER).
+
+* PKCS #8
+
+The PKCS #8 key loading interface has changed significantly in 1.4.0. First,
+the versions taking memory objects have been completely removed. While it is,
+in fact, quite useful to do this, it's not so useful that it's worth supporting
+it in the library (IMO). Just create a DataSource_Memory and pass that to
+load_key instead. In fact, here's the code:
+
+PKCS8_PrivateKey* load_key(const SecureVector<byte>& buffer,
+ const std::string& pass)
+ {
+ DataSource_Memory source(buffer);
+ return PKCS8::load_key(source, pass);
+ }
+
+See, that was easy. :)
+
+Second, instead of passing a std::string, representing the passphrase, you pass
+a User_Interface& object, which a) will not be used if the key isn't encrypted,
+and b) will be called as many times as needed until the correct passphrase it
+entered (or until the number of tries exceeds the config option
+"base/pkcs8_tries", which defaults to 3 (or until the ui object returns
+CANCEL_ACTION)).
+
+The base User_Interface class is pretty brain-dead. The constructor takes an
+(optional) passphrase, which it spits back out the first time it's called. The
+second time it gets called, it will return CANCEL_ACTION. This behavior is for
+compatibility with the old std::string interface (the functions still exist as
+forwarding functions, which just create the base UI object and pass it to the
+real decoding functions).
+
+Updating your code to use the new PKCS #8 functions could make things much
+nicer in your interface (for example, popping up a dialog box that asks for the
+passphrase, but only if the key really is encrypted). There is a GTK+ example
+that shows how to do this, check the web page.
+
+* Public/Private Keys
+
+This is a pretty big change. Almost all of the PK objects used to have a
+constructor taking a DataSource&, from which it would read the key. However,
+this was a poor design, because if you guess incorrectly as to what kind of key
+was in use, bad stuff would happen. So basically it was impossible to use
+safely. In addition, it was rather complex to support.
+
+Use {X509,PKCS8}::load_key and dynamic_cast<> instead. It's a bit more code,
+but it's worth it for the flexibility and better error handling. If you really
+want something like the constructors, you can look at the try_load functions in
+1.2.x's pkcs8.cpp and x509_key.cpp to see how they did it (you won't get the
+same exact effect, since you can't add a constructor, but you can do something
+that looks fairly similar).
+