What’s the date in ‘n’ days time?

I needed to see if a certificate is due to expire within “n” days. How do I find this date? It turns out to be pretty easy using standard C functions.

                                                                          
#include <stdio.h> 
#include <time.h> 
int main( int argc, char *argv??(??)) 
{ 
....
    char expireDate[11]; 
    time_t t1, t3; 
    struct tm *t2; 
    t1 = time(NULL); 
    t2 = localtime(&t1); 
    t2 -> tm_mday += 40 ; // 40 days from now 
    t3 = mktime(t2); 
    int s; 
    s=  strftime( expireDate, 11, "%Y/%m/%d", t2  ); 
    printf("====size  %d================\n",s); 
    printf(".%10.10s\n",expireDate); 

This successfully printed out the date 40 days, from now. The only little problem I had, was with strftime. The size of the output is 10 bytes. The “11” specifies the maximum number of characters that can be copied into the array. If this was 10… the size of the data I was expecting, The output was wrong “. 2023/06/1” ; off by one character in the buffer and a leading blank.!

With the technique of changing the value within a tm structure you can get the date-time n seconds / m minutes / d days/ from now either in the future – or in the past.

Clever stuff !

Is car marketing poor – or am I weird ?

Over the last few weeks I’ve bought a new car. I was very surprised at how bad the experience was. I wondered if my experience was common – or was it just me.

The brochure

For the sorts of cars I was interested in, you cannot just pick up a brochure at the garage. Car manufacturers have moved with the times – the brochures are now online and you have to download a PDF. I wondered if the sales and marketing teams for the motor manufacturers ever used their own products.

Trying to look at a brochure on my mobile phone was impractical. Using a tablet was a bit better, but the quality of the image was not good enough to be able to read the small print. “Is the size 38 or 36 cm?” I could not tell as the quality of the image was not good enough.

The brochure contents

Someone once said to me “for every presentation there are two aspects. One is what information you as the speaker want to present, the other aspect is what the audience wants to hear”. For example for a talk on Greece, I would go along expecting to hear about Archimedes and the dawn of science, but the speaker might want to show us photographs of the beaches (and bars) when he went to on holiday.

In a similar way, I want to get useful information about the car. Having pictures of the Scottish highlands, or driving through a city with no traffic. I’ve seen these places before (and how often do you drive through a city when there is no other cars in sight). Perhaps there is a subtle message. People who drive these cars have this life style. If so, the message was lost on me.

My first question was which brand of car to buy, the second was having decided on a brand, which model with brand do I want

I created a spread sheet of my requirements, “nice to have”s, and other factors. Then I tried to extract the information from each brochure in a format so it can be compared with other cars.

My requirements included

  • Fuel type petrol
  • Height under 2.2 meters. If the height is more than this you have to pay more to take it onto a ferry
  • Length and width
  • Size of boot. This is usually given in litres. Today when we go on holiday we can easily stack our cases in the boot. Can we do this – or is the boot a different shape?
  • Electric windows, air con, CD player or equivalent.
  • 6 speed gear box.

For my existing car, there were no online brochures, so I had to get my tape measure and collect the size information myself.

I eliminated brands of cars, then I had to decide which models met my criteria. My old car had a 1.4 l engine, and had listed that as a minimum engine size requirement. I test drove a car with a 1.0 l engine size – and that felt like it had more power.

I got down to a choice of three cars. The deciding factor was the older car where you needed to put a key in the ignition – rather than keyless starting. This was a surprise to me, as it was not one of the factors I had listed!

It would have been great if I could enter details of my current (old) car, and ones I was interested in, and get a table of cars and their interesting ( to me) facilities.

It was also interesting how my views different from the sales person. I was told that to change the interior temperature, I bring up “car settings” on the screen, and swipe with my finger to make it hotter or cooler. My comment, was “So I have to look down at the screen and tap and swipe. So that means I need to look down for about 2 seconds. I prefer a knob I can touch, with no more than a glance, and can rotate it”. The sales person said I had a valid point.

Now I have my new car how does it work?

The instruction book has 178 pages – and covers all models. It covers 3 models of audio system – two of which look identical, I do not know how to tell them apart. The book covers how to start the engine with the key and without the key (for those cars with the technology). It has instructions like push that knob and pull that lever to engage the parking brake – except I do not have the knob.

What would be good (and bring the technology up to date) to be able to go to the manufacturer’s web site, enter the Vehicle Identification Number (which uniquely identifies the car) and you are given a list of web page instructions for the features that were installed in the factory. This would allow me to quickly skip the pages telling my why an electric car is good for the environment (but my car is petrol), and how to install a child seat (which I do not want).

What is your relationship with your car?

I remember doing a survey on the car I had, and cars I might buy in the future. There were questions like

  • Q:”What is your relationship with your car?”. A:”What!? – it is a car, I do not have a relationship with it”
  • Q:”Does your can have a name?” A:”No!”
  • Q:”What sort of people drive a xxxxx (a top range sports car)” A:”Bad drivers, who drive without due care and consideration for other people”.

Perhaps I am the strange one after all.

Easy question – hard answer, how to I convert a hex string to hex byte string in C?

I have a program which takes as input a hex string, and this needed to be converted to an internal format, specifically a DER encoded format ( also known as a TLV, Tag, Length, Value);

This took me a good couple of hours to get right, and I thought the solution would be worth passing on.

The problem is: I have a C program and I pass in a parameter -serial abcd123456. I want to create a hex string 0x02llabcd123456 where ll is 5 – the length of the data.

Read the parameter

for (iArg = 1;iArg< argc; iArg ++   ) 
{ 
   if (strcmp(argv[iArg],"-serial") == 0 
      && iArg +1 < argc) // we have a value 
   { 
      iArg ++; 
      char * pData = argv[iArg]; 
      int iLen = strlen(pDataz); 
      if ( iLen > 16 ) 
      { 
         printf("Serial is too long(%d) %s.\n",iLen,pData); 
         return 8; 
      } 
    ... process it.
}

The

if (strcmp(argv[iArg],"-serial") == 0 
      && iArg +1 < argc) // we have a value 

checks to see if -serial was specified, and there is a parameter following. It handles the case of passing “-serial” and no following parameter.

Convert it from hex string to internal hex

I looked at various ways of converting the character string to hex, and decided the internal C run time sscanf function was best. This is the opposite of printf. It takes a formatting string and converts from printable to internal format.

For example

sscanf(pData,”%ix”,&i);

Would processes the characters in the data pointed to by pData and covert them, treating hen as hex data, to an integer &i. The processing continues until a non valid hex character is met, or the integer value is full.

If the parameter was –serial AC, the output value would be 0x000000AC.

I initially tried this, but then I had to go along and ignore any leading zeros.

You can use

sscanf(pData,”%6hh”,&bs[0]);

To read up to 6 characters into the byte string bs. If the parameter was –serial AC, the output value would be 0xAC….

This is almost what I want – I want a left justified byte string. But I have a variable length, and cannot pass a length as part of the string.

I managed this using a combindation of sprintf and sscanf.

The final-ish solution

 
int len = strlen(pData); // get the length of passed value
char sscan[20];   // used for sscanf string 
// we need to covert an ebcdic string to hex, so 
//  "1" needs length of 1, 
//  "12" needs length of 1 
//  "123" needs length of 2 etc 
int lHex = (len + 1) /2; 
                                                       
// convert to %4ddx 
// create a string for the sscan with the length 
// as it needs a hard coded length 
sprintf(&sscan[0],"%%%dhhx\0", len);
// if len = 4 this creates "%4hhx"
char tempOutput[16];
// Now use it 
sscanf(pData,&sscan[0],&tempOutput[0]); 

and I have &tempOutput containing my data – of length lHex.

This worked until it didn’t work

This worked fine until a couple of hours later. If the hex value was 7F… or smaller it worked. If it was 80… or larger it did not work.

This is because of the way the DER format handles signed numbers.

The value 0x02036789ab says

  • 02 this is an integer field
  • 03 of length 03
  • with value 6789ab.

The value 0x0203Abcdef says

  • 02 this is an integer field
  • 03 of length 03
  • with negative value Abcdef – negative because the top bit of the number is a 1.

Special casing for negative numbers

I had to allows for this negative number effect.

For negative numbers, the output needs to be 0x020400abcdef which says

  • 02 this is an integer field
  • 04 of length 04
  • with value 00abcdef – positive because the top bit is zero.

pBuffer points to the output byte field.

 if (tempOutput[0] < 0x80) 
 { 
   memcpy(pBuffer+1,&temp[0],lHex); // move the data
   *pBuffer = lHex; // char value of the length 
 } 
 else // we need to insert extra so we do not get -ve 
 { 
   *(pBuffer+1) = 0x00; // insert extra null 
   memcpy(pBuffer+2,&temp[0],lHex); // and the rest 
   *pBuffer = lHex +1 ; // char value of the length 
 } 

The solution is easy with hindsight.

Certificate dates with ICSF and PKISERV

Digging into certificates provided by ICSF, I got confused with the dates.

There are 3 places that start/end dates can be, and they have different meanings and uses.

  1. The validity period you see in the certificate is part of the certificate itself. That is added at certificate creation and enforced by the application (such as System SSL).
  2. Within ICSF there are fields START DATE/END DATE you see in the panels are CKA_START_DATE and CKA_END_DATE. They are defined in the PKCS#11 standards but are not enforced.
  3. Within record metadata for a KDSR format record, you will see Cryptoperiod start date/Cryptoperiod end date. This is enforced by ICSF. Usage outside this time frame is not permitted.

Note that PKCS#11 services are the only place you can see all three of these. Neither CKDS nor PKDS can hold certificates, nor do they support PKCS#11 attributes.

Official document

The standards document PKCS #11 Cryptographic Token Interface Base Specification says

CKA_START_DATE – Start date for the certificate (default empty)
CKA_END_DATE – End date for the certificate (default empty

Section 4.6.2 (Certificate objects Overview):
The CKA_START_DATE and CKA_END_DATE attributes are for reference only; Cryptoki does not attach any special meaning to them. When present, the application is responsible to set them to values that match the certificate’s encoded “not before” and “not after” fields (if any).

Section 4.7.2 (Key Objects Overview) has similar wording:
Note that the CKA_START_DATE and CKA_END_DATE attributes are for reference only; Cryptoki does not attach any special meaning to them. In particular, it does not restrict usage of a key

Thanks to Eric Rossman, for helping me understand this.