In this lab you will implement the function Hermes.DER.Encode.Put_Integer_Value. This function takes an Integer (or any of its subtypes such as Natural, Positive, etc.) and encodes it in ASN.1 form (as a Type-Length-Value, or TLV), returning the encoded octets as an Octet_Array.
First, be sure you have the latest version of Thumper on your system. Do the following:
On the GitHub page for your fork of the Thumper project, fetch all upstream changes and merge them into your fork.
On your system, use the GitHub Desktop app to switch to the master branch of your Thumper repository (which should be a clone of your fork on GitHub) and pull all changes to your system.
This two-step process will update the code on your machine to the latest version.
Next, create a branch in your clone for purposes of this change/enhancement to the code base. Branches like this are usually called topic branches. Call the branch something related to the change you intend to make: "lab06" or "put_integer" might be appropriate. The precise name is not critical, but keep in mind that in real life, you might have several topic branches going at once, so you want to choose names that will help you keep them straight.
After creating the branch switch to it (GitHub Desktop should do this automatically). Now load GNATstudio on the main Thumper project file thumper.gpr to start working.
Build and execute the Hermes test program (I recommend running it in a separate window). You will see some failures. In particular, you will see that the DER.Encode "Put Integer" test is failing. The goal of this lab is to fix that. Ignore the other two failing tests. Someone else will get to those!
The problem is that the function Put_Integer_Value is not implemented. However, tests exist for it (which fail, of course). Take a look at the tests by opening src/tests/check_der_encode.adb and looking for the procedure Test_Put_Integer. Each test case is described by a record consisting of an input Integer and an expected octet array. This gives you an idea of what the tests are expecting to happen.
Next look at the file src/hermes/hermes-der-encode.ads. This is the specification of the encoding package for the "distinguished encoding rules" (DER). Just note that this is where the function Put_Integer_Value is declared. Also notice that the function Put_Length_Value is also here. This function encodes a length. It is fully implemented. You will want to use it when you implement Put_Integer_Value.
Now, look at the file src/hermes/hermes-der-encode.adb. Find the place where Put_Integer_Value is defined. You will see that it is no more than a placeholder. The point of this lab is to complete that function so the tests work.
In the doc/references folder, look over the README.md file. You will want to download the reference: T-REC-X.690-202102.pdf (near the bottom of the file). This reference describes how the various data types are encoded. Specifically, section 8.3 describes the encoding of integers. Section 8.1 gives a general discussion of how the TLV triples are formed. Here are some key points:
The function Make_Leading_Identifier, which is already implemented, can be used to compute the Type field. You must provide it with values for the Tag_Class, Structured_Flag, and Tag. The class is "Universal" the Structured_Flag is "Primitive" and the tag is "Tag_Integer". You must use enumerators defined in the specification of package Hermes.DER.
One tricky aspect of this is that you can't encode a value with leading zeros. The integer 100 occupies only one octet whereas the integer 128 occupies two octets (because a '1' bit in the most significant position will look negative). Thus, you have to first figure out how many octets will be needed based on the size of the value. Then use the Put_Length_Value function to encode that size information.
Finally, you can convert the bits of the Value into octets and append those octets to the end of the Type and Length fields computed so far.
Implement Put_Integer_Value according to the ASN.1 requirements described above. You can focus on positive values only at first, leaving the handling of negatives for later (negative values are trickier).
Try running SPARK on your code using "Proof" at level 2. Does SPARK complain about anything you've written? Although not required for this lab, see if you can eliminate all SPARK messages (if any!) related to Put_Integer_Value.
Commit your changes to your branch and then push your branch to GitHub. This will add your branch to your fork of the main repository. In a later lab I will have you create a pull request on GitHub to contribute your changes back to the main Thumper repository. You don't need to do that now, however.
Submit your modified file to Canvas. This lab is worth 20 points
Last Revised: 2022-03-03
© Copyright 2022 by Peter C. Chapin <pchapin@vtc.edu>