Handling PDF digital signatures in LibreOffice with PDFium
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Vajna, Miklos
LibreOffice was capable for handling PDF signatures since 2016 already. There have been recent improvements in the past year, namely creating visible PDF signatures and reworking the underlying PDF signature verification functionality to use PDFium for tokenization. This means that PDF signature verification (which happens implicitly, during opening any PDF files) now uses much more battle-tested code to provide this feature. Come and see how this work is implemented, where are the still rough edges and how you can help.
 Hello everyone. This is a talk about handling digital signatures with PTFEma and LibroFace. I'm Mikhail Shvainov from Hungary. I'm with LibroFace for a long time. First as the player of Susan, I'm a wait-collabora. So how can we handle digital signatures with PTFEma and LibroFace? Well, let's step back a bit and think about what different scenarios we have when it comes to digital signing in LibroFace. It's actually a huge matrix when you refer to this digital document signing. It can mean a lot of different things. It may need creating a signature or signing or reading a signature, signature verification. It can also mean a signature which is part of the document as a visible signature or it can be an invisible signature which is just added on top of an existing document as a kind of metadata. It may also mean that you're signing something which is read-only a PDF or you might want to sign editable formats such as open document format or office openXMAR. It may also mean different actual crypto code which might depend on platform. So you can use Anasas from Mozilla. This is what we use on Linux and Mac OS. You can also use the Cryptography New Generation API from Microsoft. This is what we use on Windows. You can have also different certificate types. We can use this X509 type certificates which is typically used for smart cards and other kind of serious certificates like something that's issued by governments for their citizens or you might be more into this peer-reviewed network of trusted certificates which is the working rate with GPG. You can have different encryption algorithms. You can use this newer, more fancy ECDSI based encryption or you can use the older RSI based encryption. You can have also different hashing algorithms. You can use the older Shell One or the more up-to-date, more fancy, more secure Shell 256 hashing algorithm. And of course there are other legacy and other modern ones. Point is that there is not a single hashing algorithm. And sometimes done in bug report just referred to visuals, the assigning is not working. But then they mean some saying which is one combination but you can see we have several combinations here. For the purpose of this talk I will be focusing on signature verification because that's much more interesting. Signature is created once and then verified several times. It also happens on opening documents. It happens implicitly so the kind of attack vector is much more interesting. It makes more sense to have some more battle tested code there. I will talk about primarily PDF but briefly mention other editable formats as well. The actual crypto code is not that interesting for us. So what I will present here with PDF is working with both NSS and CNG. And I will focus on X509 certificates mostly because PDF supports only that one. For the actual encryption and hashing algorithm we will see that the code responsible for that did not really change by moving to PDF here so that's not that interesting. So you can initially back in the open office all times we only had signatures only for ODF and then later this got extended for office open axiomal and PDF. Both office open axiomal and ODF is physically zipped axiomal. So we use a W3C spec for how to sign axiomal files and basically that's it. PDF is rather focusing on basically doing a binary signature like take chunks of the binary PDF file, sign them digitally and then put that signature binary signature to a preallocated place order. You can see here that actually the extension on top of the W3C specification the Microsoft Office extensions are kind of horrible. They leak all sorts of your software and hardware data. So what we do on the LibroFace side is we just hardcode something as a placeholder because something has to be there but we don't really want to leak your details. As mentioned you can have different actual crypto libraries as a back-hands of LibroFace. We have two backhands the Anasas one and the Windows one bringing Anasas up to date compared to what we inherited from open office org was not that interesting. For Windows it was a bit more interesting because originally there was only crypto API which is supported even on Windows XP back then that was interesting but then the encryption and hashing part of crypto API is kind of deprecated and it does not work with ECBSA. So we had to go to the Librexamal.sac library that we also use in LibroFace and replace their backhand to not use crypto API for encryption and hashing but rather use the CNG one and then it works nicely with ECBSA keys as well. As mentioned you can have GPG certificates or X509 ones. The GPG ones are basically for ODF and that was an effort done by CIB and allotropia. So that's their baby that's not really inside the scope of this talk. For PDF and PDF-UM the only choice is X509 so I will focus on that. When you go to a file and digital signatures on the desktop LibreFace then we actually show you the signature type even if just a plain PDF1 or it's actually some extension of that like PADAS or for XMAC signatures it can be XADAS and you can also see the exact certificate and there you can see that this is X509 certificate. Now when it comes to the underlying encryption as mentioned the BigSign gets that the X509 is also working with these various smart cards like different countries like to issue electronic IDs for citizens and like my personal one is containing an X509 certificate which is actually trusted by the government and then with moving from QPRA API to CNG it was possible to use this inside the ProFace for digital signing. It's a bit similar with this modernization effort with the hashing algorithms that just moving to some newer XMAC library gave us modern hashing algorithms. The pain point there was that we inherited some huge patch from OpenOffice work times and then it was necessary to find out like which pieces of that are obsolete and which still makes sense and then upstream that but nowadays we want a lot modern enough XMAC library and this just works out out of the box. So then we arrived to the actual PDF signature verification which is the central point of this talk. So what we had is you first you take a PDF file you want to tokenize it and then extract the necessary information from the token stream so that you can make a decision if this signature is actually valid or not and we had like three PDF decolonizers already in the code base like optimal one would be just one but we already had three but all of them had different downsides so popular had the primary problem is that it had to be an out-of-process tokenizer so that's a bit painful to interpret. PDF was already there but it lagged on signature API and we also had some own boosts period based template magi ect tokenizer which is I believe used for hybrid PDFs when you embed an editable PDF inside PDF file but that's very hard to modify and maintain unless you are kind of living inside this boosts period library so we decided to not develop that for them. So instead what I did is a very simple very focused tokenizer called vcf.io our PDF document which closely tracks the source location of each and every token coming from the PDF file and that means that it's very easy to add incremental updates at the end of the documents as you are creating your signature and given that tracking was the source of various tokens from the PDF file is also useful for PDF images this is no reuse for the PDF image purpose so that in case you are inserting an image to an editable document and you are then exporting back to PDF that will be reusing the PDF image as is without any pixel or entry. So in case you want to verify a PDF signature with PDF.io originally there was basically no support for this because PDF provides a high level C API and the C API had no concept of signatures so a new signature header was created for a set of APIs and you can list how many signature objects you have and for each signature object you can have the content of the signature this PKCS7 blobe which is what you want to hand over to the crypto library then you can access what are the byte ranges like offset and size pairs of assigned data you can also have a sub filter which is describing how to interpret the content and there are also other metadata like the reason of the signature you also call it the command of the signature you can have a timestamp which is outside the content of the signature and stuff like this. So on the LibroFist side really the motivation is that in case we open PDF-wise and then we want to decide if there are signatures then and validate them right after opening without any user interaction so it makes sense to have something battle tested and something produced by some external library which has more resources to produce some nice parts or there so using PDF-EF-M DR is great and the idea is that PDF-EF-M does not really want to depend on any crypto library and we want to keep our Anacess and CNG crypto usage as well so that's a nice win-win we can ask PDF-EF-M to provide just enough details so that we can or enough information so that we can verify the signature and then we can keep our existing certificate verification code and also we can do the we can basically keep our existing verification code but we can drop all the PDF parsing pieces which is expected to be the more or less weaker ones. One important point here is that this also means that we don't have to get into this tricky decision what certificates we want to trust or not trust and as a maintenance list of trusted root CAs this decision is done by Mozilla Microsoft does the same from CNG we can delegate this decision nicely to them and then is their problem not ours. This means that I started to collect the various problematic PDF signatures and like for example there are many special cases which were not supported by the OLDOwn tokenizer and are supported by PDF-EF-M for example you can have some some custom non-command magic number or magic string between the header and the first PDF object PDF-EF-M handles this nicely also this is a screenshot from some external PDF validator this DSS validator produced by the EU which shows that actually our PDF signature as we previously said is something that's accepted by that validator. The question is like if this is working nicely and users can enjoy it then how is this implemented perhaps you are interested in some more technical details. So the PDF-EF-M side PDF-EF-M internally is written in C++ and then there is a C API on top of that and the internal C++ API is unstable but the C API is stable. So for the majority of these APIs it's just a simple wrapper around the C++ core it's not that problematic to add these the full list of wrappers is like 200 lines of code something like that what was especially tricky is how to detect incremental updates and that's tricky because normally in case you are a PDF viewer which is the primary use case for PDF-EF-M you go to the end of the file you find the last trailer and that's kind of a table of contents and then that has pointers to previous bytes of sorts of the file for previous objects and it always points to the latest version of that object. So you can quickly render the last version of that file and in case there are multiple trailers then we don't even parse the previous trailers and we don't even see the previous versions of those objects. This is working against the idea of PDF verification where we want to make sure that no further modifications were done to the file compared to when it was signed. So that's a conflicting requirement and that means that it was necessary to tweak the PDF-EF-M side so that it's possible to visit the document from start to end and find all these trailers. The PDF-EF-M side is all unit tasks no integration tasks because they are not depending on some crypto library and then basically for each and every API there is some Google tasks and also there is some documentation on how exactly the different parameters and return codes are behaving. Now on the LibreOffice side what was necessary is to kind of separate all these VCR PDF document usage to a single translation unit because then you can review how exactly that's used and when I did the PDF-EF-M side API then I tried to keep that very close to what PDF document was already providing so that switching to that one was possible in a single document. And for the task tank I just had one one of these tricky documents which were not possible to parse previously so now there is no task case locking down that even if we would switch away from PDF-EF-M in the future then we don't lose this ability for this more advanced handling of these corner cases. This also means that PDF-EF-M is now able to provide you all this information regarding signatures or these tricky cases like what happens in case you have a signature and then some incremental update adding some commands and then again a signature which is valid or you can have this add-on case which is invalid that you have some signature and then some actual modifying document which invalidates the previous signatures and then again a signature we can handle all these cases nicely and the advantage of PDF-EF-M is that it can also do not just tokenization but also rendering so we can easily find out we can have some bitmap of the page saying that this is how it should look like without commands and then in case there is some non-signing incremental update we can easily determine if this is really a command thing one because we do the rendering without commands or this is actually modifying the document which means that this is kind of a brute force or high-level approach but it's very effective but this way it's very hard to modify the document after signing without us noticing. So as usual all the work done by Collaborant has to be paid by somebody because we are an open source consulting and product company and in this case most of this work not all of that but most of that was sponsored by the Daesh Ministry of Defense and in core operation with no end of so thanks to them for funding this one. So as a summary of what you can remember is that compared to back to OpenOffice or Times LibreOffice has a very solid digital signing story we handle ODF, Oaxama, PDF, various extensions on top of the standard digital signings we have support for modern hashing algorithms, encryption, we are supposed to be interpayable with Microsoft Office and Adobe Acrobat and the latest news is that we can create visible PDF signatures and also we can do all the verification with just with PDFM code which should be a much more robust story when it comes to validating these signatures. Thanks for listening and I believe right after the call you will have the ability to ask questions. Thank you for watching. Bye bye.
 Hello everyone. This is a talk about handling digital signatures with PTFEma and LibroFace.  I'm Mikhail Shvainov from Hungary. I'm with LibroFace for a long time. First as the  player of Susan, I'm a wait-collabora. So how can we handle digital signatures with PTFEma and LibroFace?  Well, let's step back a bit and think about what different scenarios we have when it comes to  digital signing in LibroFace. It's actually a huge matrix when you refer to this digital document  signing. It can mean a lot of different things. It may need creating a signature or signing or  reading a signature, signature verification. It can also mean a signature which is part of the  document as a visible signature or it can be an invisible signature which is just added on top of  an existing document as a kind of metadata. It may also mean that you're signing something which is  read-only a PDF or you might want to sign editable formats such as open document format or office  openXMAR. It may also mean different actual crypto code which might depend on platform. So you can  use Anasas from Mozilla. This is what we use on Linux and Mac OS. You can also use the Cryptography  New Generation API from Microsoft. This is what we use on Windows. You can have also different  certificate types. We can use this X509 type certificates which is typically used for smart  cards and other kind of serious certificates like something that's issued by governments for their  citizens or you might be more into this peer-reviewed network of trusted certificates which is the  working rate with GPG. You can have different encryption algorithms. You can use this newer,  more fancy ECDSI based encryption or you can use the older RSI based encryption. You can have  also different hashing algorithms. You can use the older Shell One or the more up-to-date,  more fancy, more secure Shell 256 hashing algorithm. And of course there are other  legacy and other modern ones. Point is that there is not a single hashing algorithm. And sometimes  done in bug report just referred to visuals, the assigning is not working. But then they mean  some saying which is one combination but you can see we have several combinations here. For  the purpose of this talk I will be focusing on signature verification because that's much  more interesting. Signature is created once and then verified several times. It also happens on  opening documents. It happens implicitly so the kind of attack vector is much more interesting.  It makes more sense to have some more battle tested code there. I will talk about primarily PDF  but briefly mention other editable formats as well. The actual crypto code is not that interesting  for us. So what I will present here with PDF is working with both NSS and CNG. And I will focus  on X509 certificates mostly because PDF supports only that one. For the actual encryption and  hashing algorithm we will see that the code responsible for that did not really change by  moving to PDF here so that's not that interesting. So you can initially back in the open office  all times we only had signatures only for ODF and then later this got extended for office  open axiomal and PDF. Both office open axiomal and ODF is physically zipped axiomal. So we use  a W3C spec for how to sign axiomal files and basically that's it. PDF is rather focusing on  basically doing a binary signature like take chunks of the binary PDF file, sign them digitally  and then put that signature binary signature to a preallocated place order. You can see here that  actually the extension on top of the W3C specification the Microsoft Office extensions  are kind of horrible. They leak all sorts of your software and hardware data. So what we do on the  LibroFace side is we just hardcode something as a placeholder because something has to be there  but we don't really want to leak your details. As mentioned you can have different actual crypto  libraries as a back-hands of LibroFace. We have two backhands the Anasas one and the Windows one  bringing Anasas up to date compared to what we inherited from open office org was not that  interesting. For Windows it was a bit more interesting because originally there was only  crypto API which is supported even on Windows XP back then that was interesting but then the  encryption and hashing part of crypto API is kind of deprecated and it does not work with ECBSA.  So we had to go to the Librexamal.sac library that we also use in LibroFace and replace their  backhand to not use crypto API for encryption and hashing but rather use the CNG one and then  it works nicely with ECBSA keys as well. As mentioned you can have GPG certificates or  X509 ones. The GPG ones are basically for ODF and that was an effort done by CIB and allotropia.  So that's their baby that's not really inside the scope of this talk. For PDF and PDF-UM the  only choice is X509 so I will focus on that. When you go to a file and digital signatures on  the desktop LibreFace then we actually show you the signature type even if just a plain PDF1 or  it's actually some extension of that like PADAS or for XMAC signatures it can be XADAS and you  can also see the exact certificate and there you can see that this is X509 certificate.  Now when it comes to the underlying encryption as mentioned the BigSign gets that the X509 is  also working with these various smart cards like different countries like to issue electronic IDs  for citizens and like my personal one is containing an X509 certificate which is actually  trusted by the government and then with moving from QPRA API to CNG it was possible to use this  inside the ProFace for digital signing. It's a bit similar with this modernization effort with  the hashing algorithms that just moving to some newer XMAC library gave us modern hashing algorithms.  The pain point there was that we inherited some huge patch from OpenOffice work times and then  it was necessary to find out like which pieces of that are obsolete and which still makes sense and  then upstream that but nowadays we want a lot modern enough XMAC library and this just works out  out of the box. So then we arrived to the actual PDF signature verification which is the central  point of this talk. So what we had is you first you take a PDF file you want to tokenize it and  then extract the necessary information from the token stream so that you can make a decision if  this signature is actually valid or not and we had like three PDF decolonizers already in the code  base like optimal one would be just one but we already had three but all of them had different  downsides so popular had the primary problem is that it had to be an out-of-process tokenizer so  that's a bit painful to interpret. PDF was already there but it lagged on signature API and we also  had some own boosts period based template magi ect tokenizer which is I believe used for hybrid  PDFs when you embed an editable PDF inside PDF file but that's very hard to modify and maintain  unless you are kind of living inside this boosts period library so we decided to not develop that  for them. So instead what I did is a very simple very focused tokenizer called vcf.io  our PDF document which closely tracks the source location of each and every token coming from  the PDF file and that means that it's very easy to add incremental updates at the end of the  documents as you are creating your signature and given that tracking was the source of various  tokens from the PDF file is also useful for PDF images this is no reuse for the PDF image  purpose so that in case you are inserting an image to an editable document and you are then  exporting back to PDF that will be reusing the PDF image as is without any pixel or entry.  So in case you want to verify a PDF signature with PDF.io originally there was basically  no support for this because PDF provides a high level C API and the C API had no concept of signatures  so a new signature header was created for a set of APIs and you can list how many signature objects  you have and for each signature object you can have the content of the signature this PKCS7  blobe which is what you want to hand over to the crypto library then you can access what are the  byte ranges like offset and size pairs of assigned data you can also have a sub filter which is  describing how to interpret the content and there are also other metadata like the reason of the  signature you also call it the command of the signature you can have a timestamp which is  outside the content of the signature and stuff like this. So on the LibroFist side really the  motivation is that in case we open PDF-wise and then we want to decide if there are signatures  then and validate them right after opening without any user interaction so it makes sense to have  something battle tested and something produced by some external library which has more resources to  produce some nice parts or there so using PDF-EF-M DR is great and the idea is that PDF-EF-M  does not really want to depend on any crypto library and we want to keep our Anacess and  CNG crypto usage as well so that's a nice win-win we can ask PDF-EF-M to provide just enough  details so that we can or enough information so that we can verify the signature and then we  can keep our existing certificate verification code and also we can do the we can basically keep  our existing verification code but we can drop all the PDF parsing pieces which is expected to be  the more or less weaker ones. One important point here is that this also means that we don't have  to get into this tricky decision what certificates we want to trust or not trust and as a maintenance  list of trusted root CAs this decision is done by Mozilla Microsoft does the same from CNG we  can delegate this decision nicely to them and then is their problem not ours. This means that  I started to collect the various problematic PDF signatures and like for example there are many  special cases which were not supported by the OLDOwn tokenizer and are supported by PDF-EF-M  for example you can have some some custom non-command magic number or magic string between  the header and the first PDF object PDF-EF-M handles this nicely also this is a screenshot from some  external PDF validator this DSS validator produced by the EU which shows that actually our PDF  signature as we previously said is something that's accepted by that validator. The question is like  if this is working nicely and users can enjoy it then how is this implemented perhaps you are  interested in some more technical details. So the PDF-EF-M side PDF-EF-M internally is written  in C++ and then there is a C API on top of that and the internal C++ API is unstable but the C API  is stable. So for the majority of these APIs it's just a simple wrapper around the C++ core it's not  that problematic to add these the full list of wrappers is like 200 lines of code something like  that what was especially tricky is how to detect incremental updates and that's tricky because  normally in case you are a PDF viewer which is the primary use case for PDF-EF-M you go to the end  of the file you find the last trailer and that's kind of a table of contents and then that has  pointers to previous bytes of sorts of the file for previous objects and it always points to the  latest version of that object. So you can quickly render the last version of that file and in case  there are multiple trailers then we don't even parse the previous trailers and we don't even see  the previous versions of those objects. This is working against the idea of PDF verification where  we want to make sure that no further modifications were done to the file compared to when it was  signed. So that's a conflicting requirement and that means that it was necessary to tweak the  PDF-EF-M side so that it's possible to visit the document from start to end and find all these  trailers. The PDF-EF-M side is all unit tasks no integration tasks because they are not depending  on some crypto library and then basically for each and every API there is some Google  tasks and also there is some documentation on how exactly the different parameters and  return codes are behaving. Now on the LibreOffice side what was necessary is to kind of separate all  these VCR PDF document usage to a single translation unit because then you can review how  exactly that's used and when I did the PDF-EF-M side API then I tried to keep that very close to what  PDF document was already providing so that switching to that one was possible in a single  document. And for the task tank I just had one one of these tricky documents which were not  possible to parse previously so now there is no task case locking down that even if we would  switch away from PDF-EF-M in the future then we don't lose this ability for this more advanced  handling of these corner cases. This also means that PDF-EF-M is now able to provide you all this  information regarding signatures or these tricky cases like what happens in case you have a  signature and then some incremental update adding some commands and then again a signature which  is valid or you can have this add-on case which is invalid that you have some signature and then  some actual modifying document which invalidates the previous signatures and then again a signature  we can handle all these cases nicely and the advantage of PDF-EF-M is that it can also do  not just tokenization but also rendering so we can easily find out we can have some bitmap  of the page saying that this is how it should look like without commands and then in case there is  some non-signing incremental update we can easily determine if this is really a command thing one  because we do the rendering without commands or this is actually modifying the document which  means that this is kind of a brute force or high-level approach but it's very effective  but this way it's very hard to modify the document after signing without us noticing.  So as usual all the work done by Collaborant has to be paid by somebody because we are an open  source consulting and product company and in this case most of this work not all of that but most  of that was sponsored by the Daesh Ministry of Defense and in core operation with no end of so  thanks to them for funding this one. So as a summary of what you can remember is that compared  to back to OpenOffice or Times LibreOffice has a very solid digital signing story we handle ODF,  Oaxama, PDF, various extensions on top of the standard digital signings we have support for  modern hashing algorithms, encryption, we are supposed to be interpayable with Microsoft  Office and Adobe Acrobat and the latest news is that we can create visible PDF signatures and also  we can do all the verification with just with PDFM code which should be a much more robust story  when it comes to validating these signatures. Thanks for listening and I believe right after  the call you will have the ability to ask questions. Thank you for watching. Bye bye.
lo_pdfsignatures_0_179.png lo_pdfsignatures_180_347.png lo_pdfsignatures_348_683.png lo_pdfsignatures_684_851.png lo_pdfsignatures_852_6719.png lo_pdfsignatures_6720_8675.png lo_pdfsignatures_8676_10295.png lo_pdfsignatures_10296_10415.png lo_pdfsignatures_10416_11771.png lo_pdfsignatures_11772_12791.png lo_pdfsignatures_12792_13775.png lo_pdfsignatures_13776_17291.png lo_pdfsignatures_17292_19031.png lo_pdfsignatures_19032_23051.png lo_pdfsignatures_23052_23315.png lo_pdfsignatures_23316_26015.png lo_pdfsignatures_26016_26579.png lo_pdfsignatures_26580_27395.png lo_pdfsignatures_27396_30011.png lo_pdfsignatures_30012_30563.png lo_pdfsignatures_30564_32039.png lo_pdfsignatures_32040_32315.png lo_pdfsignatures_32316_32435.png